Module Name:    src
Committed By:   bsh
Date:           Tue Nov 30 13:05:27 UTC 2010

Modified Files:
        src/sys/arch/arm/imx: files.imx51 imx51_axi.c imx51reg.h imx51var.h
            imxgpioreg.h imxkppreg.h
Added Files:
        src/sys/arch/arm/imx: imx51_gpio.c imx51_iomux.c imx51_usb.c imxgpio.c
            imxgpiovar.h imxusb.c imxusbreg.h imxusbvar.h

Log Message:
Support GPIO, IOMUX, and USB on i.MX51.


To generate a diff of this commit:
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/imx/files.imx51 \
    src/sys/arch/arm/imx/imx51_axi.c src/sys/arch/arm/imx/imx51reg.h \
    src/sys/arch/arm/imx/imx51var.h src/sys/arch/arm/imx/imxgpioreg.h \
    src/sys/arch/arm/imx/imxkppreg.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/imx/imx51_gpio.c \
    src/sys/arch/arm/imx/imx51_iomux.c src/sys/arch/arm/imx/imx51_usb.c \
    src/sys/arch/arm/imx/imxgpio.c src/sys/arch/arm/imx/imxgpiovar.h \
    src/sys/arch/arm/imx/imxusb.c src/sys/arch/arm/imx/imxusbreg.h \
    src/sys/arch/arm/imx/imxusbvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/arm/imx/files.imx51
diff -u src/sys/arch/arm/imx/files.imx51:1.1 src/sys/arch/arm/imx/files.imx51:1.2
--- src/sys/arch/arm/imx/files.imx51:1.1	Sat Nov 13 07:11:02 2010
+++ src/sys/arch/arm/imx/files.imx51	Tue Nov 30 13:05:27 2010
@@ -1,4 +1,4 @@
-#	$NetBSD: files.imx51,v 1.1 2010/11/13 07:11:02 bsh Exp $
+#	$NetBSD: files.imx51,v 1.2 2010/11/30 13:05:27 bsh Exp $
 #
 # Configuration info for the Freescale i.MX51
 #
@@ -46,14 +46,15 @@
 defparam opt_imx51clk.h IMX51_IPGCLK_FREQ
 
 # iMX GPIO
-# device	imxgpio: gpiobus
-# attach	imxgpio at ahb
-# file	arch/arm/imx/imx31_gpio.c		imxgpio		needs-flag
+device	imxgpio: gpiobus
+attach	imxgpio at axi
+file	arch/arm/imx/imxgpio.c		imxgpio		needs-flag
+file	arch/arm/imx/imx51_gpio.c	imxgpio
 
 # iMX IOMUX
 device	imxiomux : bus_space_generic
 attach	imxiomux at axi
-file	arch/arm/imx/imx31_iomux.c		imxiomux
+file	arch/arm/imx/imx51_iomux.c		imxiomux
 
 # LCD controller
 # device	lcd : bus_dma_generic, wsemuldisplaydev, rasops16, rasops8, rasops4, rasops_rotation
@@ -73,8 +74,13 @@
 file	arch/arm/imx/imx51_uart.c		imxuart
 defflag	opt_imxuart.h				IMXUARTCONSOLE
 
-# attach	ohci at ahb with ohci_ahb : bus_dma_generic
-# file	arch/arm/imx/ochi_axi.c			ohci_axi
+# USB controller
+# attach of this driver need to be specified in paltform configuration
+device imxusbc { unit, irq } : bus_dma_generic
+file   arch/arm/imx/imx51_usb.c			imxusbc
+
+attach ehci at imxusbc with imxehci
+file   arch/arm/imx/imxusb.c			imxehci
 
 # attach	wdc at ahb with wdc_ahb : bus_dma_generic
 # file	arch/arm/imx/wdc_axi.c			wdc_axi
Index: src/sys/arch/arm/imx/imx51_axi.c
diff -u src/sys/arch/arm/imx/imx51_axi.c:1.1 src/sys/arch/arm/imx/imx51_axi.c:1.2
--- src/sys/arch/arm/imx/imx51_axi.c:1.1	Sat Nov 13 07:11:02 2010
+++ src/sys/arch/arm/imx/imx51_axi.c	Tue Nov 30 13:05:27 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx51_axi.c,v 1.1 2010/11/13 07:11:02 bsh Exp $	*/
+/*	$NetBSD: imx51_axi.c,v 1.2 2010/11/30 13:05:27 bsh Exp $	*/
 
 /*-
  * Copyright (c) 2010 SHIMIZU Ryo <r...@nerv.org>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: imx51_axi.c,v 1.1 2010/11/13 07:11:02 bsh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: imx51_axi.c,v 1.2 2010/11/30 13:05:27 bsh Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -101,9 +101,11 @@
 	aa = aux;
 
 	if ((strcmp(cf->cf_name, "tzic") != 0) &&
-	    (strcmp(cf->cf_name, "imxuart") != 0))
+	    (strcmp(cf->cf_name, "imxuart") != 0) &&
+	    (strcmp(cf->cf_name, "imxgpio") != 0))
 		return 0;
 
+	aa->aa_name = cf->cf_name;
 	aa->aa_addr = cf->cf_loc[AXICF_ADDR];
 	aa->aa_size = cf->cf_loc[AXICF_SIZE];
 	aa->aa_irq = cf->cf_loc[AXICF_IRQ];
Index: src/sys/arch/arm/imx/imx51reg.h
diff -u src/sys/arch/arm/imx/imx51reg.h:1.1 src/sys/arch/arm/imx/imx51reg.h:1.2
--- src/sys/arch/arm/imx/imx51reg.h:1.1	Sat Nov 13 07:11:03 2010
+++ src/sys/arch/arm/imx/imx51reg.h	Tue Nov 30 13:05:27 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: imx51reg.h,v 1.1 2010/11/13 07:11:03 bsh Exp $ */
+/* $NetBSD: imx51reg.h,v 1.2 2010/11/30 13:05:27 bsh Exp $ */
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -89,12 +89,72 @@
 
 #define	USBOH3_BASE	0x73f80000
 #define	USBOH3_PL301_BASE	0x73fc4000
-#define	USB_OTG_BASE	0x43F88000
-#define	USB_EHCI1_BASE	0x43F88200
-#define	USB_EHCI2_BASE	0x43F88400
-#define	USB_EHCI_SIZE	0x0200
-#define	USB_CONTROL	0x43F88600
+#define	USBOH3_EHCI_SIZE	0x200
+#define	USBOH3_OTG	0x000
+#define	USBOH3_EHCI(n)	(USBOH3_EHCI_SIZE*(n))	/* n=1,2,3 */
+
+/* USB_CTRL register */
+#define	USBOH3_USBCTRL   	0x800
+#define	 USBCTRL_OWIR	__BIT(31)	/* OTG Wakeup interrupt request */
+#define	 USBCTRL_OSIC_SHIFT	29
+#define	 USBCTRL_OSIC	__BITS(29,30)	/* OTG Serial interface configuration */
+#define	 USBCTRL_OUIE	__BIT(28)	/* OTG Wake-up interrupt enable */
+#define	 USBCTRL_OBPAL	__BITS(25,26)	/* OTG Bypass value */
+#define	 USBCTRL_OPM	__BIT(24)	/* OTG Power Mask */
+#define	 USBCTRL_ICVOL	__BIT(23)	/* Host1 IC_USB voltage status */
+#define	 USBCTRL_ICTPIE	__BIT(19)	/* IC USB TP interrupt enable */
+#define	 USBCTRL_UBPCKE	__BIT(18)	/* Bypass clock enable */
+#define	 USBCTRL_H1TCKOEN __BIT(17)	/* Host1 ULPO PHY clock enable */
+#define	 USBCTRL_ICTPC	__BIT(16)	/* Clear IC TP interrupt flag */
+#define	 USBCTRL_H1WIR	__BIT(15)	/* Host1 wakeup interrupt request */
+#define	 USBCTRL_H1STC_SHIFT	13
+#define	 USBCTRL_H1SIC	__BITS(13,14)	/* Host1 serial interface config */
+#define	 USBCTRL_H1UIE	__BIT(12)	/* Host1 ILPI interrupt enable */
+#define	 USBCTRL_H1WIE	__BIT(11)	/* Host1 wakeup interrupt enable */
+#define	 USBCTRL_H1BPVAL __BITS(9,10)	/* Host1 bypass value */
+#define	 USBCTRL_H1PM	__BIT(8)	/* Host1 power mask */
+#define	 USBCTRL_OHSTLL	__BIT(7)	/* OTG ULPI TLL enable */
+#define	 USBCTRL_H1HSTLL __BIT(6)	/* Host1 ULPI TLL enable */
+#define	 USBCTRL_H1DISFSTTL __BIT(4)	/* Host1 serial TLL disable */
+#define	 USBCTRL_OTCKOEN __BIT(1)	/* OTG ULPI PHY clock enable */
+#define	 USBCTRL_BPE	__BIT(0)	/* Bypass enable */
+
+#define	USBOH3_OTGMIRROR	0x804
+#define	USBOH3_PHYCTRL0  	0x808
+#define	 PHYCTRL0_VLOAD		__BIT(31)
+#define	 PHYCTRL0_VCONTROL	__BITS(27,30)
+#define	 PHYCTRL0_CONF2		__BIT(26)
+#define	 PHYCTRL0_CONF3		__BIT(25)
+#define	 PHYCTRL0_CHGRDETEN	__BIT(24)
+#define	 PHYCTRL0_CHGRDETON	__BIT(23)
+#define	 PHYCTRL0_VSTATUS	__BITS(15,22)
+#define	 PHYCTRL0_SUSPENDM	__BIT(12)
+#define	 PHYCTRL0_RESET		__BIT(11)
+#define	 PHYCTRL0_UTMI_ON_CLOCK	__BIT(10)
+#define	 PHYCTRL0_OTG_OVER_CUR_POL	__BIT(9)
+#define	 PHYCTRL0_OTG_OVER_CUR_DIS	__BIT(8)
+#define	 PHYCTRL0_OTG_XCVR_CLK_SEL	__BIT(7)
+#define	 PHYCTRL0_H1_XCVR_CLK_SEL	__BIT(4)
+#define	 PHYCTRL0_PWR_POL		__BIT(3)
+#define	 PHYCTRL0_CHRGDET		__BIT(2)
+#define	 PHYCTRL0_CHRGDET_INT_EN	__BIT(1)
+#define	 PHYCTRL0_CHRGDET_INT_FLG	__BIT(0)
+
+#define	USBOH3_PHYCTRL1  	0x80c
+#define	 PHYCTRL1_PLLDIVVALUE_MASK	__BITS(0,1)
+#define	 PHYCTRL1_PLLDIVVALUE_19MHZ	0	/* 19.2MHz */
+#define	 PHYCTRL1_PLLDIVVALUE_24MHZ	1
+#define	 PHYCTRL1_PLLDIVVALUE_26MHZ	2
+#define	 PHYCTRL1_PLLDIVVALUE_27MHZ	3
+#define	USBOH3_USBCTRL1  	0x810
+#define	 USBCTRL1_UH3_EXT_CLK_EN	__BIT(27)
+#define	 USBCTRL1_UH2_EXT_CLK_EN	__BIT(26)
+#define	 USBCTRL1_UH1_EXT_CLK_EN	__BIT(25)
+#define	 USBCTRL1_OTG_EXT_CLK_EN	__BIT(24)
+#define	USBOH3_USBCTRL2  	0x814
+#define	USBOH3_USBCTRL3  	0x818
 
+#define	USBOH3_SIZE	0x820
 
 /* GPIO module */
 
@@ -105,15 +165,14 @@
 #define	GPIO3_BASE	GPIO_BASE(3)
 #define	GPIO4_BASE	GPIO_BASE(4)
 
-#define	GPIO_NPINS		32
-#define	GPIO_NGROUPS		3
+#define	GPIO_NGROUPS		4
 
 #define	KPP_BASE	0x73f94000
 /* register definitions in imxkppreg.h */
 
 #define	WDOG1_BASE	0x73f98000
 #define	WDOG2_BASE	0x73f9c000
-#define	WDOG_SIZE	0x4000
+#define	WDOG_SIZE	0x000a
 
 #define	GPT_BASE	0x73fa0000
 #define	GPT_SIZE	0x4000
@@ -134,25 +193,24 @@
 #define	 IOMUX_CONFIG_ALT5	(5)
 #define	 IOMUX_CONFIG_ALT6	(6)
 #define	 IOMUX_CONFIG_ALT7	(7)
+#define	 IOMUX_CONFIG_SION	__BIT(4)
 #define	IOMUXC_PAD_CTL		0x03f0		/* pad control */
-#define	 PAD_CTL_HYS_NONE	(0x0 << 8)
-#define	 PAD_CTL_HYS_ENABLE	(0x1 << 8)
-#define	 PAD_CTL_PKE_NONE	(0x0 << 7)
-#define	 PAD_CTL_PKE_ENABLE	(0x1 << 7)
-#define	 PAD_CTL_PUE_KEEPER	(0x0 << 6)
-#define	 PAD_CTL_PUE_PULL	(0x1 << 6)
+#define	 PAD_CTL_DDR_INPUT	__BIT(9)
+#define	 PAD_CTL_HYS		__BIT(8)
+#define	 PAD_CTL_PKE		__BIT(7)
+#define	 PAD_CTL_PUE		__BIT(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_CMOS	(0x0 << 3)
-#define	 PAD_CTL_ODE_OpenDrain	(0x1 << 3)
+#define	 PAD_CTL_ODE		__BIT(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_SLOW	(0x0 << 0)
-#define	 PAD_CTL_SRE_FAST	(0x1 << 0)
+#define	 PAD_CTL_SRE		__BIT(0)
 #define	IOMUXC_INPUT_CTL	0x08c4		/* input control */
 #define	 INPUT_DAISY_0		0
 #define	 INPUT_DAISY_1		1
@@ -187,7 +245,7 @@
 #define	SRC_SIZE	0x4000
 
 #define	CCM_BASE	0x73fd4000
-#define	CCM_SIZE	0x4000
+#define	CCM_SIZE	0x0088
 
 #define	GPC_BASE	0x73fd8000
 #define	GPC_SIZE	0x4000
Index: src/sys/arch/arm/imx/imx51var.h
diff -u src/sys/arch/arm/imx/imx51var.h:1.1 src/sys/arch/arm/imx/imx51var.h:1.2
--- src/sys/arch/arm/imx/imx51var.h:1.1	Sat Nov 13 07:11:03 2010
+++ src/sys/arch/arm/imx/imx51var.h	Tue Nov 30 13:05:27 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: imx51var.h,v 1.1 2010/11/13 07:11:03 bsh Exp $ */
+/*	$NetBSD: imx51var.h,v 1.2 2010/11/30 13:05:27 bsh Exp $ */
 
 #ifndef _ARM_IMX_IMX51VAR_H
 #define	_ARM_IMX_IMX51VAR_H
@@ -20,4 +20,18 @@
 	int		aa_irqbase;
 };
 
+
+/* 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);
+//void iomux_set_input(u_int, u_int);
+void iomux_mux_config(const struct iomux_conf *);
+
 #endif	/* _ARM_IMX_IMX51VAR_H */
Index: src/sys/arch/arm/imx/imxgpioreg.h
diff -u src/sys/arch/arm/imx/imxgpioreg.h:1.1 src/sys/arch/arm/imx/imxgpioreg.h:1.2
--- src/sys/arch/arm/imx/imxgpioreg.h:1.1	Sat Nov 13 06:44:11 2010
+++ src/sys/arch/arm/imx/imxgpioreg.h	Tue Nov 30 13:05:27 2010
@@ -45,11 +45,6 @@
 #define	GPIO_ICR_EDGE_RISING	2
 #define	GPIO_ICR_EDGE_FALLING	3
 
-#define	GPIO_MODULE(pin)	((pin) / GPIO_NPINS)
-
-/*
- * GPIO number
- */
-#define	GPIO_NO(group, pin)	(((group) - 1) * GPIO_NPINS + (pin))
+#define	GPIO_NPINS		32
 
 #endif	/* _ARM_IMX_IMXGPIOREG_H */
Index: src/sys/arch/arm/imx/imxkppreg.h
diff -u src/sys/arch/arm/imx/imxkppreg.h:1.1 src/sys/arch/arm/imx/imxkppreg.h:1.2
--- src/sys/arch/arm/imx/imxkppreg.h:1.1	Sat Nov 13 07:11:03 2010
+++ src/sys/arch/arm/imx/imxkppreg.h	Tue Nov 30 13:05:27 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: imxkppreg.h,v 1.1 2010/11/13 07:11:03 bsh Exp $	*/
+/*	$NetBSD: imxkppreg.h,v 1.2 2010/11/30 13:05:27 bsh Exp $	*/
 
 /*
  * Copyright (c) 2010  Genetec Corporation.  All rights reserved.
@@ -50,4 +50,6 @@
 
 #define	KPP_KPDR	0x0006	/* data register */
 
+#define	KPP_SIZE	0x0008
+
 #endif	/* _ARM_IMX_IMXKPPREG_H */

Added files:

Index: src/sys/arch/arm/imx/imx51_gpio.c
diff -u /dev/null src/sys/arch/arm/imx/imx51_gpio.c:1.1
--- /dev/null	Tue Nov 30 13:05:27 2010
+++ src/sys/arch/arm/imx/imx51_gpio.c	Tue Nov 30 13:05:27 2010
@@ -0,0 +1,114 @@
+/*	$NetBSD: imx51_gpio.c,v 1.1 2010/11/30 13:05:27 bsh Exp $ */
+
+/* derived from imx31_gpio.c */
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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>
+__KERNEL_RCSID(0, "$NetBSD: imx51_gpio.c,v 1.1 2010/11/30 13:05:27 bsh Exp $");
+
+#include "locators.h"
+#include "gpio.h"
+
+#include <sys/param.h>
+#include <sys/evcnt.h>
+#include <sys/atomic.h>
+
+#include <machine/intr.h>
+
+#include <arm/cpu.h>
+#include <arm/armreg.h>
+#include <arm/cpufunc.h>
+
+#include <machine/bus.h>
+
+#include <arm/imx/imx51reg.h>
+#include <arm/imx/imx51var.h>
+#include <arm/pic/picvar.h>
+
+#include <arm/imx/imxgpioreg.h>
+#include <arm/imx/imxgpiovar.h>
+
+#if NGPIO > 0
+#include <sys/gpio.h>
+#include <dev/gpio/gpiovar.h>
+#endif
+
+const int imxgpio_ngroups = GPIO_NGROUPS;
+
+int
+imxgpio_match(device_t parent, cfdata_t cfdata, void *aux)
+{
+	struct axi_attach_args *aa = aux;
+
+	switch(aa->aa_addr) {
+	case GPIO1_BASE:
+	case GPIO2_BASE:
+	case GPIO3_BASE:
+	case GPIO4_BASE:
+		return 1;
+	}
+
+	return 0;
+}
+
+void
+imxgpio_attach(device_t parent, device_t self, void *aux)
+{
+	struct axi_attach_args * const aa = aux;
+	bus_space_handle_t ioh;
+	int error;
+
+	if (aa->aa_irq == AXICF_IRQ_DEFAULT &&
+	    aa->aa_irqbase != AXICF_IRQBASE_DEFAULT) {
+		aprint_error_dev(self, "missing intr in config\n");
+		return;
+	}
+	if (aa->aa_irq != AXICF_IRQ_DEFAULT &&
+	    aa->aa_irqbase == AXICF_IRQBASE_DEFAULT) {
+		aprint_error_dev(self, "missing irqbase in config\n");
+		return;
+	}
+		
+	if (aa->aa_size == AXICF_SIZE_DEFAULT)
+		aa->aa_size = GPIO_SIZE;
+
+	error = bus_space_map(aa->aa_iot, aa->aa_addr, aa->aa_size,
+	    0, &ioh);
+
+	if (error) {
+		aprint_error(": failed to map register %...@%#lx: %d\n",
+		    aa->aa_size, aa->aa_addr, error);
+		return;
+	}
+
+	imxgpio_attach_common(self, aa->aa_iot, ioh,
+	    (aa->aa_addr - GPIO1_BASE) / 0x4000,
+	    aa->aa_irq, aa->aa_irqbase);
+}
+
Index: src/sys/arch/arm/imx/imx51_iomux.c
diff -u /dev/null src/sys/arch/arm/imx/imx51_iomux.c:1.1
--- /dev/null	Tue Nov 30 13:05:27 2010
+++ src/sys/arch/arm/imx/imx51_iomux.c	Tue Nov 30 13:05:27 2010
@@ -0,0 +1,180 @@
+/*	$NetBSD: imx51_iomux.c,v 1.1 2010/11/30 13:05:27 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.
+ */
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: imx51_iomux.c,v 1.1 2010/11/30 13:05:27 bsh Exp $");
+
+#define	_INTR_PRIVATE
+
+#include "locators.h"
+
+#include <sys/param.h>
+#include <sys/evcnt.h>
+#include <sys/atomic.h>
+#include <sys/device.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/intr.h>
+
+#include <arm/cpu.h>
+#include <arm/armreg.h>
+#include <arm/cpufunc.h>
+
+#include <machine/bus.h>
+
+#include <arm/imx/imx51reg.h>
+#include <arm/imx/imx51var.h>
+
+struct iomux_softc {
+	struct device iomux_dev;
+	bus_space_tag_t iomux_memt;
+	bus_space_handle_t iomux_memh;
+};
+
+extern struct cfdriver imxiomux_cd;
+
+#define	IOMUX_READ(iomux, reg) \
+	bus_space_read_4((iomux)->iomux_memt, (iomux)->iomux_memh, (reg))
+#define	IOMUX_WRITE(iomux, reg, val) \
+	bus_space_write_4((iomux)->iomux_memt, (iomux)->iomux_memh, (reg), (val))
+
+static int iomux_match(device_t, cfdata_t, void *);
+static void iomux_attach(device_t, device_t, void *);
+
+static struct iomux_softc *iomuxsc = NULL;
+
+CFATTACH_DECL(imxiomux,
+	      sizeof(struct iomux_softc),
+	      iomux_match, iomux_attach,
+	      NULL, NULL);
+
+int
+iomux_match(device_t parent, cfdata_t cfdata, void *aux)
+{
+	struct axi_attach_args *axia = aux;
+
+	if (axia->aa_addr != IOMUXC_BASE)
+		return 0;
+
+	return 1;
+}
+
+void
+iomux_attach(device_t parent, device_t self, void *aux)
+{
+	struct axi_attach_args * const axia = aux;
+	struct iomux_softc * const iomux = device_private(self);
+	int error;
+
+	if (axia->aa_size == AXICF_SIZE_DEFAULT)
+		axia->aa_size = IOMUXC_SIZE;
+
+	iomux->iomux_memt = axia->aa_iot;
+	error = bus_space_map(axia->aa_iot, axia->aa_addr, axia->aa_size,
+			      0, &iomux->iomux_memh);
+
+	if (error) {
+		aprint_error(": failed to map register %...@%#lx: %d\n",
+		    axia->aa_size, axia->aa_addr, error);
+		return;
+	}
+
+	aprint_normal("\n");
+
+	iomuxsc = iomux;
+}
+
+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)
+		bus_space_write_4(sc->iomux_memt, sc->iomux_memh,
+		    mux_ctl_reg, fn);
+}
+
+void
+iomux_set_function(unsigned int pin, unsigned int fn)
+{
+	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)
+		bus_space_write_4(sc->iomux_memt, sc->iomux_memh,
+		    pad_ctl_reg, config);
+}
+
+void
+iomux_set_pad(unsigned int pin, unsigned int config)
+{
+	iomux_set_pad_sub(iomuxsc, pin, config);
+}
+
+#if 0
+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;
+
+	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);
+	}
+}
+
+#if 0
+void
+iomux_input_config(const struct iomux_input_conf *conflist)
+{
+	int i;
+
+	for (i = 0; conflist[i].inout != -1; i++) {
+		iomux_set_inout(iomuxsc, conflist[i].inout, 
+		    conflist[i].inout_mode);
+	}
+}
+#endif
+
Index: src/sys/arch/arm/imx/imx51_usb.c
diff -u /dev/null src/sys/arch/arm/imx/imx51_usb.c:1.1
--- /dev/null	Tue Nov 30 13:05:27 2010
+++ src/sys/arch/arm/imx/imx51_usb.c	Tue Nov 30 13:05:27 2010
@@ -0,0 +1,89 @@
+/*	$NetBSD: imx51_usb.c,v 1.1 2010/11/30 13:05:27 bsh Exp $	*/
+/*
+ * Copyright (c) 2010  Genetec Corporation.  All rights reserved.
+ * Written by Hiroyuki Bessho 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.
+ */
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: imx51_usb.c,v 1.1 2010/11/30 13:05:27 bsh Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/bus.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
+#include <dev/usb/usb_mem.h>
+
+#include <dev/usb/ehcireg.h>
+#include <dev/usb/ehcivar.h>
+
+#include <arm/imx/imx51reg.h>
+#include <arm/imx/imx51var.h>
+#include <arm/imx/imxusbvar.h>
+#include "locators.h"
+
+static int 	imxusbc_search(device_t, cfdata_t, const int *, void *);
+
+
+int
+imxusbc_attach_common(device_t parent, device_t self, bus_space_tag_t iot)
+{
+	struct imxusbc_softc *sc = device_private(self);
+
+	sc->sc_iot = iot;
+
+	/* Map entire USBOH3 registers.  Host controller drivers
+	 * re-use subregions of this. */
+	if (bus_space_map(iot, USBOH3_BASE, USBOH3_SIZE, 0, &sc->sc_ioh))
+		return -1;
+
+	/* attach OTG/EHCI host controllers */
+	config_search_ia(imxusbc_search, self, "imxusbc", NULL);
+
+	return 0;
+}
+
+static int
+imxusbc_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
+{
+	struct imxusbc_softc *sc = device_private(parent);
+	struct imxusbc_attach_args aa;
+
+        aa.aa_iot = sc->sc_iot;
+	aa.aa_ioh = sc->sc_ioh;
+	aa.aa_dmat = &imx_bus_dma_tag;
+        aa.aa_unit = cf->cf_loc[IMXUSBCCF_UNIT];
+	aa.aa_irq = cf->cf_loc[IMXUSBCCF_IRQ];
+
+        if (config_match(parent, cf, &aa) > 0)
+                config_attach(parent, cf, &aa, NULL);
+
+        return 0;
+}
+
Index: src/sys/arch/arm/imx/imxgpio.c
diff -u /dev/null src/sys/arch/arm/imx/imxgpio.c:1.1
--- /dev/null	Tue Nov 30 13:05:27 2010
+++ src/sys/arch/arm/imx/imxgpio.c	Tue Nov 30 13:05:27 2010
@@ -0,0 +1,422 @@
+/*	$NetBSD: imxgpio.c,v 1.1 2010/11/30 13:05:27 bsh Exp $ */
+
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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>
+__KERNEL_RCSID(0, "$NetBSD: imxgpio.c,v 1.1 2010/11/30 13:05:27 bsh Exp $");
+
+#define	_INTR_PRIVATE
+
+#include "locators.h"
+#include "gpio.h"
+
+#include <sys/param.h>
+#include <sys/evcnt.h>
+#include <sys/atomic.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/intr.h>
+
+#include <arm/cpu.h>
+#include <arm/armreg.h>
+#include <arm/cpufunc.h>
+
+#include <machine/bus.h>
+
+#include <arm/imx/imx31reg.h>
+#include <arm/imx/imx31var.h>
+#include <arm/imx/imxgpioreg.h>
+#include <arm/pic/picvar.h>
+
+#include <arm/imx/imxgpioreg.h>
+#include <arm/imx/imxgpiovar.h>
+
+#if NGPIO > 0
+/* GPIO access from userland */
+#include <sys/gpio.h>
+#include <dev/gpio/gpiovar.h>
+#endif
+
+#define	MAX_NGROUP	4
+
+static void gpio_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
+static void gpio_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
+static int gpio_pic_find_pending_irqs(struct pic_softc *);
+static void gpio_pic_establish_irq(struct pic_softc *, struct intrsource *);
+
+const struct pic_ops gpio_pic_ops = {
+	.pic_unblock_irqs = gpio_pic_unblock_irqs,
+	.pic_block_irqs = gpio_pic_block_irqs,
+	.pic_find_pending_irqs = gpio_pic_find_pending_irqs,
+	.pic_establish_irq = gpio_pic_establish_irq,
+	.pic_source_name = NULL
+};
+
+struct gpio_softc {
+	device_t gpio_dev;
+	struct pic_softc gpio_pic;
+	struct intrsource *gpio_is;
+	bus_space_tag_t gpio_memt;
+	bus_space_handle_t gpio_memh;
+	uint32_t gpio_enable_mask;
+	uint32_t gpio_edge_mask;
+	uint32_t gpio_level_mask;
+#if NGPIO > 0
+	struct gpio_chipset_tag gpio_chipset;
+	gpio_pin_t gpio_pins[32];
+#endif
+};
+
+static struct {
+	bus_space_tag_t	iot;
+	struct {
+		bus_space_handle_t ioh;
+		struct gpio_softc *softc;
+	} unit[MAX_NGROUP];
+} gpio_handles;
+
+extern struct cfdriver imxgpio_cd;
+
+CFATTACH_DECL_NEW(imxgpio,
+	sizeof(struct gpio_softc),
+	imxgpio_match, imxgpio_attach,
+	NULL, NULL);
+
+
+#define	PIC_TO_SOFTC(pic) \
+	((struct gpio_softc *)((char *)(pic) - \
+		offsetof(struct gpio_softc, gpio_pic)))
+
+#define	GPIO_READ(gpio, reg) \
+	bus_space_read_4((gpio)->gpio_memt, (gpio)->gpio_memh, (reg))
+#define	GPIO_WRITE(gpio, reg, val) \
+	bus_space_write_4((gpio)->gpio_memt, (gpio)->gpio_memh, (reg), (val))
+
+void
+gpio_pic_unblock_irqs(struct pic_softc *pic, size_t irq_base, uint32_t irq_mask)
+{
+	struct gpio_softc * const gpio = PIC_TO_SOFTC(pic);
+	KASSERT(irq_base == 0);
+
+	gpio->gpio_enable_mask |= irq_mask;
+
+	GPIO_WRITE(gpio, GPIO_ISR, irq_mask);
+	GPIO_WRITE(gpio, GPIO_IMR, gpio->gpio_enable_mask);
+}
+
+void
+gpio_pic_block_irqs(struct pic_softc *pic, size_t irq_base, uint32_t irq_mask)
+{
+	struct gpio_softc * const gpio = PIC_TO_SOFTC(pic);
+	KASSERT(irq_base == 0);
+
+	gpio->gpio_enable_mask &= ~irq_mask;
+	GPIO_WRITE(gpio, GPIO_IMR, gpio->gpio_enable_mask);
+}
+
+int
+gpio_pic_find_pending_irqs(struct pic_softc *pic)
+{
+	struct gpio_softc * const gpio = PIC_TO_SOFTC(pic);
+	uint32_t v;
+	uint32_t pending;
+
+	v = GPIO_READ(gpio, GPIO_ISR);
+	pending = (v & gpio->gpio_enable_mask);
+	if (pending == 0)
+		return 0;
+
+	/*
+	 * Disable the pending interrupts.
+	 */
+	gpio->gpio_enable_mask &= ~pending;
+	GPIO_WRITE(gpio, GPIO_IMR, gpio->gpio_enable_mask);
+
+	/*
+	 * If any of the sources are edge triggered, ack them now so
+	 * we won't lose them.
+	 */
+	if (v & gpio->gpio_edge_mask)
+		GPIO_WRITE(gpio, GPIO_ISR, v & gpio->gpio_edge_mask);
+
+	/*
+	 * Now find all the pending bits and mark them as pending.
+	 */
+	do {
+		int irq;
+		KASSERT(pending != 0);
+		irq = 31 - __builtin_clz(pending);
+		pending &= ~__BIT(irq);
+		pic_mark_pending(&gpio->gpio_pic, irq);
+	} while (pending != 0);
+
+	return 1;
+}
+
+#define	GPIO_TYPEMAP \
+	((GPIO_ICR_LEVEL_LOW << (2*IST_LEVEL_LOW)) | \
+	 (GPIO_ICR_LEVEL_HIGH << (2*IST_LEVEL_HIGH)) | \
+	 (GPIO_ICR_EDGE_RISING << (2*IST_EDGE_RISING)) | \
+	 (GPIO_ICR_EDGE_FALLING << (2*IST_EDGE_FALLING)))
+
+void
+gpio_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
+{
+	struct gpio_softc * const gpio = PIC_TO_SOFTC(pic);
+	KASSERT(is->is_irq < 32);
+	uint32_t irq_mask = __BIT(is->is_irq);
+	uint32_t v;
+	unsigned int icr_shift, icr_reg;
+	unsigned int gtype;
+
+	/*
+	 * Make sure the irq isn't enabled and not asserting.
+	 */
+	gpio->gpio_enable_mask &= ~irq_mask;
+	GPIO_WRITE(gpio, GPIO_ISR, irq_mask);
+	GPIO_WRITE(gpio, GPIO_IMR, gpio->gpio_enable_mask);
+	/*
+	 * Convert the type to a gpio type and figure out which bits in what
+	 * register we have to tweak.
+	 */
+	gtype = (GPIO_TYPEMAP >> (2 * is->is_type)) & 3;
+	icr_shift = (is->is_irq & 0x0f) << 1;
+	icr_reg = GPIO_ICR1 + ((is->is_irq & 0x10) >> 2);
+
+	/*
+	 * Set the interrupt type.
+	 */
+	v = GPIO_READ(gpio, icr_reg);
+	v &= ~(3 << icr_shift);
+	v |= gtype << icr_shift;
+	GPIO_WRITE(gpio, icr_reg, v);
+
+	/*
+	 * Mark it as input.
+	 */
+	v = GPIO_READ(gpio, GPIO_DIR);
+	v &= ~irq_mask;
+	GPIO_WRITE(gpio, GPIO_DIR, v);
+
+	/*
+	 * Now record the type of interrupt.
+	 */
+	if (gtype == GPIO_ICR_EDGE_RISING || gtype == GPIO_ICR_EDGE_FALLING) {
+		gpio->gpio_edge_mask |= irq_mask;
+		gpio->gpio_level_mask &= ~irq_mask;
+	} else {
+		gpio->gpio_edge_mask &= ~irq_mask;
+		gpio->gpio_level_mask |= irq_mask;
+	}
+}
+
+#if NGPIO > 0
+
+static int
+imxgpio_pin_read(void *arg, int pin)
+{
+	struct gpio_softc * const gpio = arg;
+
+	return (GPIO_READ(gpio, GPIO_DR) >> pin) & 1;
+}
+
+static void
+imxgpio_pin_write(void *arg, int pin, int value)
+{
+	struct gpio_softc * const gpio = arg;
+	uint32_t mask = 1 << pin;
+	uint32_t old, new;
+
+	old = GPIO_READ(gpio, GPIO_DR);
+	if (value)
+		new = old | mask;
+	else
+		new = old & ~mask;
+
+	if (old != new)
+		GPIO_WRITE(gpio, GPIO_DR, new);
+}
+
+static void
+imxgpio_pin_ctl(void *arg, int pin, int flags)
+{
+	struct gpio_softc * const gpio = arg;
+	uint32_t mask = 1 << pin;
+	uint32_t old, new;
+
+	old = GPIO_READ(gpio, GPIO_DIR);
+	new = old;
+	switch (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) {
+	case GPIO_PIN_INPUT:	new &= ~mask; break;
+	case GPIO_PIN_OUTPUT:	new |= mask; break;
+	default:		return;
+	}
+	if (old != new)
+		GPIO_WRITE(gpio, GPIO_DIR, new);
+}
+
+static void
+gpio_defer(device_t self)
+{
+	struct gpio_softc * const gpio = (void *) self;
+	struct gpio_chipset_tag * const gp = &gpio->gpio_chipset;
+	struct gpiobus_attach_args gba;
+	gpio_pin_t *pins;
+	uint32_t mask, dir, value;
+	int pin;
+
+	gp->gp_cookie = gpio;
+	gp->gp_pin_read = imxgpio_pin_read;
+	gp->gp_pin_write = imxgpio_pin_write;
+	gp->gp_pin_ctl = imxgpio_pin_ctl;
+
+	gba.gba_gc = gp;
+	gba.gba_pins = gpio->gpio_pins;
+	gba.gba_npins = __arraycount(gpio->gpio_pins);
+
+	dir = GPIO_READ(gpio, GPIO_DIR);
+	value = GPIO_READ(gpio, GPIO_DR);
+	for (pin = 0, mask = 1, pins = gpio->gpio_pins;
+	     pin < 32; pin++, mask <<= 1, pins++) {
+		pins->pin_num = pin;
+		if ((gpio->gpio_edge_mask|gpio->gpio_level_mask) & mask)
+			pins->pin_caps = GPIO_PIN_INPUT;
+		else
+			pins->pin_caps = GPIO_PIN_INPUT|GPIO_PIN_OUTPUT;
+		pins->pin_flags =
+		    (dir & mask) ? GPIO_PIN_OUTPUT : GPIO_PIN_INPUT;
+		pins->pin_state =
+		    (value & mask) ? GPIO_PIN_HIGH : GPIO_PIN_LOW;
+	}
+
+	config_found_ia(self, "gpiobus", &gba, gpiobus_print);
+}
+#endif /* NGPIO > 0 */
+
+void
+imxgpio_attach_common(device_t self, bus_space_tag_t iot,
+    bus_space_handle_t ioh, int index, int intr, int irqbase)
+{
+	struct gpio_softc * const gpio = device_private(self);
+
+	gpio->gpio_dev = self;
+	gpio->gpio_memt = iot;
+	gpio->gpio_memh = ioh;
+
+	if (irqbase > 0) {
+		gpio->gpio_pic.pic_ops = &gpio_pic_ops;
+		strlcpy(gpio->gpio_pic.pic_name, self->dv_xname,
+		    sizeof(gpio->gpio_pic.pic_name));
+		gpio->gpio_pic.pic_maxsources = 32;
+
+		pic_add(&gpio->gpio_pic, irqbase);
+
+		aprint_normal(": interrupts %d..%d",
+		    irqbase, irqbase + GPIO_NPINS - 1);
+
+		gpio->gpio_is = intr_establish(intr,
+		    IPL_NET, IST_LEVEL, pic_handle_intr, &gpio->gpio_pic);
+		KASSERT( gpio->gpio_is != NULL );
+	}
+	aprint_normal("\n");
+		      
+
+	gpio_handles.iot = iot;
+	gpio_handles.unit[index].softc = gpio;
+	gpio_handles.unit[index].ioh = ioh;
+
+#if NGPIO > 0
+	config_interrupts(self, gpio_defer);
+#endif
+}
+
+#define	GPIO_GROUP_READ(index,offset)	\
+	bus_space_read_4(gpio_handles.iot, gpio_handles.unit[index].ioh, \
+	    (offset))
+#define	GPIO_GROUP_WRITE(index,offset,value)				\
+	bus_space_write_4(gpio_handles.iot, gpio_handles.unit[index].ioh, \
+	    (offset), (value))
+
+void
+gpio_set_direction(u_int gpio, u_int dir)
+{
+	int index = gpio / GPIO_NPINS;
+	int bit = gpio % GPIO_NPINS;
+	uint32_t reg;
+
+	KDASSERT(index < imxgpio_ngroups);
+
+	/* XXX lock */
+
+
+	reg = GPIO_GROUP_READ(index, GPIO_DIR);
+	if (dir == GPIO_DIR_OUT)
+		reg |= __BIT(bit);
+	else
+		reg &= ~__BIT(bit);
+	GPIO_GROUP_WRITE(index, GPIO_DIR, reg);
+		      
+	/* XXX unlock */
+}
+
+
+void
+gpio_data_write(u_int gpio, u_int value)
+{
+	int index = gpio / GPIO_NPINS;
+	int bit = gpio % GPIO_NPINS;
+	uint32_t reg;
+
+	KDASSERT(index < imxgpio_ngroups);
+
+	/* XXX lock */
+	reg = GPIO_GROUP_READ(index, GPIO_DR);
+	if (value)
+		reg |= __BIT(bit);
+	else
+		reg &= ~__BIT(bit);
+	GPIO_GROUP_WRITE(index, GPIO_DR, reg);
+
+	/* XXX unlock */
+}
+
+bool
+gpio_data_read(u_int gpio)
+{
+	int index = gpio / GPIO_NPINS;
+	int bit = gpio % GPIO_NPINS;
+	uint32_t reg;
+
+	KDASSERT(index < imxgpio_ngroups);
+
+	reg = GPIO_GROUP_READ(index, GPIO_DR);
+
+	return reg & __BIT(bit) ? true : false;
+}
Index: src/sys/arch/arm/imx/imxgpiovar.h
diff -u /dev/null src/sys/arch/arm/imx/imxgpiovar.h:1.1
--- /dev/null	Tue Nov 30 13:05:27 2010
+++ src/sys/arch/arm/imx/imxgpiovar.h	Tue Nov 30 13:05:27 2010
@@ -0,0 +1,53 @@
+/*	$NetBSD: imxgpiovar.h,v 1.1 2010/11/30 13:05:27 bsh Exp $ */
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+#ifndef _ARM_IMX_IMXGRPIOVAR_H
+#define _ARM_IMX_IMXGRPIOVAR_H
+
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <arm/imx/imxgpioreg.h>	/* for GPIO_NPINS */
+
+void imxgpio_attach_common(device_t, bus_space_tag_t, bus_space_handle_t,
+    int, int, int);
+/* defined imx[35]1_gpio.c */
+extern const int imxgpio_ngroups;
+int imxgpio_match(device_t, cfdata_t, void *);
+void imxgpio_attach(device_t, device_t, void *);
+
+
+#define	GPIO_NO(group, pin)	(((group) - 1) * GPIO_NPINS + (pin))
+#define	GPIO_MODULE(pin)	((pin) / GPIO_NPINS)
+
+/* in-kernel GPIO access utility functions */
+enum GPIO_DIRECTION {GPIO_DIR_IN, GPIO_DIR_OUT};
+void gpio_set_direction(u_int, enum GPIO_DIRECTION);
+void gpio_data_write(u_int, u_int);
+bool gpio_data_read(u_int);
+#endif	/* _ARM_IMX_IMXGRPIOVAR_H */
Index: src/sys/arch/arm/imx/imxusb.c
diff -u /dev/null src/sys/arch/arm/imx/imxusb.c:1.1
--- /dev/null	Tue Nov 30 13:05:27 2010
+++ src/sys/arch/arm/imx/imxusb.c	Tue Nov 30 13:05:27 2010
@@ -0,0 +1,402 @@
+/*	$NetBSD: imxusb.c,v 1.1 2010/11/30 13:05:27 bsh Exp $	*/
+/*
+ * Copyright (c) 2009, 2010  Genetec Corporation.  All rights reserved.
+ * Written by Hashimoto Kenichi and Hiroyuki Bessho 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.
+ */
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: imxusb.c,v 1.1 2010/11/30 13:05:27 bsh Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/conf.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/bus.h>
+
+#include <dev/usb/usb.h>
+#include <dev/usb/usbdi.h>
+#include <dev/usb/usbdivar.h>
+#include <dev/usb/usb_mem.h>
+
+#include <dev/usb/ehcireg.h>
+#include <dev/usb/ehcivar.h>
+
+#include <arm/imx/imxusbreg.h>
+#include <arm/imx/imxusbvar.h>
+#include <arm/imx/imxgpiovar.h>
+#include "locators.h"
+
+#include <dev/usb/ulpireg.h>	/* for test */
+
+static int	imxehci_match(device_t, cfdata_t, void *);
+static void	imxehci_attach(device_t, device_t, void *);
+						     
+uint8_t imxusb_ulpi_read(struct imxehci_softc *sc, int addr);
+void imxusb_ulpi_write(struct imxehci_softc *sc, int addr, uint8_t data);
+static void ulpi_reset(struct imxehci_softc *sc);
+
+
+
+/* attach structures */
+CFATTACH_DECL_NEW(imxehci, sizeof(struct imxehci_softc),
+    imxehci_match, imxehci_attach, NULL, NULL);
+
+static int
+imxehci_match(device_t parent, cfdata_t cf, void *aux)
+{
+	struct imxusbc_attach_args *aa = aux;
+	
+	if (aa->aa_unit < 0 || 3 < aa->aa_unit) {
+		return 0;
+	}
+		
+	return 1;
+}
+
+static void
+imxehci_attach(device_t parent, device_t self, void *aux)
+{
+	struct imxusbc_attach_args *aa = aux;
+	struct imxusbc_softc *usbc = device_private(parent);
+	struct imxehci_softc *sc = device_private(self);
+	ehci_softc_t *hsc = &sc->sc_hsc;
+	bus_space_tag_t iot;
+	uint16_t hcirev;
+	usbd_status r;
+	uint32_t id, hwhost, hwdevice;
+	const char *comma;
+	
+	sc->sc_hsc.sc_dev = self;
+	iot = sc->sc_iot = sc->sc_hsc.iot = aa->aa_iot;
+	sc->sc_unit = aa->aa_unit;
+	sc->sc_usbc = usbc;
+	hsc->sc_bus.hci_private = sc;
+
+	aprint_normal("\n");
+
+	/* per unit registers */
+	if (bus_space_subregion(iot, aa->aa_ioh, 
+		aa->aa_unit * IMXUSB_EHCI_SIZE, IMXUSB_EHCI_SIZE,
+		&sc->sc_ioh) ||
+	    bus_space_subregion(iot, aa->aa_ioh,
+		aa->aa_unit * IMXUSB_EHCI_SIZE + IMXUSB_EHCIREGS,
+		IMXUSB_EHCI_SIZE - IMXUSB_EHCIREGS,
+		&sc->sc_hsc.ioh)) {
+
+		aprint_error_dev(self, "can't subregion\n");
+		return;
+	}
+
+	id = bus_space_read_4(iot, sc->sc_ioh, IMXUSB_ID);
+	hcirev = bus_space_read_2(iot, sc->sc_hsc.ioh, EHCI_HCIVERSION);
+
+	aprint_normal_dev(self,
+	    "i.MX USB Controller id=%d revision=%d HCI revision=0x%x\n", 
+	    id & (uint32_t)IMXUSB_ID_ID_MASK, 
+	    (id & (uint32_t)IMXUSB_ID_REVISION_MASK) >>
+	    	IMXUSB_ID_REVISION_SHIFT,
+	    hcirev);
+			  
+	hwhost = bus_space_read_4(iot, sc->sc_ioh, IMXUSB_HWHOST);
+	hwdevice = bus_space_read_4(iot, sc->sc_ioh, IMXUSB_HWDEVICE);
+
+	aprint_normal_dev(self, "");
+
+	comma = "";
+	if (hwhost & HWHOST_HC) {
+		int n_ports = 1 + ((hwhost & HWHOST_NPORT_MASK) >>
+		    HWHOST_NPORT_SHIFT);
+		aprint_normal("%d host port%s",
+		    n_ports, n_ports > 1 ? "s" : "");
+		comma = ", ";
+	}
+
+	if (hwdevice & HWDEVICE_DC) {
+		int n_endpoints = (hwdevice & HWDEVICE_DEVEP_MASK) >>
+		    HWDEVICE_DEVEP_SHIFT;
+		aprint_normal("%sdevice capable, %d endpoint%s",
+		    comma,
+		    n_endpoints, n_endpoints > 1 ? "s" : "");
+	}
+	aprint_normal("\n");
+
+	sc->sc_hsc.sc_bus.dmatag = aa->aa_dmat;
+
+	sc->sc_hsc.sc_offs = bus_space_read_1(iot, sc->sc_hsc.ioh, 
+	    EHCI_CAPLENGTH);
+
+	/* Platform dependent setup */
+	if (usbc->sc_init_md_hook)
+		usbc->sc_init_md_hook(sc);
+
+	
+	imxehci_reset(sc);
+	imxehci_select_interface(sc, sc->sc_iftype);
+
+	if (sc->sc_iftype == IMXUSBC_IF_ULPI) {
+		bus_space_write_4(sc->sc_iot, sc->sc_ioh, IMXUSB_ULPIVIEW, 0);
+
+		aprint_normal_dev(hsc->sc_dev,
+		    "ULPI phy VID 0x%04x PID 0x%04x\n",
+		    (imxusb_ulpi_read(sc, ULPI_VENDOR_ID_LOW) |
+			imxusb_ulpi_read(sc, ULPI_VENDOR_ID_HIGH) << 8),
+		    (imxusb_ulpi_read(sc, ULPI_PRODUCT_ID_LOW) |
+			imxusb_ulpi_read(sc, ULPI_PRODUCT_ID_HIGH) << 8));
+
+		ulpi_reset(sc);
+
+	}
+
+	imxehci_host_mode(sc);
+	
+	if (usbc->sc_setup_md_hook)
+		usbc->sc_setup_md_hook(sc, IMXUSB_HOST);
+	else if (sc->sc_iftype == IMXUSBC_IF_ULPI) {
+		imxusb_ulpi_write(sc, ULPI_FUNCTION_CONTROL + ULPI_REG_CLEAR,
+		    OTG_CONTROL_IDPULLUP);
+
+		imxusb_ulpi_write(sc, ULPI_OTG_CONTROL + ULPI_REG_SET,
+		    OTG_CONTROL_USEEXTVBUSIND |
+		    OTG_CONTROL_DRVVBUSEXT |
+		    OTG_CONTROL_DRVVBUS |
+		    OTG_CONTROL_CHRGVBUS
+		    );
+	}
+
+	/* Disable interrupts, so we don't get any spurious ones. */
+	EOWRITE2(hsc, EHCI_USBINTR, 0);
+
+	intr_establish(aa->aa_irq, IPL_USB, IST_LEVEL, ehci_intr, hsc);
+
+	/* Figure out vendor for root hub descriptor. */
+	strlcpy(hsc->sc_vendor, "i.MX", sizeof(hsc->sc_vendor));
+
+	r = ehci_init(hsc);
+	if (r != USBD_NORMAL_COMPLETION) {
+		aprint_error_dev(self, "init failed, error=%d\n", r);
+		return;
+	}
+
+	/* Attach usb device. */
+	hsc->sc_child = config_found(self, &hsc->sc_bus, usbctlprint);
+}
+
+
+
+
+void
+imxehci_select_interface(struct imxehci_softc *sc, enum imx_usb_if interface)
+{
+	uint32_t reg;
+	struct ehci_softc *hsc = &sc->sc_hsc;
+
+	reg = EOREAD4(hsc, EHCI_PORTSC(1));
+	reg = (reg & ~PORTSC_PTS_MASK) | (interface << PORTSC_PTS_SHIFT);
+	EOWRITE4(hsc, EHCI_PORTSC(1), reg);
+}
+
+
+static uint32_t
+ulpi_wakeup(struct imxehci_softc *sc, int tout)
+{
+	uint32_t ulpi_view;
+	int i = 0;
+	ulpi_view = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IMXUSB_ULPIVIEW);
+
+	if ( !(ulpi_view & ULPI_SS) ) {
+		bus_space_write_4(sc->sc_iot, sc->sc_ioh,
+		    IMXUSB_ULPIVIEW, ULPI_WU);
+		for (i = 0; (tout < 0) || (i < tout); i++) {
+			ulpi_view = bus_space_read_4(sc->sc_iot,
+			    sc->sc_ioh, IMXUSB_ULPIVIEW);
+			if ( !(ulpi_view & ULPI_WU) )
+				break;
+			delay(1);
+		};
+	}
+
+	if ((tout > 0) && (i >= tout)) {
+		aprint_error_dev(sc->sc_hsc.sc_dev, "%s: timeout\n", __func__);
+	}
+
+	return ulpi_view;
+}
+
+static uint32_t
+ulpi_wait(struct imxehci_softc *sc, int tout)
+{
+	uint32_t ulpi_view;
+	int i;
+	ulpi_view = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IMXUSB_ULPIVIEW);
+
+	for (i = 0; (tout < 0) | (i < tout); i++) {
+		ulpi_view = bus_space_read_4(sc->sc_iot, sc->sc_ioh,
+		    IMXUSB_ULPIVIEW);
+		if (!(ulpi_view & ULPI_RUN))
+			break;
+		delay(1);
+	}
+
+	if ((tout > 0) && (i >= tout)) {
+		aprint_error_dev(sc->sc_hsc.sc_dev, "%s: timeout\n", __func__);
+	}
+
+	return ulpi_view;
+}
+
+#define	TIMEOUT	100000
+						     
+uint8_t
+imxusb_ulpi_read(struct imxehci_softc *sc, int addr)
+{
+	uint32_t data;
+
+	ulpi_wakeup(sc, TIMEOUT);
+
+	data = ULPI_RUN | (addr << ULPI_ADDR_SHIFT);
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, IMXUSB_ULPIVIEW, data);
+
+	data = ulpi_wait(sc, TIMEOUT);
+
+	return (data & ULPI_DATRD_MASK) >> ULPI_DATRD_SHIFT;
+}
+
+void
+imxusb_ulpi_write(struct imxehci_softc *sc, int addr, uint8_t data)
+{
+	uint32_t reg;
+
+	ulpi_wakeup(sc, TIMEOUT);
+
+	reg = ULPI_RUN | ULPI_RW | ((addr) << ULPI_ADDR_SHIFT) | data;
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, IMXUSB_ULPIVIEW, reg);
+
+	ulpi_wait(sc, TIMEOUT);
+
+	return;
+}
+
+#if 0
+static int
+ulpi_scratch_test(struct imxehci_softc *sc)
+{
+	uint32_t ulpi_view;
+
+	ulpi_view = ulpi_wakeup(sc, 1000);
+	if (ulpi_view & ULPI_WU) {
+		return -1;
+	}
+
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, IMXUSB_ULPIVIEW,
+		(ULPI_RUN | ULPI_RW |
+		 (ULPI_SCRATCH << ULPI_ADDR_SHIFT) | 0xAA));
+
+	ulpi_view = ulpi_wait(sc, 1000);
+
+	if (ulpi_view & ULPI_RUN) {
+		return -1;
+	}
+
+	return 0;
+}
+#endif
+
+static void
+ulpi_reset(struct imxehci_softc *sc)
+{
+	uint8_t data;
+	int timo = 1000 * 1000;	/* XXXX: 1sec */
+
+	imxusb_ulpi_write(sc, ULPI_FUNCTION_CONTROL + ULPI_REG_SET,
+	    FUNCTION_CONTROL_RESET /*0x20*/);
+	do {
+		data = imxusb_ulpi_read(sc, ULPI_FUNCTION_CONTROL);
+		if (!(data & FUNCTION_CONTROL_RESET))
+			break;
+		delay(100);
+		timo -= 100;
+	} while (timo > 0);
+	if (timo <= 0) {
+		aprint_error_dev(sc->sc_hsc.sc_dev, "%s: reset failed!!\n",
+		    __func__);
+		return;
+	}
+
+	return;
+}
+
+void
+imxehci_reset(struct imxehci_softc *sc)
+{
+	u_int32_t reg;
+	int i;
+	struct ehci_softc *hsc = &sc->sc_hsc;
+#define	RESET_TIMEOUT 100
+
+	reg = EOREAD4(hsc, EHCI_USBCMD);
+	reg &= ~EHCI_CMD_RS;
+	EOWRITE4(hsc, EHCI_USBCMD, reg);
+
+	for (i=0; i < RESET_TIMEOUT; ++i) {
+		reg = EOREAD4(hsc, EHCI_USBCMD);
+		if ((reg & EHCI_CMD_RS) == 0)
+			break;
+		usb_delay_ms(&hsc->sc_bus, 1);
+	}
+
+	EOWRITE4(hsc, EHCI_USBCMD, reg | EHCI_CMD_HCRESET);
+	for (i = 0; i < RESET_TIMEOUT; i++) {
+		reg = EOREAD4(hsc, EHCI_USBCMD);
+		if ((reg &  EHCI_CMD_HCRESET) == 0)
+			break;
+		usb_delay_ms(&hsc->sc_bus, 1);
+	}
+	if (i >= RESET_TIMEOUT) {
+		aprint_error_dev(hsc->sc_dev, "reset timeout (%x)\n", reg);
+	}
+
+	usb_delay_ms(&hsc->sc_bus, 100);
+}
+
+void
+imxehci_host_mode(struct imxehci_softc *sc)
+{
+	struct ehci_softc *hsc = &sc->sc_hsc;
+	uint32_t reg;
+
+	reg = EOREAD4(hsc, EHCI_PORTSC(1));
+	reg &= ~(EHCI_PS_CSC | EHCI_PS_PEC | EHCI_PS_OCC);
+	reg |= EHCI_PS_PP | EHCI_PS_PE;
+	EOWRITE4(hsc, EHCI_PORTSC(1), reg);
+
+	reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IMXUSB_OTGSC);
+	reg |= OTGSC_IDPU;
+	reg |= OTGSC_DPIE | OTGSC_IDIE;
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, IMXUSB_OTGSC, reg);
+
+	reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, IMXUSB_OTGMODE);
+	reg |= USBMODE_HOST;
+	bus_space_write_4(sc->sc_iot, sc->sc_ioh, IMXUSB_OTGMODE, reg);
+}
Index: src/sys/arch/arm/imx/imxusbreg.h
diff -u /dev/null src/sys/arch/arm/imx/imxusbreg.h:1.1
--- /dev/null	Tue Nov 30 13:05:27 2010
+++ src/sys/arch/arm/imx/imxusbreg.h	Tue Nov 30 13:05:27 2010
@@ -0,0 +1,113 @@
+/*	$NetBSD: imxusbreg.h,v 1.1 2010/11/30 13:05:27 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.
+ */
+
+#ifndef _ARM_IMX_IMXUSBREG_H
+#define _ARM_IMX_IMXUSBREG_H
+
+#define	IMXUSB_ID		0x0000
+#define	 IMXUSB_ID_ID_MASK		__BITS(5,0)
+#define	 IMXUSB_ID_REVISION_SHIFT	16
+#define	 IMXUSB_ID_REVISION_MASK	__BITS(IMXUSB_ID_REVISION_SHIFT,23)
+#define	IMXUSB_HWGENERAL	0x0004
+#define	IMXUSB_HWHOST		0x0008
+#define	 HWHOST_HC			__BIT(0)
+#define	 HWHOST_NPORT_SHIFT		1
+#define	 HWHOST_NPORT_MASK		__BITS(HWHOST_NPORT_SHIFT,3)
+#define	IMXUSB_HWDEVICE		0x000c
+#define	 HWDEVICE_DC			__BIT(0)
+#define	 HWDEVICE_DEVEP_SHIFT		1
+#define	 HWDEVICE_DEVEP_MASK		__BITS(HWDEVICE_DEVEP_SHIFT,5)
+#define	IMXUSB_HWTXBUF		0x0010
+#define	IMXUSB_HWRXBUF		0x0014
+
+#define	IMXUSB_EHCIREGS	0x0100
+
+#define	IMXUSB_ULPIVIEW	0x0170
+#define	 ULPI_WU	__BIT(31)
+#define	 ULPI_RUN	__BIT(30)
+#define	 ULPI_RW	__BIT(29)
+#define	 ULPI_SS	__BIT(27)
+#define	 ULPI_PORT_SHIFT	24
+#define	 ULPI_PORT_MASK		(0x7 << ULPI_PORT_SHIFT)
+#define	 ULPI_ADDR_SHIFT	16
+#define	 ULPI_ADDR_MASK		(0xff << ULPI_ADDR_SHIFT)
+#define	 ULPI_DATRD_SHIFT	8
+#define	 ULPI_DATRD_MASK	(0xff << ULPI_DATRD_SHIFT)
+#define	 ULPI_DATWR_SHIFT	0
+#define	 ULPI_DATWR_MASK	(0xff << ULPI_DATWR_SHIFT)
+
+#define	IMXUSB_OTGSC	0x01A4
+#define	 OTGSC_DPIE	__BIT(30)
+#define	 OTGSC_1MSE	__BIT(29)
+#define	 OTGSC_BSEIE	__BIT(28)
+#define	 OTGSC_BSVIE	__BIT(27)
+#define	 OTGSC_ASVIE	__BIT(26)
+#define	 OTGSC_AVVIE	__BIT(25)
+#define	 OTGSC_IDIE	__BIT(24)
+#define	 OTGSC_DPIS	__BIT(22)
+#define	 OTGSC_1MSS	__BIT(21)
+#define	 OTGSC_BSEIS	__BIT(20)
+#define	 OTGSC_BSVIS	__BIT(19)
+#define	 OTGSC_ASVIS	__BIT(18)
+#define	 OTGSC_AVVIS	__BIT(17)
+#define	 OTGSC_IDIS	__BIT(16)
+#define	 OTGSC_DPS	__BIT(14)
+#define	 OTGSC_1MST	__BIT(13)
+#define	 OTGSC_BSE	__BIT(12)
+#define	 OTGSC_BSV	__BIT(11)
+#define	 OTGSC_ASV	__BIT(10)
+#define	 OTGSC_AVV	__BIT( 9)
+#define	 OTGSC_ID	__BIT( 8)
+#define	 OTGSC_IDPU	__BIT( 5)
+#define	 OTGSC_DP	__BIT( 4)
+#define	 OTGSC_OT	__BIT( 3)
+#define	 OTGSC_VC	__BIT( 1)
+#define	 OTGSC_VD	__BIT( 0)
+#define	IMXUSB_OTGMODE	0x01A8
+#define	 USBMODE_DEVICE	(0x2 << 0)
+#define	 USBMODE_HOST	(0x3 << 0)
+
+#define	IMXUSB_EHCI_SIZE	0x200
+
+
+/* extension to PORTSCx register of EHCI. */
+#define	PORTSC_PTS_SHIFT	30
+#define	PORTSC_PTS_MASK 	__BITS(PORTSC_PTS_SHIFT,31)
+#define	PORTSC_PTS_UTMI		(0 << PORTSC_PTS_SHIFT)
+#define	PORTSC_PTS_PHILIPS	(1 << PORTSC_PTS_SHIFT) /* not in i.MX51*/
+#define	PORTSC_PTS_ULPI		(2 << PORTSC_PTS_SHIFT)
+#define	PORTSC_PTS_SERIAL	(3 << PORTSC_PTS_SHIFT)
+
+#define	PORTSC_STS	__BIT(29)	/* serial transeiver select */
+#define	PORTSC_PTW	__BIT(28)	/* parallel transceiver width */
+#define	PORTSC_PTW_8	0
+#define	PORTSC_PTW_16	PORT_SC_PTW
+#define	PORTSC_PSPD	__BITS(26,27)	/* port speed (RO) */
+#define	PORTSC_PFSC	__BIT(24)	/* port force full speed */
+#define	PORTSC_PHCD	__BIT(23)	/* PHY low power suspend */
+
+#endif	/* _ARM_IMX_IMXUSBREG_H */
Index: src/sys/arch/arm/imx/imxusbvar.h
diff -u /dev/null src/sys/arch/arm/imx/imxusbvar.h:1.1
--- /dev/null	Tue Nov 30 13:05:27 2010
+++ src/sys/arch/arm/imx/imxusbvar.h	Tue Nov 30 13:05:27 2010
@@ -0,0 +1,51 @@
+#ifndef _ARM_IMX_IMXUSBVAR_H
+#define _ARM_IMX_IMXUSBVAR_H
+
+struct imxehci_softc;
+
+enum imx_usb_role {
+	IMXUSB_HOST,
+	IMXUSB_DEVICE
+};
+
+struct imxusbc_softc {
+	device_t sc_dev;
+	bus_space_tag_t sc_iot;
+	bus_space_handle_t sc_ioh;
+
+	/* filled in by platform dependent routine */
+	void (* sc_init_md_hook)(struct imxehci_softc *);
+	void (* sc_setup_md_hook)(struct imxehci_softc *, enum imx_usb_role);
+};
+
+struct imxusbc_attach_args {
+	bus_space_tag_t aa_iot;
+	bus_space_handle_t aa_ioh;
+	bus_dma_tag_t aa_dmat;
+	int aa_unit;	/* 0: OTG, 1: HOST1, 2: HOST2 ... */
+	int aa_irq;
+};
+
+enum imx_usb_if {
+	IMXUSBC_IF_UTMI,
+	IMXUSBC_IF_PHILIPS,
+	IMXUSBC_IF_ULPI,
+	IMXUSBC_IF_SERIAL
+};
+
+struct imxehci_softc {
+	ehci_softc_t sc_hsc;
+
+	bus_space_tag_t sc_iot;
+	bus_space_handle_t sc_ioh;
+	struct imxusbc_softc *sc_usbc;
+	uint sc_unit;
+	enum imx_usb_if sc_iftype;
+};
+
+int imxusbc_attach_common(device_t, device_t, bus_space_tag_t);
+void imxehci_select_interface(struct imxehci_softc *, enum imx_usb_if);
+void imxehci_host_mode(struct imxehci_softc *);
+void imxehci_reset(struct imxehci_softc *);
+
+#endif	/* _ARM_IMX_IMXUSBVAR_H */

Reply via email to