imx6: add support for gw5400-a
authorluka <luka@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Mon, 15 Jul 2013 23:18:39 +0000 (23:18 +0000)
committerluka <luka@3c298f89-4303-0410-b956-a3cf2f4a3e73>
Mon, 15 Jul 2013 23:18:39 +0000 (23:18 +0000)
Signed-off-by: Tim Harvey <tharvey@gateworks.com>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@37363 3c298f89-4303-0410-b956-a3cf2f4a3e73

target/linux/imx6/config-3.10
target/linux/imx6/files-3.10/arch/arm/boot/dts/imx6q-gw5400-a.dts [new file with mode: 0644]
target/linux/imx6/files-3.10/arch/arm/boot/dts/imx6q-ventana.dtsi [new file with mode: 0644]
target/linux/imx6/files-3.10/arch/arm/mach-imx/msi.c [new file with mode: 0644]
target/linux/imx6/files-3.10/arch/arm/mach-imx/msi.h [new file with mode: 0644]
target/linux/imx6/files-3.10/arch/arm/mach-imx/pcie.c [new file with mode: 0644]
target/linux/imx6/files-3.10/firmware/imx/sdma/sdma-imx6q-to1.bin.ihex [new file with mode: 0644]
target/linux/imx6/image/Makefile

index a1f147a..a5982f7 100644 (file)
@@ -20,6 +20,7 @@ CONFIG_ARCH_REQUIRE_GPIOLIB=y
 # CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
 # CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
 # CONFIG_ARCH_SUNXI is not set
+CONFIG_ARCH_SUPPORTS_MSI=y
 CONFIG_ARCH_SUSPEND_POSSIBLE=y
 # CONFIG_ARCH_VIRT is not set
 CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
@@ -28,13 +29,11 @@ CONFIG_ARM=y
 # CONFIG_ARM_APPENDED_DTB is not set
 # CONFIG_ARM_CPU_SUSPEND is not set
 # CONFIG_ARM_ERRATA_430973 is not set
-# CONFIG_ARM_ERRATA_643719 is not set
 # CONFIG_ARM_ERRATA_720789 is not set
 CONFIG_ARM_ERRATA_754322=y
 # CONFIG_ARM_ERRATA_754327 is not set
 CONFIG_ARM_ERRATA_764369=y
 CONFIG_ARM_ERRATA_775420=y
-# CONFIG_ARM_ERRATA_798181 is not set
 CONFIG_ARM_GIC=y
 CONFIG_ARM_L1_CACHE_SHIFT=6
 CONFIG_ARM_L1_CACHE_SHIFT_6=y
@@ -70,8 +69,11 @@ CONFIG_CPU_TLB_V7=y
 CONFIG_CPU_V7=y
 CONFIG_CRC16=y
 CONFIG_CRYPTO_CRC32C=y
+CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_LZO=y
+CONFIG_CRYPTO_XZ=y
 CONFIG_DCACHE_WORD_ACCESS=y
 CONFIG_DEBUG_IMX_UART_PORT=1
 CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
@@ -79,7 +81,6 @@ CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
 # CONFIG_DEBUG_USER is not set
 CONFIG_DECOMPRESS_BZIP2=y
 CONFIG_DECOMPRESS_GZIP=y
-CONFIG_DECOMPRESS_LZMA=y
 CONFIG_DECOMPRESS_LZO=y
 CONFIG_DECOMPRESS_XZ=y
 CONFIG_DMADEVICES=y
@@ -97,6 +98,8 @@ CONFIG_EXT3_FS_XATTR=y
 CONFIG_EXT4_FS=y
 CONFIG_EXT4_FS_POSIX_ACL=y
 CONFIG_EXT4_FS_SECURITY=y
+CONFIG_EXTRA_FIRMWARE="imx/sdma/sdma-imx6q-to1.bin"
+CONFIG_EXTRA_FIRMWARE_DIR="firmware"
 CONFIG_FEC=y
 CONFIG_FRAME_POINTER=y
 CONFIG_FS_MBCACHE=y
@@ -148,6 +151,7 @@ CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
 CONFIG_HAVE_FUNCTION_TRACER=y
 CONFIG_HAVE_GENERIC_DMA_COHERENT=y
 CONFIG_HAVE_GENERIC_HARDIRQS=y
+CONFIG_HAVE_IDE=y
 CONFIG_HAVE_IMX_ANATOP=y
 CONFIG_HAVE_IMX_GPC=y
 CONFIG_HAVE_IMX_MMDC=y
@@ -166,9 +170,13 @@ CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
 CONFIG_HAVE_SMP=y
 CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
 CONFIG_HAVE_UID16=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_IMX=y
 # CONFIG_IMX2_WDT is not set
 # CONFIG_IMX_DMA is not set
-# CONFIG_IMX_SDMA is not set
+CONFIG_IMX_PCIE=y
+CONFIG_IMX_SDMA=y
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_IRQCHIP=y
 CONFIG_IRQ_DOMAIN=y
@@ -179,10 +187,10 @@ CONFIG_KTIME_SCALAR=y
 CONFIG_LOCAL_TIMERS=y
 CONFIG_LZO_COMPRESS=y
 CONFIG_LZO_DECOMPRESS=y
+CONFIG_M25PXX_USE_FAST_READ=y
 # CONFIG_MACH_EUKREA_CPUIMX51SD is not set
 # CONFIG_MACH_IMX51_DT is not set
 # CONFIG_MACH_MX51_BABBAGE is not set
-# CONFIG_MCPM is not set
 CONFIG_MDIO_BOARDINFO=y
 CONFIG_MFD_SYSCON=y
 CONFIG_MMC=y
@@ -191,18 +199,30 @@ CONFIG_MMC_BLOCK=y
 CONFIG_MMC_SDHCI=y
 CONFIG_MMC_SDHCI_ESDHC_IMX=y
 CONFIG_MMC_SDHCI_IO_ACCESSORS=y
+# CONFIG_MMC_SDHCI_PCI is not set
 CONFIG_MMC_SDHCI_PLTFM=y
+# CONFIG_MMC_TIFM_SD is not set
 CONFIG_MODULES_USE_ELF_REL=y
 # CONFIG_MPCORE_WATCHDOG is not set
+CONFIG_MTD_M25P80=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_ECC=y
+CONFIG_MTD_NAND_GPMI_NAND=y
 CONFIG_MTD_OF_PARTS=y
 # CONFIG_MTD_PHYSMAP_OF is not set
+# CONFIG_MTD_SM_COMMON is not set
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_BEB_LIMIT=20
+# CONFIG_MTD_UBI_FASTMAP is not set
+# CONFIG_MTD_UBI_GLUEBI is not set
+CONFIG_MTD_UBI_WL_THRESHOLD=4096
 CONFIG_MULTI_IRQ_HANDLER=y
 CONFIG_MUTEX_SPIN_ON_OWNER=y
 CONFIG_MX3_IPU=y
 CONFIG_MX3_IPU_IRQS=4
 # CONFIG_MXC_DEBUG_BOARD is not set
 # CONFIG_MXC_IRQ_PRIOR is not set
-# CONFIG_MXS_DMA is not set
+CONFIG_MXS_DMA=y
 CONFIG_NEED_DMA_MAP_STATE=y
 # CONFIG_NET_DMA is not set
 # CONFIG_NET_IP_TUNNEL is not set
@@ -217,15 +237,19 @@ CONFIG_OF_DEVICE=y
 CONFIG_OF_EARLY_FLATTREE=y
 CONFIG_OF_FLATTREE=y
 CONFIG_OF_GPIO=y
+CONFIG_OF_I2C=y
 CONFIG_OF_IRQ=y
 CONFIG_OF_MDIO=y
 CONFIG_OF_MTD=y
 CONFIG_OF_NET=y
+CONFIG_OF_PCI=y
+CONFIG_OF_PCI_IRQ=y
 CONFIG_OLD_SIGACTION=y
 CONFIG_OLD_SIGSUSPEND3=y
 CONFIG_PAGEFLAGS_EXTENDED=y
 CONFIG_PAGE_OFFSET=0xC0000000
-# CONFIG_PCI_SYSCALL is not set
+CONFIG_PCI=y
+CONFIG_PCI_MSI=y
 CONFIG_PERF_USE_VMALLOC=y
 CONFIG_PHYLIB=y
 CONFIG_PINCONF=y
@@ -241,13 +265,14 @@ CONFIG_PROC_DEVICETREE=y
 CONFIG_PTP_1588_CLOCK=y
 CONFIG_RATIONAL=y
 CONFIG_RCU_STALL_COMMON=y
-# CONFIG_RCU_USER_QS is not set
 CONFIG_RD_BZIP2=y
 CONFIG_RD_GZIP=y
 CONFIG_RD_LZO=y
 CONFIG_RD_XZ=y
 CONFIG_REGMAP=y
+CONFIG_REGMAP_I2C=y
 CONFIG_REGMAP_MMIO=y
+CONFIG_REGMAP_SPI=y
 CONFIG_RFS_ACCEL=y
 CONFIG_RPS=y
 CONFIG_SCHED_HRTICK=y
@@ -259,6 +284,11 @@ CONFIG_SMP_ON_UP=y
 # CONFIG_SOC_IMX53 is not set
 CONFIG_SOC_IMX6Q=y
 CONFIG_SPARSE_IRQ=y
+CONFIG_SPI=y
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_IMX=y
+CONFIG_SPI_MASTER=y
+CONFIG_STMP_DEVICE=y
 CONFIG_STOP_MACHINE=y
 # CONFIG_SWP_EMULATE is not set
 CONFIG_SYS_SUPPORTS_APM_EMULATION=y
@@ -266,11 +296,15 @@ CONFIG_SYS_SUPPORTS_APM_EMULATION=y
 # CONFIG_THUMB2_KERNEL is not set
 CONFIG_TICK_CPU_ACCOUNTING=y
 CONFIG_TREE_RCU=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_UBIFS_FS_LZO=y
+CONFIG_UBIFS_FS_XZ=y
+CONFIG_UBIFS_FS_ZLIB=y
 CONFIG_UID16=y
 CONFIG_UIDGID_CONVERTED=y
 CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
-# CONFIG_USB_ARCH_HAS_OHCI is not set
-# CONFIG_USB_ARCH_HAS_XHCI is not set
+CONFIG_USB_ARCH_HAS_XHCI=y
 CONFIG_USE_GENERIC_SMP_HELPERS=y
 CONFIG_USE_OF=y
 CONFIG_VECTORS_BASE=0xffff0000
@@ -279,4 +313,6 @@ CONFIG_VECTORS_BASE=0xffff0000
 CONFIG_XPS=y
 CONFIG_ZBOOT_ROM_BSS=0x0
 CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_ZLIB_INFLATE=y
 CONFIG_ZONE_DMA_FLAG=0
diff --git a/target/linux/imx6/files-3.10/arch/arm/boot/dts/imx6q-gw5400-a.dts b/target/linux/imx6/files-3.10/arch/arm/boot/dts/imx6q-gw5400-a.dts
new file mode 100644 (file)
index 0000000..d79d272
--- /dev/null
@@ -0,0 +1,429 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/dts-v1/;
+#include "imx6q-ventana.dtsi"
+
+/ {
+       model = "Gateworks Ventana GW5400-A";
+       compatible = "gw,imx6q-gw5400-a", "gw,ventana", "fsl,imx6q";
+
+       aliases {
+               ethernet0 = &fec;
+               ethernet1 = &eth1;
+               sky2 = &eth1;
+       };
+
+       /* SDRAM addressing */
+       memory {
+               reg = <0x10000000 0x40000000>;
+       };
+
+       chosen {
+               bootargs = "console=ttymxc1,115200";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               led0: user0 {
+                       label = "user0";
+                       gpios = <&gpio4 6 0>; /* 102 -> MX6_PANLEDG# */
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led1: user1 {
+                       label = "user1";
+                       gpios = <&gpio4 10 0>; /* 106 -> MX6_PANLEDR# */
+               };
+
+               led2: user2 {
+                       label = "user2";
+                       gpios = <&gpio4 15 0>; /* 111 -> MX6_LOCLEDR# */
+               };
+       };
+
+       regulators {
+               compatible = "simple-bus";
+
+               reg_2p5v: 2p5v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "2P5V";
+                       regulator-min-microvolt = <2500000>;
+                       regulator-max-microvolt = <2500000>;
+                       regulator-always-on;
+               };
+
+               reg_3p3v: 3p3v {
+                       compatible = "regulator-fixed";
+                       regulator-name = "3P3V";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_usb_otg_vbus: usb_otg_vbus {
+                       compatible = "regulator-fixed";
+                       regulator-name = "usb_otg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       gpio = <&gpio3 22 0>;
+                       enable-active-high;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx6q-sabrelite-sgtl5000",
+                            "fsl,imx-audio-sgtl5000";
+               model = "imx6q-sabrelite-sgtl5000";
+               ssi-controller = <&ssi1>;
+               audio-codec = <&codec>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <1>;
+               mux-ext-port = <4>;
+       };
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       hog {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               /* USB OTG Power Enable */
+                               MX6Q_PAD_EIM_D22__GPIO3_IO22   0x80000000
+
+                               /*  3:19 SPINOR_CS0# */
+                               MX6Q_PAD_EIM_D19__GPIO3_IO19   0x80000000
+
+                               /*  1:09 MX6_DIO0 (could also be PWM1_PWM0) */
+                               MX6Q_PAD_GPIO_9__GPIO1_IO09    0x80000000
+                               /*  1:19 MX6_DIO1 (could also be PWM2_PWM0) */
+                               MX6Q_PAD_SD1_DAT2__GPIO1_IO19  0x80000000
+                               /*  2:09 MX6_DIO2 (could also be PWM3_PWM0) */
+                               MX6Q_PAD_SD4_DAT1__GPIO2_IO09  0x80000000
+                               /*  2:10 MX6_DIO3 (could also be PWM3_PWM0) */
+                               MX6Q_PAD_SD4_DAT2__GPIO2_IO10  0x80000000
+
+                               /*  1:16 USBHUB_RST# */
+                               MX6Q_PAD_SD1_DAT0__GPIO1_IO16   0x80000000
+
+                               /* PCIE IRQ */
+                               MX6Q_PAD_ENET_TX_EN__GPIO1_IO28 0x80000000
+                               /* PCIE RST */
+                               MX6Q_PAD_ENET_TXD1__GPIO1_IO29  0x08000000
+
+                               /*  1:12 MIPI_DIO */
+                               MX6Q_PAD_SD1_DAT3__GPIO1_IO21   0x80000000
+
+                               /*  AUD4_MCK */
+                               MX6Q_PAD_GPIO_0__CCM_CLKO1      0x80000000
+                        >;
+               };
+       };
+
+#if 0
+       /* ipu1: IPU1_CSI0: HDMI reciver (Digital Video In) */
+       ipu1 {
+               pinctrl_ipu1_1: ipu1grp-5 {
+                       fsl,pins = <
+                               MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC
+                               MX6Q_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN
+                               MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK
+                               MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC
+                               MX6Q_PAD_CSI0_DAT4__IPU1_CSI0_DATA04
+                               MX6Q_PAD_CSI0_DAT5__IPU1_CSI0_DATA05
+                               MX6Q_PAD_CSI0_DAT6__IPU1_CSI0_DATA06
+                               MX6Q_PAD_CSI0_DAT7__IPU1_CSI0_DATA07
+                               MX6Q_PAD_CSI0_DAT8__IPU1_CSI0_DATA08
+                               MX6Q_PAD_CSI0_DAT9__IPU1_CSI0_DATA09
+                               MX6Q_PAD_CSI0_DAT10__IPU1_CSI0_DATA10
+                               MX6Q_PAD_CSI0_DAT11__IPU1_CSI0_DATA11
+                               MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_DATA12
+                               MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_DATA13
+                               MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_DATA14
+                               MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_DATA15
+                               MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_DATA16
+                               MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_DATA17
+                               MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_DATA18
+                               MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_DATA19
+                       >;
+               };
+       };
+
+       /* ipu2: IPU1_CSI1: Analog Video Decoder (Analog Video In) */
+       /* IPU2_CSI1: Analog Video Decoder (Analog Video In) */
+       ipu2 {
+               pinctrl_ipu2_1: ipu2grp-1 {
+                       fsl,pins = <
+                               MX6Q_PAD_EIM_A17__IPU2_CSI1_DATA12
+                               MX6Q_PAD_EIM_D27__IPU2_CSI1_DATA13
+                               MX6Q_PAD_EIM_D26__IPU2_CSI1_DATA14
+                               MX6Q_PAD_EIM_D20__IPU2_CSI1_DATA15
+                               MX6Q_PAD_EIM_D19__IPU2_CSI1_DATA16
+                               MX6Q_PAD_EIM_D18__IPU2_CSI1_DATA17
+                               MX6Q_PAD_EIM_D16__IPU2_CSI1_DATA18
+                               MX6Q_PAD_EIM_EB2__IPU2_CSI1_DATA19
+
+                               MX6Q_PAD_EIM_D29__IPU2_CSI1_VSYNC
+                               MX6Q_PAD_EIM_EB3__IPU2_CSI1_HSYNC
+// not sure why this causes kernel to crash in early init
+//                     MX6Q_PAD_EIM_A16__IPU2_CSI1_PIXCLK
+                       >;
+               };
+       };
+
+       /* ipu3: IPU2_DISP0: Analog Video Encoder (Analog Video Out) */
+       ipu3 {
+               pinctrl_ipu3_1: ipu3grp-5 {
+                       fsl,pins = <
+                               MX6Q_PAD_DISP0_DAT0__IPU2_DISP0_DATA00
+                               MX6Q_PAD_DISP0_DAT1__IPU2_DISP0_DATA01
+                               MX6Q_PAD_DISP0_DAT2__IPU2_DISP0_DATA02
+                               MX6Q_PAD_DISP0_DAT3__IPU2_DISP0_DATA03
+                               MX6Q_PAD_DISP0_DAT4__IPU2_DISP0_DATA04
+                               MX6Q_PAD_DISP0_DAT5__IPU2_DISP0_DATA05
+                               MX6Q_PAD_DISP0_DAT6__IPU2_DISP0_DATA06
+                               MX6Q_PAD_DISP0_DAT7__IPU2_DISP0_DATA07
+                               MX6Q_PAD_DISP0_DAT8__IPU2_DISP0_DATA08
+                               MX6Q_PAD_DISP0_DAT9__IPU2_DISP0_DATA09
+                               MX6Q_PAD_DISP0_DAT10__IPU2_DISP0_DATA10
+                               MX6Q_PAD_DISP0_DAT11__IPU2_DISP0_DATA11
+                               MX6Q_PAD_DISP0_DAT12__IPU2_DISP0_DATA12
+                               MX6Q_PAD_DISP0_DAT13__IPU2_DISP0_DATA13
+                               MX6Q_PAD_DISP0_DAT14__IPU2_DISP0_DATA14
+                               MX6Q_PAD_DISP0_DAT15__IPU2_DISP0_DATA15
+                       >;
+               };
+       };
+#endif
+};
+
+&ecspi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi1_1>;
+       status = "okay";
+
+       flash: m25p80@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "sst,w25q256";
+               spi-max-frequency = <30000000>;
+               reg = <0>;
+       };
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1_2>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2_2>;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3_1>;
+       status = "okay";
+};
+
+&uart5 {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5_1>;
+};
+
+&ssi1 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&ssi2 {
+       fsl,mode = "i2s-slave";
+       status = "okay";
+};
+
+&can1 {
+       reg = <0x02090000 0x4000>;
+       interrupts = <0 110 0x04>;
+       //clock-frequency
+       status = "okay";
+};
+
+&usbh1 {
+       status = "okay";
+};
+
+&pcie {
+       rst-gpios = <&gpio1 29 0>; /* PCIESWT_RST# */
+       clken-gpios = <&gpio1 20 0>; /* not used */
+       status = "okay";
+
+       eth1: sky2@8 { /* MAC/PHY on bus 8 */
+               compatible = "marvell,sky2";
+               /* Filled in by U-Boot */
+               mac-address = [ 00 00 00 00 00 00 ];
+       };      
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet_1>;
+       phy-mode = "rgmii";
+       phy-reset-gpios = <&gpio1 30 0>;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc3_2>;
+       cd-gpios = <&gpio7 0 0>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
+
+&audmux {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_audmux_3>;
+       status = "okay";
+};
+
+&i2c1 {
+       status = "okay";
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1_1>;
+
+       eeprom: eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       eeprom1: eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       eeprom2: eeprom@51 {
+               compatible = "atmel,24c02";
+               reg = <0x51>;
+               pagesize = <16>;
+       };
+
+       eeprom3: eeprom@52 {
+               compatible = "atmel,24c02";
+               reg = <0x52>;
+               pagesize = <16>;
+       };
+
+       eeprom4: eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+               pagesize = <16>;
+       };
+
+       rtc: ds1672@68 {
+               compatible = "dallas,ds1672";
+               reg = <0x68>;
+       };
+
+       gpio: pca9555@23 {
+               compatible = "nxp,pca9555";
+               reg = <0x23>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       hwmon: gsc@29 {
+               compatible = "gw,gsp";
+               reg = <0x29>;
+       };
+};
+
+&i2c2 {
+       status = "okay";
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2_2>;
+
+       pmic: pfuze@08 {
+               compatible = "fsl,pfuze100";
+               reg = <0x0a>;
+       };
+
+       pciswitch: pex8609@3f {
+               compatible = "plx,pex8609";
+               reg = <0x3f>;
+       };
+
+       pciclkgen: si52147@6b {
+               compatible = "sil,si52147";
+               reg = <0x6b>;
+       };
+};
+
+&i2c3 {
+       status = "okay";
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3_2>;
+
+       codec: sgtl5000@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               clocks = <&clks 169>;
+               VDDA-supply = <&reg_2p5v>;
+               VDDIO-supply = <&reg_3p3v>;
+       };
+
+       accelerometer: mma8450@1c {
+               compatible = "fsl,mma8450";
+               reg = <0x1c>;
+       };
+
+       videoout: adv7393@2a {
+               compatible = "adi,adv7393";
+               reg = <0x2a>;
+       };
+
+       videoin: adv7180@20 {
+               compatible = "adi,adv7180";
+               reg = <0x20>;
+       };
+
+       hdmiin: adv7611@4c {
+               compatible = "adi,adv7611";
+               reg = <0x4c>;
+       };
+
+       touchscreen: egalax_ts@04 {
+               compatible = "eeti,egalax_ts";
+               reg = <0x04>;
+               wakeup-gpios = <&gpio1 12 0>;
+       };
+};
+
+&ldb {
+       status = "okay";
+       lvds-channel@0 {
+               crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
+       };
+};
diff --git a/target/linux/imx6/files-3.10/arch/arm/boot/dts/imx6q-ventana.dtsi b/target/linux/imx6/files-3.10/arch/arm/boot/dts/imx6q-ventana.dtsi
new file mode 100644 (file)
index 0000000..7cebdba
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2013 Gateworks Corporation
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include "imx6q.dtsi"
+
+/ {
+       model = "Gateworks Ventana";
+       system-serial = "";
+
+       // these are used by bootloader for disabling nodes
+       aliases {
+               // ethernet0 = &eth0;
+               // ethernet1 = &eth1;
+               ssi0 = &ssi1;
+               ssi1 = &ssi2;
+               ipu0 = &ipu1;
+               ipu1 = &ipu2;
+               // mipi_csi = &mipi_csi;
+               // mipi_dsi = &mipi_dsi;
+               usdhc0 = &usdhc1;
+               usdhc1 = &usdhc2;
+               usdhc2 = &usdhc3;
+               usdhc3 = &usdhc4;
+               i2c0 = &i2c1;
+               i2c1 = &i2c2;
+               i2c2 = &i2c3;
+               usb0 = &usbh3;
+               usb1 = &usbotg;
+               spi0 = &ecspi1;
+               spi1 = &ecspi2;
+               spi2 = &ecspi3;
+               spi3 = &ecspi4;
+               spi4 = &ecspi5;
+               pwm0 = &pwm1;
+               pwm1 = &pwm2;
+               pwm2 = &pwm3;
+               pwm3 = &pwm4;
+               can0 = &can1;
+               led0 = &led0;
+               led1 = &led1;
+               led2 = &led2;
+       };
+};
diff --git a/target/linux/imx6/files-3.10/arch/arm/mach-imx/msi.c b/target/linux/imx6/files-3.10/arch/arm/mach-imx/msi.c
new file mode 100644 (file)
index 0000000..8850eaf
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * arch/arm/mach-mx6/msi.c
+ *
+ * PCI MSI support for the imx processor
+ *
+ * Copyright (c) 2013, Boundary Devices.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place - Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/msi.h>
+#include <asm/bitops.h>
+#include <asm/mach/irq.h>
+#include <asm/irq.h>
+#include <linux/irqchip/chained_irq.h>
+
+#include "hardware.h"
+#include "msi.h"
+
+#define IMX_NUM_MSI_IRQS 128
+static DECLARE_BITMAP(msi_irq_in_use, IMX_NUM_MSI_IRQS);
+static int irq_base;
+
+static void imx_msi_handler(unsigned int irq, struct irq_desc *desc)
+{
+       int i, j;
+       unsigned status;
+       struct irq_chip *chip = irq_get_chip(irq);
+
+       irq_base = irq_alloc_descs(-1, 0, IMX_NUM_MSI_IRQS, 0);
+       if (irq_base < 0) {
+               printk(KERN_ERR "%s: could not allocate IRQ numbers\n", __func__);
+               return;
+       }
+
+       chained_irq_enter(chip, desc);
+       for (i = 0; i < 8; i++) {
+               status = imx_pcie_msi_pending(i);
+               while (status) {
+                       j = __fls(status);
+                       generic_handle_irq(irq_base + j);
+                       status &= ~(1 << j);
+               }
+               irq_base += 32;
+       }
+       chained_irq_exit(chip, desc);
+}
+
+/*
+ * Dynamic irq allocate and deallocation
+ */
+int create_irq(void)
+{
+       int irq, pos;
+
+       do {
+               pos = find_first_zero_bit(msi_irq_in_use, IMX_NUM_MSI_IRQS);
+               if ((unsigned)pos >= IMX_NUM_MSI_IRQS)
+                       return -ENOSPC;
+               /* test_and_set_bit operates on 32-bits at a time */
+       } while (test_and_set_bit(pos, msi_irq_in_use));
+
+       irq = irq_base + pos;
+       dynamic_irq_init(irq);
+       return irq;
+}
+
+void destroy_irq(unsigned int irq)
+{
+       int pos = irq - irq_base;
+
+       dynamic_irq_cleanup(irq);
+       clear_bit(pos, msi_irq_in_use);
+}
+
+void arch_teardown_msi_irq(unsigned int irq)
+{
+       destroy_irq(irq);
+}
+
+static void imx_msi_irq_ack(struct irq_data *d)
+{
+       return;
+}
+
+static void imx_msi_irq_enable(struct irq_data *d)
+{
+       imx_pcie_enable_irq(d->irq - irq_base, 1);
+       return unmask_msi_irq(d);
+}
+
+static void imx_msi_irq_disable(struct irq_data *d)
+{
+       imx_pcie_enable_irq(d->irq - irq_base, 0);
+       return mask_msi_irq(d);
+}
+
+static void imx_msi_irq_mask(struct irq_data *d)
+{
+       imx_pcie_mask_irq(d->irq - irq_base, 1);
+       return mask_msi_irq(d);
+}
+
+static void imx_msi_irq_unmask(struct irq_data *d)
+{
+       imx_pcie_mask_irq(d->irq - irq_base, 0);
+       return unmask_msi_irq(d);
+}
+
+static struct irq_chip imx_msi_chip = {
+       .name = "PCIe-MSI",
+       .irq_ack = imx_msi_irq_ack,
+       .irq_enable = imx_msi_irq_enable,
+       .irq_disable = imx_msi_irq_disable,
+       .irq_mask = imx_msi_irq_mask,
+       .irq_unmask = imx_msi_irq_unmask,
+};
+
+int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+{
+       int irq = create_irq();
+       struct msi_msg msg;
+
+       if (irq < 0)
+               return irq;
+
+       irq_set_msi_desc(irq, desc);
+
+       msg.address_hi = 0x0;
+       msg.address_lo = MSI_MATCH_ADDR;
+       msg.data = (mxc_cpu_type << 15) | ((irq - irq_base) & 0xff);
+
+       write_msi_msg(irq, &msg);
+       irq_set_chip_and_handler(irq, &imx_msi_chip, handle_simple_irq);
+       set_irq_flags(irq, IRQF_VALID);
+       pr_info("%s: %d of %d\n", __func__, irq, NR_IRQS);
+       return 0;
+}
+
+void imx_msi_init(void)
+{
+       irq_set_chained_handler(MXC_INT_PCIE_0, imx_msi_handler);
+}
diff --git a/target/linux/imx6/files-3.10/arch/arm/mach-imx/msi.h b/target/linux/imx6/files-3.10/arch/arm/mach-imx/msi.h
new file mode 100644 (file)
index 0000000..3f9be01
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 Boundary Devices, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+void imx_pcie_enable_irq(unsigned pos, int set);
+void imx_pcie_mask_irq(unsigned pos, int set);
+unsigned imx_pcie_msi_pending(unsigned index);
+
+#define MSI_MATCH_ADDR 0x10000050
+#define MXC_INT_PCIE_0      152
+#define MXC_INT_PCIE_1      153
+#define MXC_INT_PCIE_2      154
+#define MXC_INT_PCIE_3      155
+
+void imx_msi_init(void);
diff --git a/target/linux/imx6/files-3.10/arch/arm/mach-imx/pcie.c b/target/linux/imx6/files-3.10/arch/arm/mach-imx/pcie.c
new file mode 100644 (file)
index 0000000..44bd560
--- /dev/null
@@ -0,0 +1,1037 @@
+/*
+ * arch/arm/mach-imx/pcie.c
+ *
+ * PCIe host controller driver for IMX6 SOCs
+ *
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2013 Tim Harvey <tharvey@gateworks.com>
+ *
+ * Bits taken from arch/arm/mach-dove/pcie.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+
+#include <asm/signal.h>
+#include <asm/mach/pci.h>
+#include <asm/sizes.h>
+
+#include "msi.h"
+
+/* PCIe Registers */
+#define PCIE_ARB_BASE_ADDR  0x01000000
+#define PCIE_ARB_END_ADDR   0x01FFFFFF
+#define PCIE_RC_IOBLSSR     0x1c
+
+/* Register Definitions */
+#define PRT_LOG_R_BaseAddress 0x700
+
+/* Register DB_R0 */
+/* Debug Register 0 */
+#define DB_R0 (PRT_LOG_R_BaseAddress + 0x28)
+#define DB_R0_RegisterSize 32
+#define DB_R0_RegisterResetValue 0x0
+#define DB_R0_RegisterResetMask 0xFFFFFFFF
+/* End of Register Definition for DB_R0 */
+
+/* Register DB_R1 */
+/* Debug Register 1 */
+#define DB_R1 (PRT_LOG_R_BaseAddress + 0x2c)
+#define DB_R1_RegisterSize 32
+#define DB_R1_RegisterResetValue 0x0
+#define DB_R1_RegisterResetMask 0xFFFFFFFF
+/* End of Register Definition for DB_R1 */
+
+#define PCIE_PL_MSICA          0x820
+#define PCIE_PL_MSICUA         0x824
+#define PCIE_PL_MSIC_INT       0x828
+
+#define MSIC_INT_EN    0x0
+#define MSIC_INT_MASK  0x4
+#define MSIC_INT_STATUS        0x8
+
+#define ATU_R_BaseAddress 0x900
+#define ATU_VIEWPORT_R (ATU_R_BaseAddress + 0x0)
+#define ATU_REGION_CTRL1_R (ATU_R_BaseAddress + 0x4)
+#define ATU_REGION_CTRL2_R (ATU_R_BaseAddress + 0x8)
+#define ATU_REGION_LOWBASE_R (ATU_R_BaseAddress + 0xC)
+#define ATU_REGION_UPBASE_R (ATU_R_BaseAddress + 0x10)
+#define ATU_REGION_LIMIT_ADDR_R (ATU_R_BaseAddress + 0x14)
+#define ATU_REGION_LOW_TRGT_ADDR_R (ATU_R_BaseAddress + 0x18)
+#define ATU_REGION_UP_TRGT_ADDR_R (ATU_R_BaseAddress + 0x1C)
+
+/* IOMUXC */
+#define IOMUXC_GPR_BASE_ADDR   0x020E0000
+#define IOMUXC_GPR1     (imx_pcie.gpr_base + 0x04)
+#define IOMUXC_GPR8     (imx_pcie.gpr_base + 0x20)
+#define IOMUXC_GPR12    (imx_pcie.gpr_base + 0x30)
+/* GPR1: iomuxc_gpr1_pcie_ref_clk_en(iomuxc_gpr1[16]) */
+#define iomuxc_gpr1_pcie_ref_clk_en            (1 << 16)
+/* GPR1: iomuxc_gpr1_test_powerdown(iomuxc_gpr1_18) */
+#define iomuxc_gpr1_test_powerdown             (1 << 18)
+/* GPR12: iomuxc_gpr12_los_level(iomuxc_gpr12[8:4]) */
+#define iomuxc_gpr12_los_level                 (0x1F << 4)
+/* GPR12: iomuxc_gpr12_app_ltssm_enable(iomuxc_gpr12[10]) */
+#define iomuxc_gpr12_app_ltssm_enable          (1 << 10)
+/* GPR12: iomuxc_gpr12_device_type(iomuxc_gpr12[15:12]) */
+#define iomuxc_gpr12_device_type               (0xF << 12)
+/* GPR8: iomuxc_gpr8_tx_deemph_gen1(iomuxc_gpr8[5:0]) */
+#define iomuxc_gpr8_tx_deemph_gen1             (0x3F << 0)
+/* GPR8: iomuxc_gpr8_tx_deemph_gen2_3p5db(iomuxc_gpr8[11:6]) */
+#define iomuxc_gpr8_tx_deemph_gen2_3p5db       (0x3F << 6)
+/* GPR8: iomuxc_gpr8_tx_deemph_gen2_6db(iomuxc_gpr8[17:12]) */
+#define iomuxc_gpr8_tx_deemph_gen2_6db         (0x3F << 12)
+/* GPR8: iomuxc_gpr8_tx_swing_full(iomuxc_gpr8[24:18]) */
+#define iomuxc_gpr8_tx_swing_full              (0x7F << 18)
+/* GPR8: iomuxc_gpr8_tx_swing_low(iomuxc_gpr8[31:25]) */
+#define iomuxc_gpr8_tx_swing_low               (0x7F << 25)
+
+/* Registers of PHY */
+/* Register PHY_STS_R */
+/* PHY Status Register */
+#define PHY_STS_R (PRT_LOG_R_BaseAddress + 0x110)
+
+/* Register PHY_CTRL_R */
+/* PHY Control Register */
+#define PHY_CTRL_R (PRT_LOG_R_BaseAddress + 0x114)
+
+#define SSP_CR_SUP_DIG_MPLL_OVRD_IN_LO 0x0011
+/* FIELD: RES_ACK_IN_OVRD [15:15]
+// FIELD: RES_ACK_IN [14:14]
+// FIELD: RES_REQ_IN_OVRD [13:13]
+// FIELD: RES_REQ_IN [12:12]
+// FIELD: RTUNE_REQ_OVRD [11:11]
+// FIELD: RTUNE_REQ [10:10]
+// FIELD: MPLL_MULTIPLIER_OVRD [9:9]
+// FIELD: MPLL_MULTIPLIER [8:2]
+// FIELD: MPLL_EN_OVRD [1:1]
+// FIELD: MPLL_EN [0:0]
+*/
+
+#define SSP_CR_SUP_DIG_ATEOVRD 0x0010
+/* FIELD: ateovrd_en [2:2]
+// FIELD: ref_usb2_en [1:1]
+// FIELD: ref_clkdiv2 [0:0]
+*/
+
+#define SSP_CR_LANE0_DIG_RX_OVRD_IN_LO 0x1005
+/* FIELD: RX_LOS_EN_OVRD [13:13]
+// FIELD: RX_LOS_EN [12:12]
+// FIELD: RX_TERM_EN_OVRD [11:11]
+// FIELD: RX_TERM_EN [10:10]
+// FIELD: RX_BIT_SHIFT_OVRD [9:9]
+// FIELD: RX_BIT_SHIFT [8:8]
+// FIELD: RX_ALIGN_EN_OVRD [7:7]
+// FIELD: RX_ALIGN_EN [6:6]
+// FIELD: RX_DATA_EN_OVRD [5:5]
+// FIELD: RX_DATA_EN [4:4]
+// FIELD: RX_PLL_EN_OVRD [3:3]
+// FIELD: RX_PLL_EN [2:2]
+// FIELD: RX_INVERT_OVRD [1:1]
+// FIELD: RX_INVERT [0:0]
+*/
+
+#define SSP_CR_LANE0_DIG_RX_ASIC_OUT 0x100D
+/* FIELD: LOS [2:2]
+// FIELD: PLL_STATE [1:1]
+// FIELD: VALID [0:0]
+*/
+
+/* control bus bit definition */
+#define PCIE_CR_CTL_DATA_LOC 0
+#define PCIE_CR_CTL_CAP_ADR_LOC 16
+#define PCIE_CR_CTL_CAP_DAT_LOC 17
+#define PCIE_CR_CTL_WR_LOC 18
+#define PCIE_CR_CTL_RD_LOC 19
+#define PCIE_CR_STAT_DATA_LOC 0
+#define PCIE_CR_STAT_ACK_LOC 16
+
+#define PCIE_CAP_STRUC_BaseAddress 0x70
+
+/* Register LNK_CAP */
+/* PCIE Link cap */
+#define LNK_CAP (PCIE_CAP_STRUC_BaseAddress + 0xc)
+
+/* End of Register Definitions */
+
+enum {
+       MemRdWr = 0,
+       MemRdLk = 1,
+       IORdWr = 2,
+       CfgRdWr0 = 4,
+       CfgRdWr1 = 5
+};
+
+struct imx_pcie_port {
+       u8                      index;
+       u8                      root_bus_nr;
+       void __iomem            *base;
+       void __iomem            *dbi_base;
+       spinlock_t              conf_lock;
+
+       char                    io_space_name[16];
+       char                    mem_space_name[16];
+
+       struct resource         res[2];
+       struct clk *clk;
+};
+
+struct imx_pcie_info {
+       struct imx_pcie_port imx_pcie_port[1];
+       int num_pcie_ports;
+
+       void __iomem *base;
+       void __iomem *dbi_base;
+       void __iomem *gpr_base;
+
+       unsigned int pcie_pwr_en;
+       unsigned int pcie_rst;
+       unsigned int pcie_wake_up;
+       unsigned int pcie_dis;
+};
+
+static struct imx_pcie_info imx_pcie;
+
+static int pcie_phy_cr_read(int addr, int *data);
+static int pcie_phy_cr_write(int addr, int data);
+static void change_field(int *in, int start, int end, int val);
+
+/* IMX PCIE GPR configure routines */
+static inline void imx_pcie_clrset(u32 mask, u32 val, void __iomem *addr)
+{
+       writel(((readl(addr) & ~mask) | (val & mask)), addr);
+}
+
+static int imx_pcie_setup(int nr, struct pci_sys_data *sys)
+{
+       struct imx_pcie_port *pp;
+
+       if (nr >= imx_pcie.num_pcie_ports)
+               return 0;
+
+       pp = &imx_pcie.imx_pcie_port[nr];
+       pp->root_bus_nr = sys->busnr;
+
+       /*
+        * IORESOURCE_IO
+        */
+       snprintf(pp->io_space_name, sizeof(pp->io_space_name),
+                "PCIe %d I/O", pp->index);
+       pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
+       pp->res[0].name = pp->io_space_name;
+       if (pp->index == 0) {
+               pp->res[0].start = PCIE_ARB_BASE_ADDR;
+               pp->res[0].end = pp->res[0].start + SZ_1M - 1;
+       }
+       pp->res[0].flags = IORESOURCE_IO;
+       if (request_resource(&ioport_resource, &pp->res[0]))
+               panic("Request PCIe IO resource failed\n");
+       pci_add_resource_offset(&sys->resources, &pp->res[0], sys->io_offset);
+
+       /*
+        * IORESOURCE_MEM
+        */
+       snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
+                       "PCIe %d MEM", pp->index);
+       pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
+       pp->res[1].name = pp->mem_space_name;
+       if (pp->index == 0) {
+               pp->res[1].start = PCIE_ARB_BASE_ADDR + SZ_1M;
+               pp->res[1].end = pp->res[1].start + SZ_16M - SZ_2M - 1;
+       }
+       pp->res[1].flags = IORESOURCE_MEM;
+       if (request_resource(&iomem_resource, &pp->res[1]))
+               panic("Request PCIe Memory resource failed\n");
+       pci_add_resource_offset(&sys->resources, &pp->res[1], sys->mem_offset);
+
+       return 1;
+}
+
+static int imx_pcie_link_up(void __iomem *dbi_base)
+{
+       /* Check the pcie link up or link down */
+       int iterations = 200;
+       u32 rc, ltssm, rx_valid, temp;
+
+       do {
+               /* link is debug bit 36 debug 1 start in bit 32 */
+               rc = readl(dbi_base + DB_R1) & (0x1 << (36 - 32)) ;
+               iterations--;
+               usleep_range(2000, 3000);
+
+               /* From L0, initiate MAC entry to gen2 if EP/RC supports gen2.
+                * Wait 2ms (LTSSM timeout is 24ms, PHY lock is ~5us in gen2).
+                * If (MAC/LTSSM.state == Recovery.RcvrLock)
+                * && (PHY/rx_valid==0) then pulse PHY/rx_reset. Transition
+                * to gen2 is stuck
+                */
+               pcie_phy_cr_read(SSP_CR_LANE0_DIG_RX_ASIC_OUT, &rx_valid);
+               ltssm = readl(dbi_base + DB_R0) & 0x3F;
+               if ((ltssm == 0x0D) && ((rx_valid & 0x01) == 0)) {
+                       pr_info("Transition to gen2 is stuck, reset PHY!\n");
+                       pcie_phy_cr_read(SSP_CR_LANE0_DIG_RX_OVRD_IN_LO, &temp);
+                       change_field(&temp, 3, 3, 0x1);
+                       change_field(&temp, 5, 5, 0x1);
+                       pcie_phy_cr_write(SSP_CR_LANE0_DIG_RX_OVRD_IN_LO,
+                                       0x0028);
+                       usleep_range(2000, 3000);
+                       pcie_phy_cr_read(SSP_CR_LANE0_DIG_RX_OVRD_IN_LO, &temp);
+                       change_field(&temp, 3, 3, 0x0);
+                       change_field(&temp, 5, 5, 0x0);
+                       pcie_phy_cr_write(SSP_CR_LANE0_DIG_RX_OVRD_IN_LO,
+                                       0x0000);
+               }
+
+               if ((iterations < 0))
+                       pr_info("link up failed, DB_R0:0x%08x, DB_R1:0x%08x!\n"
+                                       , readl(dbi_base + DB_R0)
+                                       , readl(dbi_base + DB_R1));
+       } while (!rc && iterations);
+
+       if (!rc)
+               return 0;
+       return 1;
+}
+
+static void imx_pcie_regions_setup(void __iomem *dbi_base)
+{
+       unsigned bus;
+       unsigned i;
+       unsigned untranslated_base = PCIE_ARB_END_ADDR +1 - SZ_1M;
+       void __iomem *p = dbi_base + PCIE_PL_MSIC_INT;
+       /*
+        * i.MX6 defines 16MB in the AXI address map for PCIe.
+        *
+        * That address space excepted the pcie registers is
+        * split and defined into different regions by iATU,
+        * with sizes and offsets as follows:
+        *
+        * 0x0100_0000 --- 0x010F_FFFF 1MB IORESOURCE_IO
+        * 0x0110_0000 --- 0x01EF_FFFF 14MB IORESOURCE_MEM
+        * 0x01F0_0000 --- 0x01FF_FFFF 1MB Cfg + Registers
+        */
+
+       /* CMD reg:I/O space, MEM space, and Bus Master Enable */
+       writel(readl(dbi_base + PCI_COMMAND)
+                       | PCI_COMMAND_IO
+                       | PCI_COMMAND_MEMORY
+                       | PCI_COMMAND_MASTER,
+                       dbi_base + PCI_COMMAND);
+
+       /* Set the CLASS_REV of RC CFG header to PCI_CLASS_BRIDGE_PCI */
+       writel(readl(dbi_base + PCI_CLASS_REVISION)
+                       | (PCI_CLASS_BRIDGE_PCI << 16),
+                       dbi_base + PCI_CLASS_REVISION);
+
+       /*
+        * region0-3 outbound used to access target cfg
+        */
+       for (bus = 1; bus <= 4; bus++) {
+               writel(bus - 1, dbi_base + ATU_VIEWPORT_R);
+               writel(untranslated_base, dbi_base + ATU_REGION_LOWBASE_R);
+               untranslated_base += (1 << 18);
+               if (bus == 4)
+                       untranslated_base -= (1 << 14); //(remove registers)
+               writel(untranslated_base - 1, dbi_base + ATU_REGION_LIMIT_ADDR_R);
+               writel(0, dbi_base + ATU_REGION_UPBASE_R);
+
+               writel(bus << 24, dbi_base + ATU_REGION_LOW_TRGT_ADDR_R);
+               writel(0, dbi_base + ATU_REGION_UP_TRGT_ADDR_R);
+               writel((bus > 1) ? CfgRdWr1 : CfgRdWr0,
+                               dbi_base + ATU_REGION_CTRL1_R);
+               writel((1<<31), dbi_base + ATU_REGION_CTRL2_R);
+       }
+
+       writel(MSI_MATCH_ADDR, dbi_base + PCIE_PL_MSICA);
+       writel(0, dbi_base + PCIE_PL_MSICUA);
+       for (i = 0; i < 8 ; i++) {
+               writel(0, p + MSIC_INT_EN);
+               writel(0xffffffff, p + MSIC_INT_MASK);
+               writel(0xffffffff, p + MSIC_INT_STATUS);
+               p += 12;
+       }
+}
+
+void imx_pcie_mask_irq(unsigned pos, int set)
+{
+       unsigned mask = 1 << (pos & 0x1f);
+       unsigned val, newval;
+       void __iomem *p = imx_pcie.dbi_base + PCIE_PL_MSIC_INT + MSIC_INT_MASK + ((pos >> 5) * 12);
+       if (pos >= (8 * 32))
+               return;
+       val = readl(p);
+       if (set)
+               newval = val | mask;
+       else
+               newval = val & ~mask;
+       if (val != newval)
+               writel(newval, p);
+}
+
+void imx_pcie_enable_irq(unsigned pos, int set)
+{
+       unsigned mask = 1 << (pos & 0x1f);
+       unsigned val, newval;
+       void __iomem *p = imx_pcie.dbi_base + PCIE_PL_MSIC_INT + MSIC_INT_EN + ((pos >> 5) * 12);
+       if (pos >= (8 * 32))
+               return;
+       val = readl(p);
+       if (set)
+               newval = val | mask;
+       else
+               newval = val & ~mask;
+       if (val != newval)
+               writel(newval, p);
+       if (set && (val != newval))
+               imx_pcie_mask_irq(pos, 0);      /* unmask when enabled */
+}
+
+unsigned imx_pcie_msi_pending(unsigned index)
+{
+       unsigned val, mask;
+       void __iomem *p = imx_pcie.dbi_base + PCIE_PL_MSIC_INT + (index * 12);
+       if (index >= 8)
+               return 0;
+       val = readl(p + MSIC_INT_STATUS);
+       mask = readl(p + MSIC_INT_MASK);
+       val &= ~mask;
+       writel(val, p + MSIC_INT_STATUS);
+       return val;
+}
+
+static char master_abort(struct pci_bus *bus, u32 devfn, int where)
+{
+       u32 reg;
+       void __iomem *dbi_base = imx_pcie.dbi_base;
+       int ret = 0;
+
+       reg = readl(dbi_base + PCIE_RC_IOBLSSR);
+       if (reg & 0x71000000) {
+               if (reg & 1<<30)
+                       pr_err("%d:%02d.%d 0x%04x: parity error\n", bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where);
+               if (reg & 1<<29) {
+                       pr_err("%d:%02d.%d 0x%04x: master abort\n", bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where);
+                       ret = 1;
+               }
+               if (reg & 1<<28)
+                       pr_err("%d:%02d.%d 0x%04x: target abort\n", bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where);
+               if (reg & 1<<24)
+                       pr_err("%d:%02d.%d 0x%04x: master data parity error\n", bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where);
+               writel(reg, dbi_base + PCIE_RC_IOBLSSR);
+               udelay(1500); // without this delay subsequent reads through bridge can erroneously return 0???
+       }
+       return ret;
+}
+
+static volatile void *get_cfg_addr(struct pci_bus *bus, u32 devfn, int where)
+{
+       unsigned busnum;
+       void __iomem *base = imx_pcie.base;
+       void __iomem *dbi_base = imx_pcie.dbi_base;
+
+       if (!bus->number) {
+               if (devfn != 0)
+                       return 0;
+               return (imx_pcie.dbi_base) + (where & 0x0ffc);
+       }
+       if ((devfn > 0xff) || (bus->number > 15))
+               return 0;
+       busnum = bus->number - 1;
+       if ((busnum < 3) && (devfn <= 3)) {
+               return (base) + (busnum << 18) + (devfn << 16) + (where & 0xfffc);
+       }
+       writel(3, dbi_base + ATU_VIEWPORT_R);
+       writel((bus->number << 24) | (devfn << 16),
+                       dbi_base + ATU_REGION_LOW_TRGT_ADDR_R);
+       writel((bus->number > 1) ? CfgRdWr1 : CfgRdWr0,
+                       dbi_base + ATU_REGION_CTRL1_R);
+       return (base) + (3 << 18) + (where & 0xfffc);
+}
+
+static int imx_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+                       int size, u32 *val)
+{
+       const volatile void *va_address;
+       u32 v;
+
+       if (0)
+               pr_info("%s: bus=%x, devfn=%x, where=%x size=%x\n", __func__, bus->number, devfn, where, size);
+       va_address = get_cfg_addr(bus, devfn, where);
+       if (!va_address) {
+               *val = 0xffffffff;
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       }
+       v = readl(va_address);
+       if (master_abort(bus, devfn, where)) {
+               return PCIBIOS_DEVICE_NOT_FOUND;        
+       }
+       if (0)
+               pr_info("%s: bus=%x, devfn=%x, where=%x size=%x v=%x\n", __func__, bus->number, devfn, where, size, v);
+       if (size == 4) {
+               *val = v;
+       } else if (size == 1) {
+               *val = (v >> (8 * (where & 3))) & 0xFF;
+       } else if (size == 2) {
+               *val = (v >> (8 * (where & 3))) & 0xFFFF;
+       } else {
+               *val = 0xffffffff;
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+       }
+       return PCIBIOS_SUCCESSFUL;
+}
+
+static int imx_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
+                       int where, int size, u32 val)
+{
+       volatile void *va_address;
+       u32 mask, tmp;
+
+       if (0)
+               pr_info("%s: bus=%x, devfn=%x, where=%x size=%x val=%x\n", __func__, bus->number, devfn, where, size, val);
+       va_address = get_cfg_addr(bus, devfn, where);
+       if (!va_address)
+               return PCIBIOS_DEVICE_NOT_FOUND;
+       if (size == 4) {
+               writel(val, va_address);
+               return (master_abort(bus, devfn, where))
+                       ?PCIBIOS_DEVICE_NOT_FOUND:PCIBIOS_SUCCESSFUL;
+       }
+       if (size == 2)
+               mask = ~(0xFFFF << ((where & 0x3) * 8));
+       else if (size == 1)
+               mask = ~(0xFF << ((where & 0x3) * 8));
+       else
+               return PCIBIOS_BAD_REGISTER_NUMBER;
+
+       tmp = readl(va_address) & mask;
+       tmp |= val << ((where & 0x3) * 8);
+       writel(tmp, va_address);
+       return (master_abort(bus, devfn, where))
+               ?PCIBIOS_DEVICE_NOT_FOUND:PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops imx_pcie_ops = {
+       .read = imx_pcie_rd_conf,
+       .write = imx_pcie_wr_conf,
+};
+
+signed short irq_map[] = {
+       -EINVAL,
+       MXC_INT_PCIE_3,         /* int a */
+       MXC_INT_PCIE_2,         /* int b */
+       MXC_INT_PCIE_1,         /* int c */
+       MXC_INT_PCIE_0,         /* int d/MSI */
+};
+
+static int imx_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+       int val = -EINVAL;
+       if (pin <= 4)
+               val = irq_map[pin];
+       return val;
+}
+
+static struct hw_pci imx_pci __initdata = {
+       .nr_controllers = 1,
+       .setup          = imx_pcie_setup,
+       .ops    = &imx_pcie_ops,
+       .map_irq        = imx_pcie_map_irq,
+};
+
+/* PHY CR bus acess routines */
+static int pcie_phy_cr_ack_polling(int max_iterations, int exp_val)
+{
+       u32 temp_rd_data, wait_counter = 0;
+
+       do {
+               temp_rd_data = readl(imx_pcie.dbi_base + PHY_STS_R);
+               temp_rd_data = (temp_rd_data >> PCIE_CR_STAT_ACK_LOC) & 0x1;
+               wait_counter++;
+       } while ((wait_counter < max_iterations) && (temp_rd_data != exp_val));
+
+       if (temp_rd_data != exp_val)
+               return 0 ;
+       return 1 ;
+}
+
+static int pcie_phy_cr_cap_addr(int addr)
+{
+       u32 temp_wr_data;
+       void __iomem *dbi_base = imx_pcie.dbi_base;
+
+       /* write addr */
+       temp_wr_data = addr << PCIE_CR_CTL_DATA_LOC ;
+       writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+       /* capture addr */
+       temp_wr_data |= (0x1 << PCIE_CR_CTL_CAP_ADR_LOC);
+       writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+       /* wait for ack */
+       if (!pcie_phy_cr_ack_polling(100, 1))
+               return 0;
+
+       /* deassert cap addr */
+       temp_wr_data = addr << PCIE_CR_CTL_DATA_LOC;
+       writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+       /* wait for ack de-assetion */
+       if (!pcie_phy_cr_ack_polling(100, 0))
+               return 0 ;
+
+       return 1 ;
+}
+
+static int pcie_phy_cr_read(int addr , int *data)
+{
+       u32 temp_rd_data, temp_wr_data;
+       void __iomem *dbi_base = imx_pcie.dbi_base;
+
+       /*  write addr */
+       /* cap addr */
+       if (!pcie_phy_cr_cap_addr(addr))
+               return 0;
+
+       /* assert rd signal */
+       temp_wr_data = 0x1 << PCIE_CR_CTL_RD_LOC;
+       writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+       /* wait for ack */
+       if (!pcie_phy_cr_ack_polling(100, 1))
+               return 0;
+
+       /* after got ack return data */
+       temp_rd_data = readl(dbi_base + PHY_STS_R);
+       *data = (temp_rd_data & (0xffff << PCIE_CR_STAT_DATA_LOC)) ;
+
+       /* deassert rd signal */
+       temp_wr_data = 0x0;
+       writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+       /* wait for ack de-assetion */
+       if (!pcie_phy_cr_ack_polling(100, 0))
+               return 0 ;
+
+       return 1 ;
+
+}
+
+static int pcie_phy_cr_write(int addr, int data)
+{
+       u32 temp_wr_data;
+       void __iomem *dbi_base = imx_pcie.dbi_base;
+
+       /* write addr */
+       /* cap addr */
+       if (!pcie_phy_cr_cap_addr(addr))
+               return 0 ;
+
+       temp_wr_data = data << PCIE_CR_CTL_DATA_LOC;
+       writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+       /* capture data */
+       temp_wr_data |= (0x1 << PCIE_CR_CTL_CAP_DAT_LOC);
+       writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+       /* wait for ack */
+       if (!pcie_phy_cr_ack_polling(100, 1))
+               return 0 ;
+
+       /* deassert cap data */
+       temp_wr_data = data << PCIE_CR_CTL_DATA_LOC;
+       writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+       /* wait for ack de-assetion */
+       if (!pcie_phy_cr_ack_polling(100, 0))
+               return 0;
+
+       /* assert wr signal */
+       temp_wr_data = 0x1 << PCIE_CR_CTL_WR_LOC;
+       writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+       /* wait for ack */
+       if (!pcie_phy_cr_ack_polling(100, 1))
+               return 0;
+
+       /* deassert wr signal */
+       temp_wr_data = data << PCIE_CR_CTL_DATA_LOC;
+       writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+       /* wait for ack de-assetion */
+       if (!pcie_phy_cr_ack_polling(100, 0))
+               return 0;
+
+       temp_wr_data = 0x0 ;
+       writel(temp_wr_data, dbi_base + PHY_CTRL_R);
+
+       return 1 ;
+}
+
+static void change_field(int *in, int start, int end, int val)
+{
+       int mask;
+
+       mask = ((0xFFFFFFFF << start) ^ (0xFFFFFFFF << (end + 1))) & 0xFFFFFFFF;
+       *in = (*in & ~mask) | (val << start);
+}
+
+static int imx_pcie_enable_controller(struct device *dev)
+{
+       struct clk *clk;
+       struct device_node *np = dev->of_node;
+
+       if (gpio_is_valid(imx_pcie.pcie_pwr_en)) {
+               /* Enable PCIE power */
+               gpio_request(imx_pcie.pcie_pwr_en, "PCIE POWER_EN");
+
+               /* activate PCIE_PWR_EN */
+               gpio_direction_output(imx_pcie.pcie_pwr_en, 1);
+       }
+
+       // power up PCIe PHY
+       imx_pcie_clrset(iomuxc_gpr1_test_powerdown, 0 << 18, IOMUXC_GPR1);
+
+       /* enable the clks */
+       if (np)
+               clk = of_clk_get(np, 0);
+       else
+               clk = devm_clk_get(dev, "pcie_clk");
+       if (IS_ERR(clk)) {
+               pr_err("no pcie clock.\n");
+               return -EINVAL;
+       }
+
+       if (clk_prepare_enable(clk)) {
+               pr_err("can't enable pcie clock.\n");
+               clk_put(clk);
+               return -EINVAL;
+       }
+
+       // Enable PCIe PHY ref clock
+       imx_pcie_clrset(iomuxc_gpr1_pcie_ref_clk_en, 1 << 16, IOMUXC_GPR1);
+
+       return 0;
+}
+
+static void card_reset(struct device *dev)
+{
+       if (gpio_is_valid(imx_pcie.pcie_rst)) {
+               /* PCIE RESET */
+               gpio_request(imx_pcie.pcie_rst, "PCIE RESET");
+
+               /* activate PERST_B */
+               gpio_direction_output(imx_pcie.pcie_rst, 0);
+
+               /* Add one reset to the pcie external device */
+               msleep(100);
+
+               /* deactive PERST_B */
+               gpio_direction_output(imx_pcie.pcie_rst, 1);
+       }
+}
+
+static void add_pcie_port(struct platform_device *pdev, void __iomem *base, void __iomem *dbi_base)
+{
+       struct clk *clk;
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+
+       if (imx_pcie_link_up(dbi_base)) {
+               struct imx_pcie_port *pp = &imx_pcie.imx_pcie_port[imx_pcie.num_pcie_ports++];
+
+               pr_info("IMX PCIe port: link up.\n");
+
+               pp->index = 0;
+               pp->root_bus_nr = -1;
+               pp->base = base;
+               pp->dbi_base = dbi_base;
+               spin_lock_init(&pp->conf_lock);
+               memset(pp->res, 0, sizeof(pp->res));
+       } else {
+               pr_info("IMX PCIe port: link down!\n");
+               /* Release the clocks, and disable the power */
+
+               if (np)
+                       clk = of_clk_get(np, 0);
+               else
+                       clk = clk_get(NULL, "pcie_clk");
+               if (IS_ERR(clk)) {
+                       pr_err("no pcie clock.\n");
+                       return;
+               }
+
+               clk_disable_unprepare(clk);
+               clk_put(clk);
+
+               // Disable the PCIE PHY Ref Clock
+               imx_pcie_clrset(iomuxc_gpr1_pcie_ref_clk_en, 0 << 16, IOMUXC_GPR1);
+
+               if (gpio_is_valid(imx_pcie.pcie_pwr_en)) {
+                       /* Disable PCIE power */
+                       gpio_request(imx_pcie.pcie_pwr_en, "PCIE POWER_EN");
+
+                       /* activate PCIE_PWR_EN */
+                       gpio_direction_output(imx_pcie.pcie_pwr_en, 0);
+               }
+
+               // Power down PCIE PHY
+               imx_pcie_clrset(iomuxc_gpr1_test_powerdown, 1 << 18, IOMUXC_GPR1);
+       }
+}
+
+static int imx_pcie_abort_handler(unsigned long addr, unsigned int fsr,
+               struct pt_regs *regs)
+{
+       unsigned long instr;
+       unsigned long pc = instruction_pointer(regs) - 4;
+
+       instr = *(unsigned long *)pc;
+/* imprecise aborts are no longer enabled in 3.7+ during init it would appear.
+ * We now using PCIE_RC_IOBLSSR to detect master abort however we will still get
+ * at least one imprecise abort and need to have a handler.
+ */
+#if 0
+       if (instr == 0xf57ff04f) {
+               /* dsb sy */
+               pc -= 4;
+               instr = *(unsigned long *)pc;
+       }
+       pr_info("PCIe abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx instr=%08lx\n",
+               addr, fsr, regs->ARM_pc, regs->ARM_lr, instr);
+
+
+       /*
+        * If the instruction being executed was a read,
+        * make it look like it read all-ones.
+        */
+       if ((instr & 0x0c500000) == 0x04100000) {
+               /* LDR instruction */
+               int reg = (instr >> 12) & 15;
+
+               regs->uregs[reg] = -1;
+               regs->ARM_pc = pc + 4;
+               return 0;
+       }
+       return 1;
+#else
+       pr_info("PCIe abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx instr=%08lx\n",
+               addr, fsr, regs->ARM_pc, regs->ARM_lr, instr);
+
+       return 0;
+#endif
+}
+
+
+static int imx_pcie_pltfm_probe(struct platform_device *pdev)
+{
+       struct resource *mem;
+       struct device *dev = &pdev->dev;
+       struct device_node *np = pdev->dev.of_node;
+       struct resource res;
+       int ret;
+
+       if (!np) {
+               dev_err(&pdev->dev, "No of data found\n");
+               return -EINVAL;
+       }
+
+       res.start = res.end = 0;
+       ret = of_address_to_resource(np, 0, &res);
+       if (ret)
+               goto err;
+       mem = &res;
+       imx_pcie.pcie_pwr_en = of_get_named_gpio(np, "pwren-gpios", 0);
+       imx_pcie.pcie_rst = of_get_named_gpio(np, "rst-gpios", 0);
+       imx_pcie.pcie_wake_up = of_get_named_gpio(np, "wake-gpios", 0);
+       imx_pcie.pcie_dis = of_get_named_gpio(np, "dis-gpios", 0);
+       //pdev->dev.platform_data = pdata;
+
+       imx_pcie.base = ioremap_nocache(PCIE_ARB_END_ADDR - SZ_1M + 1, SZ_1M - SZ_16K);
+       if (!imx_pcie.base) {
+               pr_err("error with ioremap in function %s\n", __func__);
+               return -EIO;
+       }
+
+       imx_pcie.dbi_base = devm_ioremap(dev, mem->start, resource_size(mem));
+       if (!imx_pcie.dbi_base) {
+               dev_err(dev, "can't map %pR\n", mem);
+               return -ENOMEM;
+       }
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-iomuxc-gpr");
+       if (!np) {
+               dev_err(dev, "can't find iomux\n");
+               return -ENOMEM;
+       }
+       ret = of_address_to_resource(np, 0, &res);
+       of_node_put(np);
+       if (ret)
+               goto err;
+       mem = &res;
+       imx_pcie.gpr_base = devm_ioremap(dev, mem->start, resource_size(mem));
+       if (!imx_pcie.gpr_base) {
+               dev_err(dev, "can't map %pR\n", mem);
+               return -ENOMEM;
+       }
+
+       // hold LTSSM in detect state
+       imx_pcie_clrset(iomuxc_gpr12_app_ltssm_enable, 0 << 10, IOMUXC_GPR12);
+
+       /* configure constant input signal to the pcie ctrl and phy */
+       // set device type to RC (PCI_EXP_TYPE_ROOT_PORT=4 is from pcie_regs.h)
+       imx_pcie_clrset(iomuxc_gpr12_device_type, PCI_EXP_TYPE_ROOT_PORT << 12, IOMUXC_GPR12);
+       // loss of signal detect sensitivity function - must be 0x9
+       imx_pcie_clrset(iomuxc_gpr12_los_level, 9 << 4, IOMUXC_GPR12);
+       // not clear what values these should have from RM
+       imx_pcie_clrset(iomuxc_gpr8_tx_deemph_gen1, 0 << 0, IOMUXC_GPR8);
+       imx_pcie_clrset(iomuxc_gpr8_tx_deemph_gen2_3p5db, 0 << 6, IOMUXC_GPR8);
+       imx_pcie_clrset(iomuxc_gpr8_tx_deemph_gen2_6db, 20 << 12, IOMUXC_GPR8);
+       imx_pcie_clrset(iomuxc_gpr8_tx_swing_full, 127 << 18, IOMUXC_GPR8);
+       imx_pcie_clrset(iomuxc_gpr8_tx_swing_low, 127 << 25, IOMUXC_GPR8);
+
+       /* Enable the pwr, clks and so on */
+       ret = imx_pcie_enable_controller(dev);
+       if (ret)
+               goto err;
+
+       /* togle the external card's reset */
+       card_reset(dev) ;
+
+       usleep_range(3000, 4000);
+       imx_pcie_regions_setup(imx_pcie.dbi_base);
+       usleep_range(3000, 4000);
+
+       /*
+        * Force to GEN1 because of PCIE2USB storage stress tests
+        * would be failed when GEN2 is enabled
+        */
+       writel(((readl(imx_pcie.dbi_base + LNK_CAP) & 0xfffffff0) | 0x1),
+                       imx_pcie.dbi_base + LNK_CAP);
+
+       /* start link up */
+       imx_pcie_clrset(iomuxc_gpr12_app_ltssm_enable, 1 << 10, IOMUXC_GPR12);
+
+       hook_fault_code(16 + 6, imx_pcie_abort_handler, SIGBUS, 0,
+                       "imprecise external abort");
+
+       /* add the pcie port */
+       add_pcie_port(pdev, imx_pcie.base, imx_pcie.dbi_base);
+
+       pci_common_init(&imx_pci);
+
+       return 0;
+
+err:
+       return ret;
+}
+
+static int imx_pcie_pltfm_remove(struct platform_device *pdev)
+{
+       struct clk *clk;
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       struct resource *iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+       /* Release clocks, and disable power  */
+       if (np)
+               clk = of_clk_get(np, 0);
+       else
+               clk = devm_clk_get(dev, "pcie_clk");
+       if (IS_ERR(clk))
+               pr_err("no pcie clock.\n");
+
+       if (clk) {
+               clk_disable_unprepare(clk);
+               clk_put(clk);
+       }
+
+       // disable PCIe PHY clock ref
+       imx_pcie_clrset(iomuxc_gpr1_pcie_ref_clk_en, 0 << 16, IOMUXC_GPR1);
+
+       if (gpio_is_valid(imx_pcie.pcie_pwr_en)) {
+               /* Disable PCIE power */
+               gpio_request(imx_pcie.pcie_pwr_en, "PCIE POWER_EN");
+
+               /* activate PCIE_PWR_EN */
+               gpio_direction_output(imx_pcie.pcie_pwr_en, 0);
+       }
+
+       // power down PCIe PHY
+       imx_pcie_clrset(iomuxc_gpr1_test_powerdown, 1 << 18, IOMUXC_GPR1);
+
+       iounmap(imx_pcie.base);
+       iounmap(imx_pcie.dbi_base);
+       iounmap(imx_pcie.gpr_base);
+       release_mem_region(iomem->start, resource_size(iomem));
+       //platform_set_drvdata(pdev, NULL);
+
+       return 0;
+}
+
+static const struct of_device_id of_imx_pcie_match[] = {
+       { .compatible = "fsl,pcie" },
+       {}
+};
+MODULE_DEVICE_TABLE(of, of_imx_pcie_match);
+
+static struct platform_driver imx_pcie_pltfm_driver = {
+       .driver = {
+               .name   = "imx-pcie",
+               .owner  = THIS_MODULE,
+               .of_match_table = of_imx_pcie_match,
+       },
+       .probe          = imx_pcie_pltfm_probe,
+       .remove         = imx_pcie_pltfm_remove,
+};
+
+/*****************************************************************************\
+ *                                                                           *
+ * Driver init/exit                                                          *
+ *                                                                           *
+\*****************************************************************************/
+
+static int __init imx_pcie_drv_init(void)
+{
+       pcibios_min_io = 0;
+       pcibios_min_mem = 0;
+
+       return platform_driver_register(&imx_pcie_pltfm_driver);
+}
+
+static void __exit imx_pcie_drv_exit(void)
+{
+       platform_driver_unregister(&imx_pcie_pltfm_driver);
+}
+
+//module_init(imx_pcie_drv_init);
+//module_exit(imx_pcie_drv_exit);
+late_initcall(imx_pcie_drv_init);
+
+MODULE_DESCRIPTION("i.MX PCIE platform driver");
+MODULE_LICENSE("GPL v2");
diff --git a/target/linux/imx6/files-3.10/firmware/imx/sdma/sdma-imx6q-to1.bin.ihex b/target/linux/imx6/files-3.10/firmware/imx/sdma/sdma-imx6q-to1.bin.ihex
new file mode 100644 (file)
index 0000000..2e561f0
--- /dev/null
@@ -0,0 +1,116 @@
+:1000000053444D4101000000010000001C000000AD
+:1000100026000000B40000007A0600008202000002
+:10002000FFFFFFFF00000000FFFFFFFFFFFFFFFFDC
+:10003000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD0
+:10004000FFFFFFFFFFFFFFFF6A1A0000FFFFFFFF38
+:10005000EB020000BB180000FFFFFFFF08040000D8
+:10006000FFFFFFFFC0030000FFFFFFFFFFFFFFFFD9
+:10007000FFFFFFFFAB020000FFFFFFFF7B0300005D
+:10008000FFFFFFFFFFFFFFFF4C0400006E040000B6
+:10009000FFFFFFFF00180000FFFFFFFFFFFFFFFF54
+:1000A000000000000018000062180000161A00008E
+:1000B000061B0000E3C1DB57E35FE357F352016A1D
+:1000C0008F00D500017D8D00A005EB5D7804037DD8
+:1000D00079042C7D367C79041F7CEE56000F600677
+:1000E000057D0965437E0A62417E20980A623E7E54
+:1000F00009653C7E12051205AD026007037DFB55C4
+:10010000D36D2B98FB55041DD36DC86A2F7F011F3B
+:1001100003200048E47C5398FB55D76D1500057803
+:100120000962C86A0962C86AD76D5298FB55D76DD3
+:100130001500150005780A62C86A0A62C86AD76D98
+:100140005298FB55D76D15001500150005780B6208
+:10015000C86A0B62C86AD76D097CDF6D077F000033
+:10016000EB55004D077DFAC1E35706980700CC68B0
+:100170000C6813C20AC20398D9C1E3C1DB57E35F1D
+:10018000E357F352216A8F00D500017D8D00A00551
+:10019000EB5DFB567804037D79042A7D317C79047C
+:1001A000207C700B1103EB53000F6003057D096584
+:1001B000377E0A62357E86980A62327E0965307E15
+:1001C00012051205AD026007027C065A8E98265A67
+:1001D000277F011F03200048E87C700B1103135395
+:1001E000AF98150004780962065A0962265AAE983B
+:1001F0001500150004780A62065A0A62265AAE985B
+:1002000015001500150004780B62065A0B62265A79
+:10021000077C0000EB55004D067DFAC1E357699855
+:1002200007000C6813C20AC26698700B11031353BF
+:100230006C07017CD9C1FB5E8A066B07017CD9C1C2
+:10024000F35EDB59D3588F0110010F398B003CC18D
+:100250002B7DC05AC85B4EC1277C88038906E35CAE
+:10026000FF0D1105FF1DBC053E07004D187D7008F0
+:1002700011007E07097D7D07027D2852E698F8521D
+:10028000DB54BC02CC02097C7C07027D2852EF982B
+:10029000F852D354BC02CC02097D0004DD988B00D7
+:1002A000C052C85359C1D67D0002CD98FF08BF0087
+:1002B0007F07157D8804D500017D8D00A005EB5DCD
+:1002C0008F0212021202FF3ADA05027C3E071899E9
+:1002D000A402DD02027D3E0718995E071899EB55CE
+:1002E0009805EB5DF352FB546A07267D6C07017D90
+:1002F00055996B07577C6907047D6807027D010EDD
+:100300002F999358D600017D8E009355A005935DDB
+:10031000A00602780255045D1D7C004E087C69072A
+:10032000037D0255177E3C99045D147F8906935026
+:100330000048017D2799A099150006780255045DB3
+:100340004F070255245D2F07017CA09917006F0706
+:10035000017C012093559D000700A7D9F598D36C27
+:100360006907047D6807027D010E64999358D600E1
+:10037000017D8E009355A005935DA006027802557D
+:10038000C86D0F7C004E087C6907037D0255097E0D
+:100390007199C86D067F890693500048017D5C996C
+:1003A000A0999A99C36A6907047D6807027D010EC6
+:1003B00087999358D600017D8E009355A005935DD3
+:1003C000A0060278C865045D0F7C004E087C6907B2
+:1003D000037DC865097E9499045D067F8906935064
+:1003E0000048017D7F99A09993559D000700FF6CFF
+:1003F000A7D9F5980000E354EB55004D017CF59822
+:10040000DD98E354EB55FF0A1102FF1A7F07027CC7
+:10041000A005B4999D008C05BA05A0051002BA0488
+:10042000AD0454040600E3C1DB57FB52C36AF35228
+:10043000056A8F00D500017D8D00A005EB5D780475
+:10044000037D79042B7D1E7C7904337CEE56000FEE
+:10045000FB556007027DC36DD599041DC36DC8624D
+:100460003B7E6006027D10021202096A357F12028D
+:10047000096A327F1202096A2F7F011F0320004898
+:10048000E77C099AFB55C76D150015001500057826
+:10049000C8620B6AC8620B6AC76D089AFB55C76DC4
+:1004A000150015000578C8620A6AC8620A6AC76D35
+:1004B000089AFB55C76D15000578C862096AC862BD
+:1004C000096AC76D097C286A077F0000EB55004D5B
+:1004D000057DFAC1DB57BF9977C254040AC2BA99A5
+:1004E000D9C1E3C1DB57F352056A8F00D500017D06
+:1004F0008D00A005FB567804037D7904297D1F7CBF
+:1005000079042E7CE35D700D1105ED55000F600739
+:10051000027D0652329A2652337E6005027D100219
+:100520001202096A2D7F1202096A2A7F1202096AE1
+:10053000277F011F03200048EA7CE3555D9A1500E0
+:1005400015001500047806520B6A26520B6A5C9A55
+:1005500015001500047806520A6A26520A6A5C9A47
+:10056000150004780652096A2652096A097C286A2D
+:10057000077F0000DB57004D057DFAC1DB571B9A52
+:1005800077C254040AC2189AE3C1DB57F352056AD2
+:10059000FB568E02941AC36AC8626902247D941EB7
+:1005A000C36ED36EC8624802C86A9426981EC36E92
+:1005B000D36EC8624C02C86A9826C36E981EC36E7A
+:1005C000C8629826C36E6002097CC8626E02247DF0
+:1005D000096A1E7F0125004D257D849A286A187FAF
+:1005E00004627AC2B89AE36E8F00D805017D8D004F
+:1005F000A005C8626E02107D096A0A7F0120F97C9D
+:10060000286A067F0000004D0D7DFAC1DB576E9A07
+:10061000070004620C6AB59A286AFA7F04627AC2FB
+:1006200058045404286AF47F0AC26B9AD9C1E3C102
+:10063000DB57F352056AFB568E02941A0252690286
+:100640001D7D941E06524802065A9426981E065294
+:100650004C02065A9826981E065260020A7C98267A
+:1006600006526E02237D096A1D7F0125004D247DFF
+:10067000D19A286A177F04627AC2029B8F00D8053C
+:10068000017D8D00A00506526E02107D096A0A7F69
+:100690000120F97C286A067F0000004D0D7DFAC11B
+:1006A000DB57C19A070004620C6AFF9A286AFA7F36
+:1006B00004627AC258045404286AF47F0AC2BE9ABB
+:1006C000016E0B612F7E0B622D7E0B632B7E0C0D5A
+:1006D0001704170417049D04081DCC05017C0C0D9C
+:1006E000D16A000F4207C86FDD6F1C7F8E009D002E
+:1006F00001680B67177ED56B04080278C86F120774
+:10070000117C0B670F7E04080278C86F12070A7C01
+:10071000DD6F087FD169010FC86FDD6F037F0101B5
+:0E0720000004129B0700FF680C680002129B89
+:00000001FF
index 04a446d..0bcb85b 100644 (file)
@@ -8,7 +8,8 @@ include $(TOPDIR)/rules.mk
 include $(INCLUDE_DIR)/image.mk
 
 BOARDS := \
-       imx6dl-wandboard
+       imx6dl-wandboard \
+       imx6q-gw5400-a
 
 # board-specific Flattened Image Tree
 define mkfit