summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Documentation/devicetree/bindings/README6
-rw-r--r--Documentation/devicetree/bindings/misc/fsl,imx-iim.txt20
-rw-r--r--Makefile4
-rw-r--r--arch/arm/Kconfig7
-rw-r--r--arch/arm/Makefile234
-rw-r--r--arch/arm/boards/crystalfontz-cfa10036/hwdetect.c16
-rw-r--r--arch/arm/boards/freescale-mx51-pdk/Makefile4
-rw-r--r--arch/arm/boards/freescale-mx51-pdk/board.c106
-rw-r--r--arch/arm/boards/freescale-mx51-pdk/dcd-data.h60
-rw-r--r--arch/arm/boards/freescale-mx51-pdk/flash-header.imxcfg59
-rw-r--r--arch/arm/boards/freescale-mx51-pdk/flash_header.c29
-rw-r--r--arch/arm/boards/freescale-mx6-sabrelite/board.c156
-rw-r--r--arch/arm/boards/freescale-mx6-sabresd/board.c143
-rw-r--r--arch/arm/boards/globalscale-guruplug/Makefile1
-rw-r--r--arch/arm/boards/globalscale-guruplug/board.c17
-rw-r--r--arch/arm/boards/globalscale-guruplug/config.h4
-rw-r--r--arch/arm/boards/globalscale-guruplug/kwbimage.cfg27
-rw-r--r--arch/arm/boards/globalscale-mirabox/Makefile1
-rw-r--r--arch/arm/boards/globalscale-mirabox/board.c17
-rw-r--r--arch/arm/boards/globalscale-mirabox/config.h4
-rw-r--r--arch/arm/boards/globalscale-mirabox/kwbimage.cfg5
-rw-r--r--arch/arm/boards/marvell-armada-xp-gp/Makefile1
-rw-r--r--arch/arm/boards/marvell-armada-xp-gp/board.c17
-rw-r--r--arch/arm/boards/marvell-armada-xp-gp/config.h4
-rw-r--r--arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg3
-rw-r--r--arch/arm/boards/pcm038/pcm038.c30
-rw-r--r--arch/arm/boards/pcm049/board.c4
-rw-r--r--arch/arm/boards/pcm049/lowlevel.c31
-rw-r--r--arch/arm/boards/plathome-openblocks-ax3/Makefile1
-rw-r--r--arch/arm/boards/plathome-openblocks-ax3/board.c17
-rw-r--r--arch/arm/boards/plathome-openblocks-ax3/config.h4
-rw-r--r--arch/arm/boards/plathome-openblocks-ax3/kwbimage.cfg3
-rw-r--r--arch/arm/boards/qil-a926x/Makefile (renamed from arch/arm/boards/qil-a9260/Makefile)0
-rw-r--r--arch/arm/boards/qil-a926x/config.h (renamed from arch/arm/boards/qil-a9260/config.h)0
-rw-r--r--arch/arm/boards/qil-a926x/env/bin/init_board (renamed from arch/arm/boards/qil-a9260/env/bin/init_board)0
-rw-r--r--arch/arm/boards/qil-a926x/env/config (renamed from arch/arm/boards/qil-a9260/env/config)3
-rw-r--r--arch/arm/boards/qil-a926x/init.c (renamed from arch/arm/boards/qil-a9260/init.c)35
-rw-r--r--arch/arm/boards/qil-a926x/qil-a9260.dox (renamed from arch/arm/boards/qil-a9260/qil-a9260.dox)0
-rw-r--r--arch/arm/boards/solidrun-cubox/Makefile1
-rw-r--r--arch/arm/boards/solidrun-cubox/board.c17
-rw-r--r--arch/arm/boards/solidrun-cubox/config.h4
-rw-r--r--arch/arm/boards/solidrun-cubox/kwbimage.cfg37
-rw-r--r--arch/arm/configs/freescale-mx6-sabrelite_defconfig28
-rw-r--r--arch/arm/configs/freescale_mx51_babbage_defconfig16
-rw-r--r--arch/arm/configs/globalscale_guruplug_defconfig6
-rw-r--r--arch/arm/configs/globalscale_mirabox_defconfig8
-rw-r--r--arch/arm/configs/marvell_armada_xp_gp_defconfig10
-rw-r--r--arch/arm/configs/plathome_openblocks_ax3_defconfig9
-rw-r--r--arch/arm/configs/qil_a9260_128mib_defconfig14
-rw-r--r--arch/arm/configs/qil_a9260_defconfig14
-rw-r--r--arch/arm/configs/qil_a9g20_128mib_defconfig77
-rw-r--r--arch/arm/configs/qil_a9g20_defconfig76
-rw-r--r--arch/arm/configs/solidrun_cubox_defconfig9
-rw-r--r--arch/arm/configs/tegra20_colibri_iris_defconfig24
-rw-r--r--arch/arm/cpu/Kconfig8
-rw-r--r--arch/arm/cpu/cpuinfo.c2
-rw-r--r--arch/arm/dts/Makefile11
-rw-r--r--arch/arm/dts/imx51-babbage.dts307
-rw-r--r--arch/arm/dts/imx51-pinfunc.h773
-rw-r--r--arch/arm/dts/imx51.dtsi723
-rw-r--r--arch/arm/dts/imx6q-pinfunc.h1041
-rw-r--r--arch/arm/dts/imx6q-sabrelite.dts174
-rw-r--r--arch/arm/dts/imx6q-sabresd.dts43
-rw-r--r--arch/arm/dts/imx6q.dtsi358
-rw-r--r--arch/arm/dts/imx6qdl-sabresd.dtsi87
-rw-r--r--arch/arm/dts/imx6qdl.dtsi840
-rw-r--r--arch/arm/dts/tegra20-colibri-iris.dts32
-rw-r--r--arch/arm/dts/tegra20-colibri.dtsi190
-rw-r--r--arch/arm/dts/tegra20-paz00.dts216
-rw-r--r--arch/arm/dts/tegra20.dtsi8
-rw-r--r--arch/arm/lib/bootm.c6
-rw-r--r--arch/arm/lib/module.c6
-rw-r--r--arch/arm/mach-at91/Kconfig12
-rw-r--r--arch/arm/mach-bcm2835/core.c1
-rw-r--r--arch/arm/mach-imx/Kconfig25
-rw-r--r--arch/arm/mach-imx/clk-imx6.c2
-rw-r--r--arch/arm/mach-imx/iim.c64
-rw-r--r--arch/arm/mach-imx/imx25.c6
-rw-r--r--arch/arm/mach-imx/imx51.c58
-rw-r--r--arch/arm/mach-imx/imx6.c3
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx1.h1
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx21.h1
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx25.h1
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx27.h1
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx35.h1
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx51.h3
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx53.h1
-rw-r--r--arch/arm/mach-imx/include/mach/devices-imx6.h1
-rw-r--r--arch/arm/mach-imx/include/mach/generic.h3
-rw-r--r--arch/arm/mach-imx/include/mach/iim.h4
-rw-r--r--arch/arm/mach-imx/include/mach/imx5.h1
-rw-r--r--arch/arm/mach-imx/include/mach/iomux-v1.h2
-rw-r--r--arch/arm/mach-imx/include/mach/weim.h2
-rw-r--r--arch/arm/mach-mvebu/Kconfig124
-rw-r--r--arch/arm/mach-mvebu/Makefile6
-rw-r--r--arch/arm/mach-mvebu/armada-370-xp.c121
-rw-r--r--arch/arm/mach-mvebu/common.c57
-rw-r--r--arch/arm/mach-mvebu/dove.c145
-rw-r--r--arch/arm/mach-mvebu/include/mach/armada-370-xp-regs.h47
-rw-r--r--arch/arm/mach-mvebu/include/mach/common.h23
-rw-r--r--arch/arm/mach-mvebu/include/mach/debug_ll.h43
-rw-r--r--arch/arm/mach-mvebu/include/mach/dove-regs.h62
-rw-r--r--arch/arm/mach-mvebu/include/mach/dove.h23
-rw-r--r--arch/arm/mach-mvebu/include/mach/kirkwood-regs.h50
-rw-r--r--arch/arm/mach-mvebu/include/mach/kirkwood.h22
-rw-r--r--arch/arm/mach-mvebu/include/mach/lowlevel.h23
-rw-r--r--arch/arm/mach-mvebu/include/mach/mvebu.h22
-rw-r--r--arch/arm/mach-mvebu/kirkwood.c107
-rw-r--r--arch/arm/mach-mvebu/lowlevel.c28
-rw-r--r--arch/arm/mach-mxs/imx.c44
-rw-r--r--arch/arm/mach-omap/Kconfig12
-rw-r--r--arch/arm/mach-omap/am33xx_clock.c8
-rw-r--r--arch/arm/mach-omap/am33xx_mux.c35
-rw-r--r--arch/arm/mach-omap/include/mach/am33xx-clock.h3
-rw-r--r--arch/arm/mach-omap/include/mach/am33xx-mux.h3
-rw-r--r--arch/arm/mach-omap/omap4_twl6030_mmc.c19
-rw-r--r--arch/arm/mach-tegra/Kconfig13
-rw-r--r--arch/mips/Kconfig19
-rw-r--r--arch/mips/Makefile15
-rw-r--r--arch/mips/boards/netgear-wg102/Kconfig6
-rw-r--r--arch/mips/boards/netgear-wg102/Makefile1
-rw-r--r--arch/mips/boards/netgear-wg102/ram.c11
-rw-r--r--arch/mips/boards/qemu-malta/init.c11
-rw-r--r--arch/mips/boards/rzx50/include/board/board_pbl_start.h34
-rw-r--r--arch/mips/boards/rzx50/include/board/debug_ll.h5
-rw-r--r--arch/mips/boards/rzx50/serial.c37
-rw-r--r--arch/mips/boot/Makefile2
-rw-r--r--arch/mips/boot/dtb.c61
-rw-r--r--arch/mips/configs/qemu-malta_defconfig17
-rw-r--r--arch/mips/configs/rzx50_defconfig3
-rw-r--r--arch/mips/dts/Makefile10
-rw-r--r--arch/mips/dts/qemu-malta.dts12
-rw-r--r--arch/mips/dts/skeleton.dtsi13
-rw-r--r--arch/mips/include/asm/debug_ll_ns16550.h100
-rw-r--r--arch/mips/include/asm/mipsregs.h8
-rw-r--r--arch/mips/lib/barebox.lds.S2
-rw-r--r--arch/mips/mach-ar231x/Kconfig17
-rw-r--r--arch/mips/mach-ar231x/Makefile3
-rw-r--r--arch/mips/mach-ar231x/ar231x.c195
-rw-r--r--arch/mips/mach-ar231x/ar231x_reset.c73
-rw-r--r--arch/mips/mach-ar231x/board.c188
-rw-r--r--arch/mips/mach-ar231x/include/mach/ar2312_regs.h302
-rw-r--r--arch/mips/mach-ar231x/include/mach/ar231x_platform.h104
-rw-r--r--arch/mips/mach-xburst/Kconfig18
-rw-r--r--arch/mips/mach-xburst/Makefile1
-rw-r--r--arch/mips/mach-xburst/include/mach/debug_ll_jz4750d.h37
-rw-r--r--arch/mips/mach-xburst/include/mach/devices.h8
-rw-r--r--arch/mips/mach-xburst/include/mach/jz4750d_regs.h2
-rw-r--r--arch/mips/mach-xburst/serial.c60
-rw-r--r--arch/ppc/boards/.gitignore1
-rw-r--r--arch/ppc/include/asm/io.h71
-rw-r--r--arch/sandbox/board/hostfile.c5
-rw-r--r--arch/x86/include/asm/types.h4
-rw-r--r--commands/Kconfig9
-rw-r--r--commands/Makefile1
-rw-r--r--commands/bootm.c6
-rw-r--r--commands/detect.c77
-rw-r--r--common/block.c38
-rw-r--r--common/globalvar.c4
-rw-r--r--common/hush.c2
-rw-r--r--common/oftree.c21
-rw-r--r--common/partitions.c2
-rw-r--r--common/partitions/Kconfig1
-rw-r--r--common/partitions/dos.c88
-rw-r--r--common/partitions/efi.c4
-rw-r--r--drivers/ata/ahci.c2
-rw-r--r--drivers/ata/sata-imx.c2
-rw-r--r--drivers/base/driver.c33
-rw-r--r--drivers/clocksource/Kconfig8
-rw-r--r--drivers/clocksource/Makefile2
-rw-r--r--drivers/clocksource/mvebu.c90
-rw-r--r--drivers/clocksource/orion.c76
-rw-r--r--drivers/gpio/gpiolib.c95
-rw-r--r--drivers/i2c/busses/i2c-imx.c10
-rw-r--r--drivers/i2c/i2c.c73
-rw-r--r--drivers/mci/Kconfig7
-rw-r--r--drivers/mci/Makefile20
-rw-r--r--drivers/mci/atmel_mci.c8
-rw-r--r--drivers/mci/imx-esdhc.c251
-rw-r--r--drivers/mci/imx-esdhc.h89
-rw-r--r--drivers/mci/imx.c2
-rw-r--r--drivers/mci/mci-bcm2835.c591
-rw-r--r--drivers/mci/mci-bcm2835.h73
-rw-r--r--drivers/mci/mci-core.c465
-rw-r--r--drivers/mci/mxs.c14
-rw-r--r--drivers/mci/s3c.c8
-rw-r--r--drivers/mci/sdhci.h89
-rw-r--r--drivers/mci/twl6030.c29
-rw-r--r--drivers/misc/jtag.c40
-rw-r--r--drivers/mtd/core.c6
-rw-r--r--drivers/mtd/devices/m25p80.c9
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c11
-rw-r--r--drivers/mtd/nor/cfi_flash.c81
-rw-r--r--drivers/mtd/nor/cfi_flash.h6
-rw-r--r--drivers/net/Kconfig7
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/ar231x.c437
-rw-r--r--drivers/net/ar231x.h219
-rw-r--r--drivers/net/cs8900.c3
-rw-r--r--drivers/net/fec_imx.c4
-rw-r--r--drivers/of/Kconfig5
-rw-r--r--drivers/of/Makefile1
-rw-r--r--drivers/of/base.c147
-rw-r--r--drivers/of/mem_generic.c15
-rw-r--r--drivers/pinctrl/Kconfig6
-rw-r--r--drivers/pinctrl/Makefile1
-rw-r--r--drivers/pinctrl/imx-iomux-v3.c2
-rw-r--r--drivers/pinctrl/pinctrl-tegra20.c346
-rw-r--r--drivers/spi/spi.c15
-rw-r--r--drivers/video/fb.c3
-rw-r--r--drivers/video/s3c24xx.c8
-rw-r--r--drivers/video/stm.c3
-rw-r--r--include/block.h10
-rw-r--r--include/driver.h15
-rw-r--r--include/environment.h2
-rw-r--r--include/fb.h1
-rw-r--r--include/filetype.h2
-rw-r--r--include/globalvar.h4
-rw-r--r--include/i2c/i2c.h4
-rw-r--r--include/image.h2
-rw-r--r--include/linux/phy.h1
-rw-r--r--include/mci.h36
-rw-r--r--include/mci/twl6030.h10
-rw-r--r--include/mfd/mc13xxx.h2
-rw-r--r--include/net.h7
-rw-r--r--include/notifier.h2
-rw-r--r--include/of.h21
-rw-r--r--include/param.h15
-rw-r--r--include/partition.h3
-rw-r--r--include/spi/spi.h1
-rw-r--r--lib/parameter.c104
-rw-r--r--net/eth.c68
-rw-r--r--scripts/.gitignore2
-rw-r--r--scripts/Makefile2
-rw-r--r--scripts/Makefile.lib46
-rw-r--r--scripts/basic/fixdep.c206
-rw-r--r--scripts/imx/.gitignore2
-rw-r--r--scripts/imx/Makefile10
-rw-r--r--scripts/imx/README89
-rw-r--r--scripts/imx/imx-image.c744
-rw-r--r--scripts/imx/imx-usb-loader.c1427
-rw-r--r--scripts/kwbimage.c1496
-rw-r--r--scripts/kwboot.c730
244 files changed, 16200 insertions, 1469 deletions
diff --git a/.gitignore b/.gitignore
index d1971967f6..a08c6c1ec4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,6 +39,8 @@ barebox.ubl
barebox.zynq
barebox.uimage
barebox.map
+barebox.kwb
+barebox.kwbuart
barebox-flash-image
System.map
Module.symvers
diff --git a/Documentation/devicetree/bindings/README b/Documentation/devicetree/bindings/README
new file mode 100644
index 0000000000..b818ee8243
--- /dev/null
+++ b/Documentation/devicetree/bindings/README
@@ -0,0 +1,6 @@
+
+barebox uses the same devicetree bindings as the kernel. For
+the bindings derived from the kernel look in the kernel sources
+for reference.
+
+barebox specific bindings are documented here.
diff --git a/Documentation/devicetree/bindings/misc/fsl,imx-iim.txt b/Documentation/devicetree/bindings/misc/fsl,imx-iim.txt
new file mode 100644
index 0000000000..ed3efcc313
--- /dev/null
+++ b/Documentation/devicetree/bindings/misc/fsl,imx-iim.txt
@@ -0,0 +1,20 @@
+Freescale i.MX IIM (Ic Identification Module)
+
+Required properties:
+
+- compatible: fsl,imx-iim
+- reg: physical register base and size
+
+Optional properties:
+
+- barebox,provide-mac-address: Provide MAC addresses for ethernet devices. This
+ can be multiple entries in the form <&phandle bankno fuseofs> to specify a MAC
+ address to a ethernet device.
+
+Example:
+
+iim: iim@83f98000 {
+ compatible = "fsl,imx51-iim", "fsl,imx-iim";
+ reg = <0x83f98000 0x4000>;
+ barebox,provide-mac-address = <&fec 1 9>;
+};
diff --git a/Makefile b/Makefile
index f91999381b..54d2475b5a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,5 @@
VERSION = 2013
-PATCHLEVEL = 05
+PATCHLEVEL = 06
SUBLEVEL = 0
EXTRAVERSION =
NAME = Amissive Actinocutious Kiwi
@@ -970,7 +970,7 @@ CLEAN_FILES += barebox System.map include/generated/barebox_default_env.h \
.tmp_kallsyms* common/barebox_default_env* barebox.ldr \
scripts/bareboxenv-target barebox-flash-image \
Doxyfile.version barebox.srec barebox.s5p barebox.ubl \
- barebox.uimage barebox.spi
+ barebox.uimage barebox.spi barebox.kwb barebox.kwbuart
# Directories & files removed with 'make mrproper'
MRPROPER_DIRS += include/config include2 usr/include
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 0a4f821814..cfb82b0515 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -79,6 +79,12 @@ config ARCH_IMX
select WATCHDOG_IMX_RESET_SOURCE
select HAS_DEBUG_LL
+config ARCH_MVEBU
+ bool "Marvell EBU platforms"
+ select COMMON_CLK
+ select CLKDEV_LOOKUP
+ select HAS_DEBUG_LL
+
config ARCH_MXS
bool "Freescale i.MX23/28 (mxs) based"
select GENERIC_GPIO
@@ -161,6 +167,7 @@ source arch/arm/mach-ep93xx/Kconfig
source arch/arm/mach-highbank/Kconfig
source arch/arm/mach-imx/Kconfig
source arch/arm/mach-mxs/Kconfig
+source arch/arm/mach-mvebu/Kconfig
source arch/arm/mach-netx/Kconfig
source arch/arm/mach-nomadik/Kconfig
source arch/arm/mach-omap/Kconfig
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 8f0d23e92c..32bdd65a21 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -58,6 +58,7 @@ machine-$(CONFIG_ARCH_EP93XX) := ep93xx
machine-$(CONFIG_ARCH_HIGHBANK) := highbank
machine-$(CONFIG_ARCH_IMX) := imx
machine-$(CONFIG_ARCH_MXS) := mxs
+machine-$(CONFIG_ARCH_MVEBU) := mvebu
machine-$(CONFIG_ARCH_NOMADIK) := nomadik
machine-$(CONFIG_ARCH_NETX) := netx
machine-$(CONFIG_ARCH_OMAP) := omap
@@ -70,101 +71,108 @@ machine-$(CONFIG_ARCH_ZYNQ) := zynq
# Board directory name. This list is sorted alphanumerically
# by CONFIG_* macro name.
-board-$(CONFIG_MACH_A9M2410) := a9m2410
-board-$(CONFIG_MACH_A9M2440) := a9m2440
-board-$(CONFIG_MACH_ANIMEO_IP) := animeo_ip
-board-$(CONFIG_MACH_AT91RM9200EK) := at91rm9200ek
-board-$(CONFIG_MACH_AT91SAM9260EK) := at91sam9260ek
-board-$(CONFIG_MACH_AT91SAM9261EK) := at91sam9261ek
-board-$(CONFIG_MACH_AT91SAM9263EK) := at91sam9263ek
-board-$(CONFIG_MACH_AT91SAM9G10EK) := at91sam9261ek
-board-$(CONFIG_MACH_AT91SAM9G20EK) := at91sam9260ek
-board-$(CONFIG_MACH_AT91SAM9N12EK) := at91sam9n12ek
-board-$(CONFIG_MACH_AT91SAM9X5EK) := at91sam9x5ek
-board-$(CONFIG_MACH_AT91SAM9M10IHD) := at91sam9m10ihd
-board-$(CONFIG_MACH_AT91SAM9M10G45EK) := at91sam9m10g45ek
-board-$(CONFIG_MACH_SAMA5D3XEK) := sama5d3xek
-board-$(CONFIG_MACH_CLEP7212) := clep7212
-board-$(CONFIG_MACH_DSS11) := dss11
-board-$(CONFIG_MACH_EDB9301) := edb93xx
-board-$(CONFIG_MACH_EDB9302) := edb93xx
-board-$(CONFIG_MACH_EDB9302A) := edb93xx
-board-$(CONFIG_MACH_EDB9307) := edb93xx
-board-$(CONFIG_MACH_EDB9307A) := edb93xx
-board-$(CONFIG_MACH_EDB93012) := edb93xx
-board-$(CONFIG_MACH_EDB9315) := edb93xx
-board-$(CONFIG_MACH_EDB9315A) := edb93xx
-board-$(CONFIG_MACH_EUKREA_CPUIMX25) := eukrea_cpuimx25
-board-$(CONFIG_MACH_EUKREA_CPUIMX27) := eukrea_cpuimx27
-board-$(CONFIG_MACH_EUKREA_CPUIMX35) := eukrea_cpuimx35
-board-$(CONFIG_MACH_EUKREA_CPUIMX51SD) := eukrea_cpuimx51
-board-$(CONFIG_MACH_FREESCALE_MX25_3STACK) := freescale-mx25-3-stack
-board-$(CONFIG_MACH_FREESCALE_MX35_3STACK) := freescale-mx35-3-stack
-board-$(CONFIG_MACH_GE863) := telit-evk-pro3
-board-$(CONFIG_MACH_HIGHBANK) := highbank
-board-$(CONFIG_MACH_IMX21ADS) := imx21ads
-board-$(CONFIG_MACH_IMX27ADS) := imx27ads
-board-$(CONFIG_MACH_IMX233_OLINUXINO) := imx233-olinuxino
-board-$(CONFIG_MACH_MIOA701) := mioa701
-board-$(CONFIG_MACH_MMCCPU) := mmccpu
-board-$(CONFIG_MACH_NOMADIK_8815NHK) := nhk8815
-board-$(CONFIG_MACH_NXDB500) := netx
-board-$(CONFIG_MACH_OMAP343xSDP) := omap343xdsp
-board-$(CONFIG_MACH_BEAGLE) := beagle
-board-$(CONFIG_MACH_BEAGLEBONE) := beaglebone
-board-$(CONFIG_MACH_OMAP3EVM) := omap3evm
-board-$(CONFIG_MACH_PANDA) := panda
-board-$(CONFIG_MACH_ARCHOSG9) := archosg9
-board-$(CONFIG_MACH_PCM049) := pcm049
-board-$(CONFIG_MACH_PCA100) := phycard-i.MX27
-board-$(CONFIG_MACH_PCAAL1) := phycard-a-l1
-board-$(CONFIG_MACH_PCAAXL2) := phycard-a-xl2
-board-$(CONFIG_MACH_PCM027) := pcm027
-board-$(CONFIG_MACH_PCM037) := pcm037
-board-$(CONFIG_MACH_PCM038) := pcm038
-board-$(CONFIG_MACH_PCM043) := pcm043
-board-$(CONFIG_MACH_PCM051) := pcm051
-board-$(CONFIG_MACH_PM9261) := pm9261
-board-$(CONFIG_MACH_PM9263) := pm9263
-board-$(CONFIG_MACH_PM9G45) := pm9g45
-board-$(CONFIG_MACH_RPI) := raspberry-pi
-board-$(CONFIG_MACH_SCB9328) := scb9328
-board-$(CONFIG_MACH_NESO) := guf-neso
-board-$(CONFIG_MACH_MX23EVK) := freescale-mx23-evk
-board-$(CONFIG_MACH_CHUMBY) := chumby_falconwing
-board-$(CONFIG_MACH_TX28) := karo-tx28
-board-$(CONFIG_MACH_MX28EVK) := freescale-mx28-evk
-board-$(CONFIG_MACH_CFA10036) := crystalfontz-cfa10036
-board-$(CONFIG_MACH_FREESCALE_MX51_PDK) := freescale-mx51-pdk
-board-$(CONFIG_MACH_FREESCALE_MX53_LOCO) := freescale-mx53-loco
-board-$(CONFIG_MACH_FREESCALE_MX53_SMD) := freescale-mx53-smd
-board-$(CONFIG_MACH_GUF_CUPID) := guf-cupid
-board-$(CONFIG_MACH_MINI2440) := friendlyarm-mini2440
-board-$(CONFIG_MACH_MINI6410) := friendlyarm-mini6410
-board-$(CONFIG_MACH_TINY6410) := friendlyarm-tiny6410
-board-$(CONFIG_MACH_QIL_A9260) := qil-a9260
-board-$(CONFIG_MACH_TNY_A9260) := tny-a926x
-board-$(CONFIG_MACH_TNY_A9263) := tny-a926x
-board-$(CONFIG_MACH_TNY_A9G20) := tny-a926x
-board-$(CONFIG_MACH_USB_A9260) := usb-a926x
-board-$(CONFIG_MACH_USB_A9263) := usb-a926x
-board-$(CONFIG_MACH_USB_A9G20) := usb-a926x
-board-$(CONFIG_MACH_VERSATILEPB) := versatile
-board-$(CONFIG_MACH_VEXPRESS) := vexpress
-board-$(CONFIG_MACH_TX25) := karo-tx25
-board-$(CONFIG_MACH_TQMA53) := tqma53
-board-$(CONFIG_MACH_TX51) := karo-tx51
-board-$(CONFIG_MACH_MX6Q_ARM2) := freescale-mx6-arm2
-board-$(CONFIG_MACH_TOSHIBA_AC100) := toshiba-ac100
-board-$(CONFIG_MACH_CCMX51) := ccxmx51
-board-$(CONFIG_MACH_TINY210) := friendlyarm-tiny210
-board-$(CONFIG_MACH_SABRELITE) := freescale-mx6-sabrelite
-board-$(CONFIG_MACH_TX53) := karo-tx53
-board-$(CONFIG_MACH_GUF_VINCELL) := guf-vincell
-board-$(CONFIG_MACH_EFIKA_MX_SMARTBOOK) := efika-mx-smartbook
-board-$(CONFIG_MACH_SABRESD) := freescale-mx6-sabresd
-board-$(CONFIG_MACH_REALQ7) := dmo-mx6-realq7
-board-$(CONFIG_MACH_ZEDBOARD) := avnet-zedboard
+
+board-$(CONFIG_MACH_A9M2410) += a9m2410
+board-$(CONFIG_MACH_A9M2440) += a9m2440
+board-$(CONFIG_MACH_ANIMEO_IP) += animeo_ip
+board-$(CONFIG_MACH_ARCHOSG9) += archosg9
+board-$(CONFIG_MACH_AT91RM9200EK) += at91rm9200ek
+board-$(CONFIG_MACH_AT91SAM9260EK) += at91sam9260ek
+board-$(CONFIG_MACH_AT91SAM9261EK) += at91sam9261ek
+board-$(CONFIG_MACH_AT91SAM9263EK) += at91sam9263ek
+board-$(CONFIG_MACH_AT91SAM9G10EK) += at91sam9261ek
+board-$(CONFIG_MACH_AT91SAM9G20EK) += at91sam9260ek
+board-$(CONFIG_MACH_AT91SAM9M10G45EK) += at91sam9m10g45ek
+board-$(CONFIG_MACH_AT91SAM9M10IHD) += at91sam9m10ihd
+board-$(CONFIG_MACH_AT91SAM9N12EK) += at91sam9n12ek
+board-$(CONFIG_MACH_AT91SAM9X5EK) += at91sam9x5ek
+board-$(CONFIG_MACH_BEAGLE) += beagle
+board-$(CONFIG_MACH_BEAGLEBONE) += beaglebone
+board-$(CONFIG_MACH_CCMX51) += ccxmx51
+board-$(CONFIG_MACH_CFA10036) += crystalfontz-cfa10036
+board-$(CONFIG_MACH_CHUMBY) += chumby_falconwing
+board-$(CONFIG_MACH_CLEP7212) += clep7212
+board-$(CONFIG_MACH_DSS11) += dss11
+board-$(CONFIG_MACH_EDB93012) += edb93xx
+board-$(CONFIG_MACH_EDB9301) += edb93xx
+board-$(CONFIG_MACH_EDB9302A) += edb93xx
+board-$(CONFIG_MACH_EDB9302) += edb93xx
+board-$(CONFIG_MACH_EDB9307A) += edb93xx
+board-$(CONFIG_MACH_EDB9307) += edb93xx
+board-$(CONFIG_MACH_EDB9315A) += edb93xx
+board-$(CONFIG_MACH_EDB9315) += edb93xx
+board-$(CONFIG_MACH_EFIKA_MX_SMARTBOOK) += efika-mx-smartbook
+board-$(CONFIG_MACH_EUKREA_CPUIMX25) += eukrea_cpuimx25
+board-$(CONFIG_MACH_EUKREA_CPUIMX27) += eukrea_cpuimx27
+board-$(CONFIG_MACH_EUKREA_CPUIMX35) += eukrea_cpuimx35
+board-$(CONFIG_MACH_EUKREA_CPUIMX51SD) += eukrea_cpuimx51
+board-$(CONFIG_MACH_FREESCALE_MX25_3STACK) += freescale-mx25-3-stack
+board-$(CONFIG_MACH_FREESCALE_MX35_3STACK) += freescale-mx35-3-stack
+board-$(CONFIG_MACH_FREESCALE_MX51_PDK) += freescale-mx51-pdk
+board-$(CONFIG_MACH_FREESCALE_MX53_LOCO) += freescale-mx53-loco
+board-$(CONFIG_MACH_FREESCALE_MX53_SMD) += freescale-mx53-smd
+board-$(CONFIG_MACH_GE863) += telit-evk-pro3
+board-$(CONFIG_MACH_GLOBALSCALE_GURUPLUG) += globalscale-guruplug
+board-$(CONFIG_MACH_GLOBALSCALE_MIRABOX) += globalscale-mirabox
+board-$(CONFIG_MACH_GUF_CUPID) += guf-cupid
+board-$(CONFIG_MACH_GUF_VINCELL) += guf-vincell
+board-$(CONFIG_MACH_HIGHBANK) += highbank
+board-$(CONFIG_MACH_IMX21ADS) += imx21ads
+board-$(CONFIG_MACH_IMX233_OLINUXINO) += imx233-olinuxino
+board-$(CONFIG_MACH_IMX27ADS) += imx27ads
+board-$(CONFIG_MACH_MARVELL_ARMADA_XP_GP) += marvell-armada-xp-gp
+board-$(CONFIG_MACH_MINI2440) += friendlyarm-mini2440
+board-$(CONFIG_MACH_MINI6410) += friendlyarm-mini6410
+board-$(CONFIG_MACH_MIOA701) += mioa701
+board-$(CONFIG_MACH_MMCCPU) += mmccpu
+board-$(CONFIG_MACH_MX23EVK) += freescale-mx23-evk
+board-$(CONFIG_MACH_MX28EVK) += freescale-mx28-evk
+board-$(CONFIG_MACH_MX6Q_ARM2) += freescale-mx6-arm2
+board-$(CONFIG_MACH_NESO) += guf-neso
+board-$(CONFIG_MACH_NOMADIK_8815NHK) += nhk8815
+board-$(CONFIG_MACH_NXDB500) += netx
+board-$(CONFIG_MACH_OMAP343xSDP) += omap343xdsp
+board-$(CONFIG_MACH_OMAP3EVM) += omap3evm
+board-$(CONFIG_MACH_PANDA) += panda
+board-$(CONFIG_MACH_PCA100) += phycard-i.MX27
+board-$(CONFIG_MACH_PCAAL1) += phycard-a-l1
+board-$(CONFIG_MACH_PCAAXL2) += phycard-a-xl2
+board-$(CONFIG_MACH_PCM027) += pcm027
+board-$(CONFIG_MACH_PCM037) += pcm037
+board-$(CONFIG_MACH_PCM038) += pcm038
+board-$(CONFIG_MACH_PCM043) += pcm043
+board-$(CONFIG_MACH_PCM049) += pcm049
+board-$(CONFIG_MACH_PCM051) += pcm051
+board-$(CONFIG_MACH_PLATHOME_OPENBLOCKS_AX3) += plathome-openblocks-ax3
+board-$(CONFIG_MACH_PM9261) += pm9261
+board-$(CONFIG_MACH_PM9263) += pm9263
+board-$(CONFIG_MACH_PM9G45) += pm9g45
+board-$(CONFIG_MACH_QIL_A9260) += qil-a926x
+board-$(CONFIG_MACH_QIL_A9G20) += qil-a926x
+board-$(CONFIG_MACH_REALQ7) += dmo-mx6-realq7
+board-$(CONFIG_MACH_RPI) += raspberry-pi
+board-$(CONFIG_MACH_SABRELITE) += freescale-mx6-sabrelite
+board-$(CONFIG_MACH_SABRESD) += freescale-mx6-sabresd
+board-$(CONFIG_MACH_SAMA5D3XEK) += sama5d3xek
+board-$(CONFIG_MACH_SCB9328) += scb9328
+board-$(CONFIG_MACH_SOLIDRUN_CUBOX) += solidrun-cubox
+board-$(CONFIG_MACH_TINY210) += friendlyarm-tiny210
+board-$(CONFIG_MACH_TINY6410) += friendlyarm-tiny6410
+board-$(CONFIG_MACH_TNY_A9260) += tny-a926x
+board-$(CONFIG_MACH_TNY_A9263) += tny-a926x
+board-$(CONFIG_MACH_TNY_A9G20) += tny-a926x
+board-$(CONFIG_MACH_TOSHIBA_AC100) += toshiba-ac100
+board-$(CONFIG_MACH_TQMA53) += tqma53
+board-$(CONFIG_MACH_TX25) += karo-tx25
+board-$(CONFIG_MACH_TX28) += karo-tx28
+board-$(CONFIG_MACH_TX51) += karo-tx51
+board-$(CONFIG_MACH_TX53) += karo-tx53
+board-$(CONFIG_MACH_USB_A9260) += usb-a926x
+board-$(CONFIG_MACH_USB_A9263) += usb-a926x
+board-$(CONFIG_MACH_USB_A9G20) += usb-a926x
+board-$(CONFIG_MACH_VERSATILEPB) += versatile
+board-$(CONFIG_MACH_VEXPRESS) += vexpress
+board-$(CONFIG_MACH_ZEDBOARD) += avnet-zedboard
machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
@@ -256,6 +264,35 @@ ifeq ($(machine-y),zynq)
KBUILD_IMAGE := barebox.zynq
endif
+CFG_barebox.imx := $(src)/arch/arm/boards/$(board-y)/flash-header.imxcfg
+barebox.imx: $(KBUILD_BINARY) FORCE
+ $(call if_changed,imx_image)
+
+ifeq ($(CONFIG_ARCH_IMX_INTERNAL_BOOT_USE_IMXIMAGE),y)
+KBUILD_IMAGE := barebox.imx
+endif
+
+KWBIMAGE_OPTS = \
+ -c -i $(srctree)/$(BOARD)/kwbimage.cfg -d $(TEXT_BASE) -e $(TEXT_BASE)
+
+quiet_cmd_kwbimage = KWB $@
+ cmd_kwbimage = scripts/kwbimage -p $< $(KWBIMAGE_OPTS) -o $@ || \
+ echo "WARNING: Couldn't create KWB image due to previous errors."
+
+quiet_cmd_kwbimage_uart = KWBUART $@
+ cmd_kwbimage_uart = scripts/kwbimage -m uart -p $< $(KWBIMAGE_OPTS) -o $@ || \
+ echo "WARNING Couldn't create KWB image due to previous errors."
+
+barebox.kwb: $(KBUILD_BINARY) FORCE
+ $(call if_changed,kwbimage)
+
+barebox.kwbuart: $(KBUILD_BINARY) FORCE
+ $(call if_changed,kwbimage_uart)
+
+ifeq ($(CONFIG_ARCH_MVEBU),y)
+KBUILD_IMAGE := barebox.kwb barebox.kwbuart
+endif
+
pbl := arch/arm/pbl
$(pbl)/zbarebox.S $(pbl)/zbarebox.bin $(pbl)/zbarebox: barebox.bin FORCE
$(Q)$(MAKE) $(build)=$(pbl) $@
@@ -268,11 +305,6 @@ dts := arch/arm/dts
%.dtb: scripts
$(Q)$(MAKE) $(build)=$(dts) $(dts)/$@
-dtbs: scripts
- $(Q)$(MAKE) $(build)=$(dts) dtbs
-
-KBUILD_DTBS := dtbs
-
KBUILD_IMAGE ?= $(KBUILD_BINARY)
archprepare: maketools
@@ -300,4 +332,6 @@ common-$(CONFIG_BUILTIN_DTB) += arch/arm/dts/
lds-y := arch/arm/lib/barebox.lds
+common- += $(patsubst %,arch/arm/boards/%/,$(board-))
+
CLEAN_FILES += include/generated/mach-types.h arch/arm/lib/barebox.lds barebox-flash-image
diff --git a/arch/arm/boards/crystalfontz-cfa10036/hwdetect.c b/arch/arm/boards/crystalfontz-cfa10036/hwdetect.c
index 5eb3ca4cf7..21199d6433 100644
--- a/arch/arm/boards/crystalfontz-cfa10036/hwdetect.c
+++ b/arch/arm/boards/crystalfontz-cfa10036/hwdetect.c
@@ -29,6 +29,10 @@ enum board_type {
BOARD_ID_CFA10036 = 0,
BOARD_ID_CFA10037 = 1,
BOARD_ID_CFA10049 = 2,
+ BOARD_ID_CFA10055 = 3,
+ BOARD_ID_CFA10056 = 4,
+ BOARD_ID_CFA10057 = 5,
+ BOARD_ID_CFA10058 = 6,
};
struct cfa_eeprom_info {
@@ -83,6 +87,18 @@ void cfa10036_detect_hw(void)
case BOARD_ID_CFA10049:
board_name = "cfa10049";
break;
+ case BOARD_ID_CFA10055:
+ board_name = "cfa10055";
+ break;
+ case BOARD_ID_CFA10056:
+ board_name = "cfa10056";
+ break;
+ case BOARD_ID_CFA10057:
+ board_name = "cfa10057";
+ break;
+ case BOARD_ID_CFA10058:
+ board_name = "cfa10058";
+ break;
default:
pr_err("Board ID not supported\n");
return;
diff --git a/arch/arm/boards/freescale-mx51-pdk/Makefile b/arch/arm/boards/freescale-mx51-pdk/Makefile
index d44f697718..f1baae24ff 100644
--- a/arch/arm/boards/freescale-mx51-pdk/Makefile
+++ b/arch/arm/boards/freescale-mx51-pdk/Makefile
@@ -1,3 +1,3 @@
-obj-y += board.o
-lwl-y += flash_header.o
+obj-y += board.o flash-header.o
+extra-y += flash-header.S flash-header.dcd
lwl-y += lowlevel.o
diff --git a/arch/arm/boards/freescale-mx51-pdk/board.c b/arch/arm/boards/freescale-mx51-pdk/board.c
index db340564f9..6807796ab9 100644
--- a/arch/arm/boards/freescale-mx51-pdk/board.c
+++ b/arch/arm/boards/freescale-mx51-pdk/board.c
@@ -39,80 +39,8 @@
#include <mach/iomux-mx51.h>
#include <mach/devices-imx51.h>
#include <mach/revision.h>
-#include <mach/iim.h>
#include <mach/imx-flash-header.h>
-static struct fec_platform_data fec_info = {
- .xcv_type = PHY_INTERFACE_MODE_MII,
-};
-
-static iomux_v3_cfg_t f3s_pads[] = {
- /* UART1 */
- MX51_PAD_UART1_RXD__UART1_RXD,
- MX51_PAD_UART1_TXD__UART1_TXD,
- MX51_PAD_UART1_RTS__UART1_RTS,
- MX51_PAD_UART1_CTS__UART1_CTS,
- /* FEC */
- MX51_PAD_EIM_EB2__FEC_MDIO,
- MX51_PAD_EIM_EB3__FEC_RDATA1,
- MX51_PAD_EIM_CS2__FEC_RDATA2,
- MX51_PAD_EIM_CS3__FEC_RDATA3,
- MX51_PAD_EIM_CS4__FEC_RX_ER,
- MX51_PAD_EIM_CS5__FEC_CRS,
- MX51_PAD_NANDF_RB2__FEC_COL,
- MX51_PAD_NANDF_RB3__FEC_RX_CLK,
- MX51_PAD_NANDF_CS2__FEC_TX_ER,
- MX51_PAD_NANDF_CS3__FEC_MDC,
- MX51_PAD_NANDF_CS4__FEC_TDATA1,
- MX51_PAD_NANDF_CS5__FEC_TDATA2,
- MX51_PAD_NANDF_CS6__FEC_TDATA3,
- MX51_PAD_NANDF_CS7__FEC_TX_EN,
- MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK,
- MX51_PAD_NANDF_D11__FEC_RX_DV,
- MX51_PAD_NANDF_D9__FEC_RDATA0,
- MX51_PAD_NANDF_D8__FEC_TDATA0,
- MX51_PAD_CSPI1_SS0__ECSPI1_SS0,
- MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI,
- MX51_PAD_CSPI1_MISO__ECSPI1_MISO,
- MX51_PAD_CSPI1_RDY__ECSPI1_RDY,
- MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK,
- MX51_PAD_EIM_A20__GPIO2_14, /* LAN8700 reset pin */
- IOMUX_PAD(0x60C, 0x21C, 3, 0x0, 0, 0x85), /* FIXME: needed? */
- /* SD 1 */
- MX51_PAD_SD1_CMD__SD1_CMD,
- MX51_PAD_SD1_CLK__SD1_CLK,
- MX51_PAD_SD1_DATA0__SD1_DATA0,
- MX51_PAD_SD1_DATA1__SD1_DATA1,
- MX51_PAD_SD1_DATA2__SD1_DATA2,
- MX51_PAD_SD1_DATA3__SD1_DATA3,
- /* SD 2 */
- MX51_PAD_SD2_CMD__SD2_CMD,
- MX51_PAD_SD2_CLK__SD2_CLK,
- MX51_PAD_SD2_DATA0__SD2_DATA0,
- MX51_PAD_SD2_DATA1__SD2_DATA1,
- MX51_PAD_SD2_DATA2__SD2_DATA2,
- MX51_PAD_SD2_DATA3__SD2_DATA3,
- /* CD/WP gpio */
- MX51_PAD_GPIO1_6__GPIO1_6,
- MX51_PAD_GPIO1_5__GPIO1_5,
-};
-
-#define BABBAGE_ECSPI1_CS0 (3 * 32 + 24)
-static int spi_0_cs[] = {BABBAGE_ECSPI1_CS0};
-
-static struct spi_imx_master spi_0_data = {
- .chipselect = spi_0_cs,
- .num_chipselect = ARRAY_SIZE(spi_0_cs),
-};
-
-static const struct spi_board_info mx51_babbage_spi_board_info[] = {
- {
- .name = "mc13xxx-spi",
- .bus_num = 0,
- .chip_select = 0,
- },
-};
-
#define MX51_CCM_CACRR 0x10
static void babbage_power_init(void)
@@ -229,32 +157,22 @@ static void babbage_power_init(void)
mdelay(50);
}
-#define DCD_NAME static struct imx_dcd_entry dcd_entry
-
-#include "dcd-data.h"
+extern char flash_header_start[], flash_header_end[];
static int f3s_devices_init(void)
{
- spi_register_board_info(mx51_babbage_spi_board_info,
- ARRAY_SIZE(mx51_babbage_spi_board_info));
- imx51_add_spi0(&spi_0_data);
-
babbage_power_init();
console_flush();
imx51_init_lowlevel(800);
clock_notifier_call_chain();
- imx51_iim_register_fec_ethaddr();
- imx51_add_fec(&fec_info);
- imx51_add_mmc0(NULL);
- imx51_add_mmc1(NULL);
-
armlinux_set_bootparams((void *)0x90000100);
armlinux_set_architecture(MACH_TYPE_MX51_BABBAGE);
- imx51_bbu_internal_mmc_register_handler("mmc", "/dev/disk0",
- BBU_HANDLER_FLAG_DEFAULT, dcd_entry, sizeof(dcd_entry), 0);
+ imx51_bbu_internal_mmc_register_handler("mmc", "/dev/mmc0",
+ BBU_HANDLER_FLAG_DEFAULT, (void *)flash_header_start,
+ flash_header_end - flash_header_start, 0);
return 0;
}
@@ -263,21 +181,9 @@ device_initcall(f3s_devices_init);
static int f3s_part_init(void)
{
- devfs_add_partition("disk0", 0x00000, 0x40000, DEVFS_PARTITION_FIXED, "self0");
- devfs_add_partition("disk0", 0x40000, 0x20000, DEVFS_PARTITION_FIXED, "env0");
+ devfs_add_partition("mmc0", 0x00000, 0x40000, DEVFS_PARTITION_FIXED, "self0");
+ devfs_add_partition("mmc0", 0x40000, 0x20000, DEVFS_PARTITION_FIXED, "env0");
return 0;
}
late_initcall(f3s_part_init);
-
-static int f3s_console_init(void)
-{
- mxc_iomux_v3_setup_multiple_pads(f3s_pads, ARRAY_SIZE(f3s_pads));
-
- imx51_add_uart0();
-
- return 0;
-}
-
-console_initcall(f3s_console_init);
-
diff --git a/arch/arm/boards/freescale-mx51-pdk/dcd-data.h b/arch/arm/boards/freescale-mx51-pdk/dcd-data.h
deleted file mode 100644
index 4dd6c0d26c..0000000000
--- a/arch/arm/boards/freescale-mx51-pdk/dcd-data.h
+++ /dev/null
@@ -1,60 +0,0 @@
-
-DCD_NAME[] = {
- { .ptr_type = 4, .addr = 0x73fa88a0, .val = 0x00000200, },
- { .ptr_type = 4, .addr = 0x73fa850c, .val = 0x000020c5, },
- { .ptr_type = 4, .addr = 0x73fa8510, .val = 0x000020c5, },
- { .ptr_type = 4, .addr = 0x73fa883c, .val = 0x00000002, },
- { .ptr_type = 4, .addr = 0x73fa8848, .val = 0x00000002, },
- { .ptr_type = 4, .addr = 0x73fa84b8, .val = 0x000000e7, },
- { .ptr_type = 4, .addr = 0x73fa84bc, .val = 0x00000045, },
- { .ptr_type = 4, .addr = 0x73fa84c0, .val = 0x00000045, },
- { .ptr_type = 4, .addr = 0x73fa84c4, .val = 0x00000045, },
- { .ptr_type = 4, .addr = 0x73fa84c8, .val = 0x00000045, },
- { .ptr_type = 4, .addr = 0x73fa8820, .val = 0x00000000, },
- { .ptr_type = 4, .addr = 0x73fa84a4, .val = 0x00000003, },
- { .ptr_type = 4, .addr = 0x73fa84a8, .val = 0x00000003, },
- { .ptr_type = 4, .addr = 0x73fa84ac, .val = 0x000000e3, },
- { .ptr_type = 4, .addr = 0x73fa84b0, .val = 0x000000e3, },
- { .ptr_type = 4, .addr = 0x73fa84b4, .val = 0x000000e3, },
- { .ptr_type = 4, .addr = 0x73fa84cc, .val = 0x000000e3, },
- { .ptr_type = 4, .addr = 0x73fa84d0, .val = 0x000000e2, },
- { .ptr_type = 4, .addr = 0x73fa882c, .val = 0x00000004, },
- { .ptr_type = 4, .addr = 0x73fa88a4, .val = 0x00000004, },
- { .ptr_type = 4, .addr = 0x73fa88ac, .val = 0x00000004, },
- { .ptr_type = 4, .addr = 0x73fa88b8, .val = 0x00000004, },
- { .ptr_type = 4, .addr = 0x83fd9000, .val = 0x82a20000, },
- { .ptr_type = 4, .addr = 0x83fd9008, .val = 0x82a20000, },
- { .ptr_type = 4, .addr = 0x83fd9010, .val = 0x000ad0d0, },
- { .ptr_type = 4, .addr = 0x83fd9004, .val = 0x3f3584ab, },
- { .ptr_type = 4, .addr = 0x83fd900c, .val = 0x3f3584ab, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x04008008, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801a, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801b, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00448019, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x07328018, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x04008008, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008010, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008010, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x06328018, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x03808019, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00408019, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008000, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0400800c, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801e, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801f, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0000801d, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0732801c, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0400800c, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008014, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008014, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0632801c, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0380801d, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x0040801d, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00008004, },
- { .ptr_type = 4, .addr = 0x83fd9000, .val = 0xb2a20000, },
- { .ptr_type = 4, .addr = 0x83fd9008, .val = 0xb2a20000, },
- { .ptr_type = 4, .addr = 0x83fd9010, .val = 0x000ad6d0, },
- { .ptr_type = 4, .addr = 0x83fd9034, .val = 0x90000000, },
- { .ptr_type = 4, .addr = 0x83fd9014, .val = 0x00000000, },
-};
-
diff --git a/arch/arm/boards/freescale-mx51-pdk/flash-header.imxcfg b/arch/arm/boards/freescale-mx51-pdk/flash-header.imxcfg
new file mode 100644
index 0000000000..bac6816fee
--- /dev/null
+++ b/arch/arm/boards/freescale-mx51-pdk/flash-header.imxcfg
@@ -0,0 +1,59 @@
+loadaddr 0x90000000
+soc imx51
+dcdofs 0x400
+wm 32 0x73fa88a0 0x00000200
+wm 32 0x73fa850c 0x000020c5
+wm 32 0x73fa8510 0x000020c5
+wm 32 0x73fa883c 0x00000002
+wm 32 0x73fa8848 0x00000002
+wm 32 0x73fa84b8 0x000000e7
+wm 32 0x73fa84bc 0x00000045
+wm 32 0x73fa84c0 0x00000045
+wm 32 0x73fa84c4 0x00000045
+wm 32 0x73fa84c8 0x00000045
+wm 32 0x73fa8820 0x00000000
+wm 32 0x73fa84a4 0x00000003
+wm 32 0x73fa84a8 0x00000003
+wm 32 0x73fa84ac 0x000000e3
+wm 32 0x73fa84b0 0x000000e3
+wm 32 0x73fa84b4 0x000000e3
+wm 32 0x73fa84cc 0x000000e3
+wm 32 0x73fa84d0 0x000000e2
+wm 32 0x73fa882c 0x00000004
+wm 32 0x73fa88a4 0x00000004
+wm 32 0x73fa88ac 0x00000004
+wm 32 0x73fa88b8 0x00000004
+wm 32 0x83fd9000 0x82a20000
+wm 32 0x83fd9008 0x82a20000
+wm 32 0x83fd9010 0x000ad0d0
+wm 32 0x83fd9004 0x3f3584ab
+wm 32 0x83fd900c 0x3f3584ab
+wm 32 0x83fd9014 0x04008008
+wm 32 0x83fd9014 0x0000801a
+wm 32 0x83fd9014 0x0000801b
+wm 32 0x83fd9014 0x00448019
+wm 32 0x83fd9014 0x07328018
+wm 32 0x83fd9014 0x04008008
+wm 32 0x83fd9014 0x00008010
+wm 32 0x83fd9014 0x00008010
+wm 32 0x83fd9014 0x06328018
+wm 32 0x83fd9014 0x03808019
+wm 32 0x83fd9014 0x00408019
+wm 32 0x83fd9014 0x00008000
+wm 32 0x83fd9014 0x0400800c
+wm 32 0x83fd9014 0x0000801e
+wm 32 0x83fd9014 0x0000801f
+wm 32 0x83fd9014 0x0000801d
+wm 32 0x83fd9014 0x0732801c
+wm 32 0x83fd9014 0x0400800c
+wm 32 0x83fd9014 0x00008014
+wm 32 0x83fd9014 0x00008014
+wm 32 0x83fd9014 0x0632801c
+wm 32 0x83fd9014 0x0380801d
+wm 32 0x83fd9014 0x0040801d
+wm 32 0x83fd9014 0x00008004
+wm 32 0x83fd9000 0xb2a20000
+wm 32 0x83fd9008 0xb2a20000
+wm 32 0x83fd9010 0x000ad6d0
+wm 32 0x83fd9034 0x90000000
+wm 32 0x83fd9014 0x00000000
diff --git a/arch/arm/boards/freescale-mx51-pdk/flash_header.c b/arch/arm/boards/freescale-mx51-pdk/flash_header.c
deleted file mode 100644
index f3f1e4bfd5..0000000000
--- a/arch/arm/boards/freescale-mx51-pdk/flash_header.c
+++ /dev/null
@@ -1,29 +0,0 @@
-#include <common.h>
-#include <mach/imx-flash-header.h>
-#include <asm/barebox-arm-head.h>
-
-void __naked __flash_header_start go(void)
-{
- barebox_arm_head();
-}
-
-#define DCD_NAME struct imx_dcd_entry __dcd_entry_section dcd_entry
-
-#include "dcd-data.h"
-
-#define APP_DEST 0x90000000
-
-struct imx_flash_header __flash_header_section flash_header = {
- .app_code_jump_vector = APP_DEST + 0x1000,
- .app_code_barker = APP_CODE_BARKER,
- .app_code_csf = 0,
- .dcd_ptr_ptr = APP_DEST + 0x400 + offsetof(struct imx_flash_header, dcd),
- .super_root_key = 0,
- .dcd = APP_DEST + 0x400 + offsetof(struct imx_flash_header, dcd_barker),
- .app_dest = APP_DEST,
- .dcd_barker = DCD_BARKER,
- .dcd_block_len = sizeof (dcd_entry),
-};
-
-unsigned long __image_len_section barebox_len = DCD_BAREBOX_SIZE;
-
diff --git a/arch/arm/boards/freescale-mx6-sabrelite/board.c b/arch/arm/boards/freescale-mx6-sabrelite/board.c
index 2afaae3007..ff27b05b14 100644
--- a/arch/arm/boards/freescale-mx6-sabrelite/board.c
+++ b/arch/arm/boards/freescale-mx6-sabrelite/board.c
@@ -29,6 +29,7 @@
#include <mach/generic.h>
#include <sizes.h>
#include <net.h>
+#include <linux/micrel_phy.h>
#include <mach/imx6.h>
#include <mach/devices-imx6.h>
#include <mach/iomux-mx6.h>
@@ -37,73 +38,8 @@
#include <mach/spi.h>
#include <mach/usb.h>
-#define SABRELITE_SD3_WP IMX_GPIO_NR(7, 1)
-#define SABRELITE_SD3_CD IMX_GPIO_NR(7, 0)
-
-#define SABRELITE_SD4_CD IMX_GPIO_NR(2, 6)
-
-static iomux_v3_cfg_t sabrelite_pads[] = {
- /* UART1 */
- MX6Q_PAD_SD3_DAT6__UART1_RXD,
- MX6Q_PAD_SD3_DAT7__UART1_TXD,
- MX6Q_PAD_EIM_D26__UART2_TXD,
- MX6Q_PAD_EIM_D27__UART2_RXD,
-
- /* SD3 (bottom) */
- MX6Q_PAD_SD3_CMD__USDHC3_CMD,
- MX6Q_PAD_SD3_CLK__USDHC3_CLK,
- MX6Q_PAD_SD3_DAT0__USDHC3_DAT0,
- MX6Q_PAD_SD3_DAT1__USDHC3_DAT1,
- MX6Q_PAD_SD3_DAT2__USDHC3_DAT2,
- MX6Q_PAD_SD3_DAT3__USDHC3_DAT3,
- MX6Q_PAD_SD3_DAT4__GPIO_7_1, /* WP */
- MX6Q_PAD_SD3_DAT5__GPIO_7_0, /* CD */
-
- /* SD4 (top) */
- MX6Q_PAD_SD4_CLK__USDHC4_CLK,
- MX6Q_PAD_SD4_CMD__USDHC4_CMD,
- MX6Q_PAD_SD4_DAT0__USDHC4_DAT0,
- MX6Q_PAD_SD4_DAT1__USDHC4_DAT1,
- MX6Q_PAD_SD4_DAT2__USDHC4_DAT2,
- MX6Q_PAD_SD4_DAT3__USDHC4_DAT3,
- MX6Q_PAD_NANDF_D6__GPIO_2_6, /* CD */
-
- /* ECSPI */
- MX6Q_PAD_EIM_D16__ECSPI1_SCLK,
- MX6Q_PAD_EIM_D17__ECSPI1_MISO,
- MX6Q_PAD_EIM_D18__ECSPI1_MOSI,
- MX6Q_PAD_EIM_D19__GPIO_3_19, /* CS1 */
-
- /* I2C0 */
- MX6Q_PAD_EIM_D21__I2C1_SCL,
- MX6Q_PAD_EIM_D28__I2C1_SDA,
-
- /* I2C1 */
- MX6Q_PAD_KEY_COL3__I2C2_SCL,
- MX6Q_PAD_KEY_ROW3__I2C2_SDA,
-
- /* I2C2 */
- MX6Q_PAD_GPIO_5__I2C3_SCL,
- MX6Q_PAD_GPIO_16__I2C3_SDA,
-
- /* USB */
- MX6Q_PAD_GPIO_17__GPIO_7_12,
- MX6Q_PAD_EIM_D22__GPIO_3_22,
- MX6Q_PAD_EIM_D30__USBOH3_USBH1_OC,
-};
-
-static iomux_v3_cfg_t sabrelite_enet_pads[] = {
+static iomux_v3_cfg_t sabrelite_enet_gpio_pads[] = {
/* Ethernet */
- MX6Q_PAD_ENET_MDC__ENET_MDC,
- MX6Q_PAD_ENET_MDIO__ENET_MDIO,
- MX6Q_PAD_ENET_REF_CLK__GPIO_1_23, // LED mode
- MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK,
- MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC,
- MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0,
- MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1,
- MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2,
- MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3,
- MX6Q_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL,
MX6Q_PAD_EIM_D23__GPIO_3_23, /* RGMII_nRST */
MX6Q_PAD_RGMII_RXC__GPIO_6_30, /* PHYAD */
MX6Q_PAD_RGMII_RD0__GPIO_6_25, /* MODE0 */
@@ -113,16 +49,6 @@ static iomux_v3_cfg_t sabrelite_enet_pads[] = {
MX6Q_PAD_RGMII_RX_CTL__GPIO_6_24,
};
-static iomux_v3_cfg_t sabrelite_enet2_pads[] = {
- MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK,
- MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC,
- MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0,
- MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1,
- MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2,
- MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3,
- MX6Q_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL,
-};
-
static int sabrelite_mem_init(void)
{
arm_add_mem_device("ram0", 0x10000000, SZ_1G);
@@ -131,7 +57,7 @@ static int sabrelite_mem_init(void)
}
mem_initcall(sabrelite_mem_init);
-static void mx6_rgmii_rework(struct phy_device *dev)
+static int ksz9021rn_phy_fixup(struct phy_device *dev)
{
phy_write(dev, 0x09, 0x0f00);
@@ -144,17 +70,14 @@ static void mx6_rgmii_rework(struct phy_device *dev)
phy_write(dev, 0x0b, 0x8104);
phy_write(dev, 0x0c, 0xf0f0);
phy_write(dev, 0x0b, 0x104);
-}
-static struct fec_platform_data fec_info = {
- .xcv_type = PHY_INTERFACE_MODE_RGMII,
- .phy_init = mx6_rgmii_rework,
- .phy_addr = 6,
-};
+ return 0;
+}
static int sabrelite_ksz9021rn_setup(void)
{
- mxc_iomux_v3_setup_multiple_pads(sabrelite_enet_pads, ARRAY_SIZE(sabrelite_enet_pads));
+ mxc_iomux_v3_setup_multiple_pads(sabrelite_enet_gpio_pads,
+ ARRAY_SIZE(sabrelite_enet_gpio_pads));
gpio_direction_output(87, 0); /* GPIO 3-23 */
@@ -175,10 +98,13 @@ static int sabrelite_ksz9021rn_setup(void)
mdelay(10);
gpio_set_value(87, 1);
- mxc_iomux_v3_setup_multiple_pads(sabrelite_enet2_pads, ARRAY_SIZE(sabrelite_enet2_pads));
-
return 0;
}
+/*
+ * Do this before the fec initializes but after our
+ * gpios are available.
+ */
+fs_initcall(sabrelite_ksz9021rn_setup);
static inline int imx6_iim_register_fec_ethaddr(void)
{
@@ -200,35 +126,6 @@ static inline int imx6_iim_register_fec_ethaddr(void)
return 0;
}
-static int sabrelite_spi_cs[] = {IMX_GPIO_NR(3, 19)};
-
-static struct spi_imx_master sabrelite_spi_0_data = {
- .chipselect = sabrelite_spi_cs,
- .num_chipselect = ARRAY_SIZE(sabrelite_spi_cs),
-};
-
-static const struct spi_board_info sabrelite_spi_board_info[] = {
- {
- .name = "m25p80",
- .max_speed_hz = 40000000,
- .bus_num = 0,
- .chip_select = 0,
- }
-};
-
-static struct esdhc_platform_data sabrelite_sd3_data = {
- .cd_gpio = SABRELITE_SD3_CD,
- .cd_type = ESDHC_CD_GPIO,
- .wp_gpio = SABRELITE_SD3_WP,
- .wp_type = ESDHC_WP_GPIO,
-};
-
-static struct esdhc_platform_data sabrelite_sd4_data = {
- .cd_gpio = SABRELITE_SD4_CD,
- .cd_type = ESDHC_CD_GPIO,
- .wp_type = ESDHC_WP_NONE,
-};
-
static void sabrelite_ehci_init(void)
{
imx6_usb_phy2_disable_oc();
@@ -244,19 +141,8 @@ static void sabrelite_ehci_init(void)
static int sabrelite_devices_init(void)
{
- imx6_add_mmc2(&sabrelite_sd3_data);
- imx6_add_mmc3(&sabrelite_sd4_data);
-
- sabrelite_ksz9021rn_setup();
- imx6_iim_register_fec_ethaddr();
- imx6_add_fec(&fec_info);
-
sabrelite_ehci_init();
- spi_register_board_info(sabrelite_spi_board_info,
- ARRAY_SIZE(sabrelite_spi_board_info));
- imx6_add_spi0(&sabrelite_spi_0_data);
-
armlinux_set_bootparams((void *)0x10000100);
armlinux_set_architecture(3769);
@@ -265,17 +151,23 @@ static int sabrelite_devices_init(void)
return 0;
}
-
device_initcall(sabrelite_devices_init);
-static int sabrelite_console_init(void)
+static int sabrelite_coredevices_init(void)
{
- mxc_iomux_v3_setup_multiple_pads(sabrelite_pads, ARRAY_SIZE(sabrelite_pads));
+ phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK,
+ ksz9021rn_phy_fixup);
- imx6_init_lowlevel();
+ imx6_iim_register_fec_ethaddr();
+
+ return 0;
+}
+coredevice_initcall(sabrelite_coredevices_init);
- imx6_add_uart1();
+static int sabrelite_core_init(void)
+{
+ imx6_init_lowlevel();
return 0;
}
-console_initcall(sabrelite_console_init);
+core_initcall(sabrelite_core_init);
diff --git a/arch/arm/boards/freescale-mx6-sabresd/board.c b/arch/arm/boards/freescale-mx6-sabresd/board.c
index e41dc77bf5..033a253a23 100644
--- a/arch/arm/boards/freescale-mx6-sabresd/board.c
+++ b/arch/arm/boards/freescale-mx6-sabresd/board.c
@@ -41,92 +41,6 @@
#define PHY_ID_AR8031 0x004dd074
#define AR_PHY_ID_MASK 0xffffffff
-#define SABRESD_SD2_CD IMX_GPIO_NR(2, 2)
-#define SABRESD_SD2_WP IMX_GPIO_NR(2, 3)
-
-#define SABRESD_SD3_CD IMX_GPIO_NR(2, 0)
-#define SABRESD_SD3_WP IMX_GPIO_NR(2, 1)
-
-static iomux_v3_cfg_t sabresd_pads[] = {
- /* UART1 */
- MX6Q_PAD_CSI0_DAT11__UART1_RXD,
- MX6Q_PAD_CSI0_DAT10__UART1_TXD,
-
- /* Ethernet */
- MX6Q_PAD_ENET_MDC__ENET_MDC,
- MX6Q_PAD_ENET_MDIO__ENET_MDIO,
- MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK,
-
- MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC,
- MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0,
- MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1,
- MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2,
- MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3,
- MX6Q_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL,
-
- MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC,
- MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0,
- MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1,
- MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2,
- MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3,
- MX6Q_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL,
-
- MX6Q_PAD_ENET_CRS_DV__GPIO_1_25, /* AR8031 PHY Reset */
- MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT,
-
- /* SD2 */
- MX6Q_PAD_SD2_CLK__USDHC2_CLK,
- MX6Q_PAD_SD2_CMD__USDHC2_CMD,
- MX6Q_PAD_SD2_DAT0__USDHC2_DAT0,
- MX6Q_PAD_SD2_DAT1__USDHC2_DAT1,
- MX6Q_PAD_SD2_DAT2__USDHC2_DAT2,
- MX6Q_PAD_SD2_DAT3__USDHC2_DAT3,
- MX6Q_PAD_NANDF_D4__USDHC2_DAT4,
- MX6Q_PAD_NANDF_D5__USDHC2_DAT5,
- MX6Q_PAD_NANDF_D6__USDHC2_DAT6,
- MX6Q_PAD_NANDF_D7__USDHC2_DAT7,
- MX6Q_PAD_NANDF_D2__GPIO_2_2, /* CD */
- MX6Q_PAD_NANDF_D3__GPIO_2_3, /* WP */
-
- /* SD3 */
- MX6Q_PAD_SD3_CMD__USDHC3_CMD,
- MX6Q_PAD_SD3_CLK__USDHC3_CLK,
- MX6Q_PAD_SD3_DAT0__USDHC3_DAT0,
- MX6Q_PAD_SD3_DAT1__USDHC3_DAT1,
- MX6Q_PAD_SD3_DAT2__USDHC3_DAT2,
- MX6Q_PAD_SD3_DAT3__USDHC3_DAT3,
- MX6Q_PAD_SD3_DAT4__USDHC3_DAT4,
- MX6Q_PAD_SD3_DAT5__USDHC3_DAT5,
- MX6Q_PAD_SD3_DAT6__USDHC3_DAT6,
- MX6Q_PAD_SD3_DAT7__USDHC3_DAT7,
- MX6Q_PAD_NANDF_D0__GPIO_2_0, /* CD */
- MX6Q_PAD_NANDF_D1__GPIO_2_1, /* WP */
-
- /* SD4 */
- MX6Q_PAD_SD4_CLK__USDHC4_CLK,
- MX6Q_PAD_SD4_CMD__USDHC4_CMD,
- MX6Q_PAD_SD4_DAT0__USDHC4_DAT0,
- MX6Q_PAD_SD4_DAT1__USDHC4_DAT1,
- MX6Q_PAD_SD4_DAT2__USDHC4_DAT2,
- MX6Q_PAD_SD4_DAT3__USDHC4_DAT3,
- MX6Q_PAD_SD4_DAT4__USDHC4_DAT4,
- MX6Q_PAD_SD4_DAT5__USDHC4_DAT5,
- MX6Q_PAD_SD4_DAT6__USDHC4_DAT6,
- MX6Q_PAD_SD4_DAT7__USDHC4_DAT7,
-
- /* I2C0 */
- MX6Q_PAD_CSI0_DAT8__I2C1_SDA,
- MX6Q_PAD_CSI0_DAT9__I2C1_SCL,
-
- /* I2C1 */
- MX6Q_PAD_KEY_COL3__I2C2_SCL,
- MX6Q_PAD_KEY_ROW3__I2C2_SDA,
-
- /* I2C2 */
- MX6Q_PAD_GPIO_3__I2C3_SCL,
- MX6Q_PAD_GPIO_6__I2C3_SDA,
-};
-
static int sabresd_mem_init(void)
{
arm_add_mem_device("ram0", 0x10000000, SZ_1G);
@@ -158,11 +72,6 @@ static int ar8031_phy_fixup(struct phy_device *dev)
return 0;
}
-static struct fec_platform_data fec_info = {
- .xcv_type = PHY_INTERFACE_MODE_RGMII,
- .phy_addr = 1,
-};
-
static void sabresd_phy_reset(void)
{
/* Reset AR8031 PHY */
@@ -191,37 +100,8 @@ static inline int imx6_iim_register_fec_ethaddr(void)
return 0;
}
-static struct esdhc_platform_data sabresd_sd2_data = {
- .cd_gpio = SABRESD_SD2_CD,
- .cd_type = ESDHC_CD_GPIO,
- .wp_gpio = SABRESD_SD2_WP,
- .wp_type = ESDHC_WP_GPIO,
-};
-
-static struct esdhc_platform_data sabresd_sd3_data = {
- .cd_gpio = SABRESD_SD3_CD,
- .cd_type = ESDHC_CD_GPIO,
- .wp_gpio = SABRESD_SD3_WP,
- .wp_type = ESDHC_WP_GPIO,
-};
-
-static struct esdhc_platform_data sabresd_sd4_data = {
- .cd_type = ESDHC_CD_PERMANENT,
- .wp_type = ESDHC_WP_CONTROLLER,
-};
-
static int sabresd_devices_init(void)
{
- imx6_add_mmc3(&sabresd_sd4_data);
- imx6_add_mmc1(&sabresd_sd2_data);
- imx6_add_mmc2(&sabresd_sd3_data);
-
- phy_register_fixup_for_uid(PHY_ID_AR8031, AR_PHY_ID_MASK, ar8031_phy_fixup);
-
- sabresd_phy_reset();
- imx6_iim_register_fec_ethaddr();
- imx6_add_fec(&fec_info);
-
armlinux_set_bootparams((void *)0x10000100);
armlinux_set_architecture(3980);
@@ -231,14 +111,27 @@ static int sabresd_devices_init(void)
}
device_initcall(sabresd_devices_init);
-static int sabresd_console_init(void)
+static int sabresd_coredevices_init(void)
{
- mxc_iomux_v3_setup_multiple_pads(sabresd_pads, ARRAY_SIZE(sabresd_pads));
+ sabresd_phy_reset();
- imx6_init_lowlevel();
+ phy_register_fixup_for_uid(PHY_ID_AR8031, AR_PHY_ID_MASK,
+ ar8031_phy_fixup);
- imx6_add_uart0();
+ imx6_iim_register_fec_ethaddr();
+
+ return 0;
+}
+/*
+ * Do this before the fec initializes but after our
+ * gpios are available.
+ */
+fs_initcall(sabresd_coredevices_init);
+
+static int sabresd_core_init(void)
+{
+ imx6_init_lowlevel();
return 0;
}
-console_initcall(sabresd_console_init);
+core_initcall(sabresd_core_init);
diff --git a/arch/arm/boards/globalscale-guruplug/Makefile b/arch/arm/boards/globalscale-guruplug/Makefile
new file mode 100644
index 0000000000..dcfc2937d3
--- /dev/null
+++ b/arch/arm/boards/globalscale-guruplug/Makefile
@@ -0,0 +1 @@
+obj-y += board.o
diff --git a/arch/arm/boards/globalscale-guruplug/board.c b/arch/arm/boards/globalscale-guruplug/board.c
new file mode 100644
index 0000000000..9c800c5410
--- /dev/null
+++ b/arch/arm/boards/globalscale-guruplug/board.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright
+ * (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * 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.
+ *
+ */
+
+/* empty */
diff --git a/arch/arm/boards/globalscale-guruplug/config.h b/arch/arm/boards/globalscale-guruplug/config.h
new file mode 100644
index 0000000000..ca15136817
--- /dev/null
+++ b/arch/arm/boards/globalscale-guruplug/config.h
@@ -0,0 +1,4 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif /* __CONFIG_H */
diff --git a/arch/arm/boards/globalscale-guruplug/kwbimage.cfg b/arch/arm/boards/globalscale-guruplug/kwbimage.cfg
new file mode 100644
index 0000000000..d0f3bdb01f
--- /dev/null
+++ b/arch/arm/boards/globalscale-guruplug/kwbimage.cfg
@@ -0,0 +1,27 @@
+VERSION 0
+BOOT_FROM nand
+NAND_ECCMODE default
+NAND_PAGESZ 00000800
+DATA ffd100e0 1b1b9b9b
+DATA ffd01400 43000c30
+DATA ffd01404 37543000
+DATA ffd01408 22125451
+DATA ffd0140c 00000a33
+DATA ffd01410 000000cc
+DATA ffd01414 00000000
+DATA ffd01418 00000000
+DATA ffd0141c 00000c52
+DATA ffd01420 00000040
+DATA ffd01424 0000f17f
+DATA ffd01428 00085520
+DATA ffd0147c 00008552
+DATA ffd01500 00000000
+DATA ffd01504 0ffffff1
+DATA ffd01508 10000000
+DATA ffd0150c 0ffffff5
+DATA ffd01514 00000000
+DATA ffd0151c 00000000
+DATA ffd01494 00030000
+DATA ffd01498 00000000
+DATA ffd0149c 0000e803
+DATA ffd01480 00000001
diff --git a/arch/arm/boards/globalscale-mirabox/Makefile b/arch/arm/boards/globalscale-mirabox/Makefile
new file mode 100644
index 0000000000..9320510bab
--- /dev/null
+++ b/arch/arm/boards/globalscale-mirabox/Makefile
@@ -0,0 +1 @@
+obj-y += board.c
diff --git a/arch/arm/boards/globalscale-mirabox/board.c b/arch/arm/boards/globalscale-mirabox/board.c
new file mode 100644
index 0000000000..9c800c5410
--- /dev/null
+++ b/arch/arm/boards/globalscale-mirabox/board.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright
+ * (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * 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.
+ *
+ */
+
+/* empty */
diff --git a/arch/arm/boards/globalscale-mirabox/config.h b/arch/arm/boards/globalscale-mirabox/config.h
new file mode 100644
index 0000000000..ca15136817
--- /dev/null
+++ b/arch/arm/boards/globalscale-mirabox/config.h
@@ -0,0 +1,4 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif /* __CONFIG_H */
diff --git a/arch/arm/boards/globalscale-mirabox/kwbimage.cfg b/arch/arm/boards/globalscale-mirabox/kwbimage.cfg
new file mode 100644
index 0000000000..72283d9b69
--- /dev/null
+++ b/arch/arm/boards/globalscale-mirabox/kwbimage.cfg
@@ -0,0 +1,5 @@
+VERSION 1
+BOOT_FROM nand
+NAND_BLKSZ 00020000
+NAND_BADBLK_LOCATION 01
+BINARY globalscale-mirabox-binary.0 0000005b 00000068
diff --git a/arch/arm/boards/marvell-armada-xp-gp/Makefile b/arch/arm/boards/marvell-armada-xp-gp/Makefile
new file mode 100644
index 0000000000..dcfc2937d3
--- /dev/null
+++ b/arch/arm/boards/marvell-armada-xp-gp/Makefile
@@ -0,0 +1 @@
+obj-y += board.o
diff --git a/arch/arm/boards/marvell-armada-xp-gp/board.c b/arch/arm/boards/marvell-armada-xp-gp/board.c
new file mode 100644
index 0000000000..9c800c5410
--- /dev/null
+++ b/arch/arm/boards/marvell-armada-xp-gp/board.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright
+ * (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * 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.
+ *
+ */
+
+/* empty */
diff --git a/arch/arm/boards/marvell-armada-xp-gp/config.h b/arch/arm/boards/marvell-armada-xp-gp/config.h
new file mode 100644
index 0000000000..ca15136817
--- /dev/null
+++ b/arch/arm/boards/marvell-armada-xp-gp/config.h
@@ -0,0 +1,4 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif /* __CONFIG_H */
diff --git a/arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg b/arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg
new file mode 100644
index 0000000000..db75969fe0
--- /dev/null
+++ b/arch/arm/boards/marvell-armada-xp-gp/kwbimage.cfg
@@ -0,0 +1,3 @@
+VERSION 1
+BOOT_FROM spi
+BINARY marvell-armada-xp-gp-binary.0 0000005b 00000068
diff --git a/arch/arm/boards/pcm038/pcm038.c b/arch/arm/boards/pcm038/pcm038.c
index 4b2fa6c6ca..372aea59d5 100644
--- a/arch/arm/boards/pcm038/pcm038.c
+++ b/arch/arm/boards/pcm038/pcm038.c
@@ -48,13 +48,20 @@
#define PCM038_GPIO_FEC_RST (GPIO_PORTC + 30)
#define PCM038_GPIO_SPI_CS0 (GPIO_PORTD + 28)
+#define PCM970_GPIO_SPI_CS1 (GPIO_PORTD + 27)
+#define PCM038_GPIO_OTG_STP (GPIO_PORTE + 1)
static struct fec_platform_data fec_info = {
.xcv_type = PHY_INTERFACE_MODE_MII,
.phy_addr = 1,
};
-static int pcm038_spi_cs[] = { PCM038_GPIO_SPI_CS0 };
+static int pcm038_spi_cs[] = {
+ PCM038_GPIO_SPI_CS0,
+#ifdef CONFIG_MACH_PCM970_BASEBOARD
+ PCM970_GPIO_SPI_CS1,
+#endif
+};
static struct spi_imx_master pcm038_spi_0_data = {
.chipselect = pcm038_spi_cs,
@@ -186,6 +193,11 @@ static int pcm038_power_init(void)
return 0;
}
+struct imxusb_platformdata pcm038_otg_pdata = {
+ .mode = IMX_USB_MODE_DEVICE,
+ .flags = MXC_EHCI_MODE_ULPI | MXC_EHCI_INTERFACE_DIFF_UNI,
+};
+
static int pcm038_devices_init(void)
{
int i;
@@ -221,10 +233,13 @@ static int pcm038_devices_init(void)
PE15_PF_UART1_RTS,
/* CSPI1 */
PD25_PF_CSPI1_RDY,
- PCM038_GPIO_SPI_CS0 | GPIO_GPIO | GPIO_OUT,
PD29_PF_CSPI1_SCLK,
PD30_PF_CSPI1_MISO,
PD31_PF_CSPI1_MOSI,
+ PCM038_GPIO_SPI_CS0 | GPIO_GPIO | GPIO_OUT,
+#ifdef CONFIG_MACH_PCM970_BASEBOARD
+ PCM970_GPIO_SPI_CS1 | GPIO_GPIO | GPIO_OUT,
+#endif
/* Display */
PA5_PF_LSCLK,
PA6_PF_LD0,
@@ -253,7 +268,7 @@ static int pcm038_devices_init(void)
PA29_PF_VSYNC,
PA30_PF_CONTRAST,
PA31_PF_OE_ACD,
- /* OTG host */
+ /* USB OTG */
PC7_PF_USBOTG_DATA5,
PC8_PF_USBOTG_DATA6,
PC9_PF_USBOTG_DATA0,
@@ -262,7 +277,7 @@ static int pcm038_devices_init(void)
PC12_PF_USBOTG_DATA4,
PC13_PF_USBOTG_DATA3,
PE0_PF_USBOTG_NXT,
- PE1_PF_USBOTG_STP,
+ PCM038_GPIO_OTG_STP | GPIO_GPIO | GPIO_OUT,
PE2_PF_USBOTG_DIR,
PE24_PF_USBOTG_CLK,
PE25_PF_USBOTG_DATA7,
@@ -308,6 +323,13 @@ static int pcm038_devices_init(void)
gpio_set_value(PCM038_GPIO_FEC_RST, 1);
imx27_add_fec(&fec_info);
+ /* Apply delay for STP line to stop ULPI */
+ gpio_direction_output(PCM038_GPIO_OTG_STP, 1);
+ mdelay(1);
+ imx_gpio_mode(PE1_PF_USBOTG_STP);
+
+ imx27_add_usbotg(&pcm038_otg_pdata);
+
switch (bootsource_get()) {
case BOOTSOURCE_NAND:
devfs_add_partition("nand0", 0x00000, 0x80000,
diff --git a/arch/arm/boards/pcm049/board.c b/arch/arm/boards/pcm049/board.c
index b0d689bf02..3c4b1a7dbe 100644
--- a/arch/arm/boards/pcm049/board.c
+++ b/arch/arm/boards/pcm049/board.c
@@ -48,7 +48,11 @@ console_initcall(pcm049_console_init);
static int pcm049_mem_init(void)
{
+#ifdef CONFIG_1024MB_DDR2RAM
+ omap_add_ram0(SZ_1G);
+#else
omap_add_ram0(SZ_512M);
+#endif
omap44xx_add_sram0();
return 0;
diff --git a/arch/arm/boards/pcm049/lowlevel.c b/arch/arm/boards/pcm049/lowlevel.c
index 5075bbba3b..8bcecb14b1 100644
--- a/arch/arm/boards/pcm049/lowlevel.c
+++ b/arch/arm/boards/pcm049/lowlevel.c
@@ -30,6 +30,7 @@
void set_muxconf_regs(void);
+/* 512MB */
static const struct ddr_regs ddr_regs_mt42L64M64_25_400_mhz = {
.tim1 = 0x0EEB0662,
.tim2 = 0x20370DD2,
@@ -43,6 +44,20 @@ static const struct ddr_regs ddr_regs_mt42L64M64_25_400_mhz = {
.mr2 = 0x4
};
+/* 1GB */
+static const struct ddr_regs ddr_regs_mt42L128M64_25_400_mhz = {
+ .tim1 = 0x0EEB0663,
+ .tim2 = 0x205715D2,
+ .tim3 = 0x00BFC53F,
+ .phy_ctrl_1 = 0x849FF408,
+ .ref_ctrl = 0x00000618,
+ .config_init = 0x80001AB9,
+ .config_final = 0x80001AB9,
+ .zq_config = 0x50093215,
+ .mr1 = 0x83,
+ .mr2 = 0x4
+};
+
static void noinline pcm049_init_lowlevel(void)
{
struct dpll_param core = OMAP4_CORE_DPLL_PARAM_19M2_DDR400;
@@ -55,7 +70,11 @@ static void noinline pcm049_init_lowlevel(void)
set_muxconf_regs();
- omap4_ddr_init(&ddr_regs_mt42L64M64_25_400_mhz, &core);
+#ifdef CONFIG_1024MB_DDR2RAM
+ omap4_ddr_init(&ddr_regs_mt42L128M64_25_400_mhz, &core);
+#else
+ omap4_ddr_init(&ddr_regs_mt42L64M64_25_400_mhz, &core);
+#endif
/* Set VCORE1 = 1.3 V, VCORE2 = VCORE3 = 1.21V */
omap4_scale_vcores(TPS62361_VSEL0_GPIO);
@@ -76,11 +95,11 @@ static void noinline pcm049_init_lowlevel(void)
/* Enable all clocks */
omap4_enable_all_clocks();
- sr32(0x4A30a31C, 8, 1, 0x1); /* enable software ioreq */
- sr32(0x4A30a31C, 1, 2, 0x0); /* set for sys_clk (19.2MHz) */
- sr32(0x4A30a31C, 16, 4, 0x0); /* set divisor to 1 */
- sr32(0x4A30a110, 0, 1, 0x1); /* set the clock source to active */
- sr32(0x4A30a110, 2, 2, 0x3); /* enable clocks */
+ sr32(OMAP44XX_SCRM_AUXCLK3, 8, 1, 0x1); /* enable software ioreq */
+ sr32(OMAP44XX_SCRM_AUXCLK3, 1, 2, 0x0); /* set for sys_clk (19.2MHz) */
+ sr32(OMAP44XX_SCRM_AUXCLK3, 16, 4, 0x0); /* set divisor to 1 */
+ sr32(OMAP44XX_SCRM_ALTCLKSRC, 0, 1, 0x1); /* activate clock source */
+ sr32(OMAP44XX_SCRM_ALTCLKSRC, 2, 2, 0x3); /* enable clocks */
}
void barebox_arm_reset_vector(void)
diff --git a/arch/arm/boards/plathome-openblocks-ax3/Makefile b/arch/arm/boards/plathome-openblocks-ax3/Makefile
new file mode 100644
index 0000000000..dcfc2937d3
--- /dev/null
+++ b/arch/arm/boards/plathome-openblocks-ax3/Makefile
@@ -0,0 +1 @@
+obj-y += board.o
diff --git a/arch/arm/boards/plathome-openblocks-ax3/board.c b/arch/arm/boards/plathome-openblocks-ax3/board.c
new file mode 100644
index 0000000000..9c800c5410
--- /dev/null
+++ b/arch/arm/boards/plathome-openblocks-ax3/board.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright
+ * (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * 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.
+ *
+ */
+
+/* empty */
diff --git a/arch/arm/boards/plathome-openblocks-ax3/config.h b/arch/arm/boards/plathome-openblocks-ax3/config.h
new file mode 100644
index 0000000000..ca15136817
--- /dev/null
+++ b/arch/arm/boards/plathome-openblocks-ax3/config.h
@@ -0,0 +1,4 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif /* __CONFIG_H */
diff --git a/arch/arm/boards/plathome-openblocks-ax3/kwbimage.cfg b/arch/arm/boards/plathome-openblocks-ax3/kwbimage.cfg
new file mode 100644
index 0000000000..69fd1fd1c1
--- /dev/null
+++ b/arch/arm/boards/plathome-openblocks-ax3/kwbimage.cfg
@@ -0,0 +1,3 @@
+VERSION 1
+BOOT_FROM spi
+BINARY plathome-openblocks-ax3-binary.0 0000005b 00000068
diff --git a/arch/arm/boards/qil-a9260/Makefile b/arch/arm/boards/qil-a926x/Makefile
index eb072c0161..eb072c0161 100644
--- a/arch/arm/boards/qil-a9260/Makefile
+++ b/arch/arm/boards/qil-a926x/Makefile
diff --git a/arch/arm/boards/qil-a9260/config.h b/arch/arm/boards/qil-a926x/config.h
index d97181032f..d97181032f 100644
--- a/arch/arm/boards/qil-a9260/config.h
+++ b/arch/arm/boards/qil-a926x/config.h
diff --git a/arch/arm/boards/qil-a9260/env/bin/init_board b/arch/arm/boards/qil-a926x/env/bin/init_board
index 0a6baf722b..0a6baf722b 100644
--- a/arch/arm/boards/qil-a9260/env/bin/init_board
+++ b/arch/arm/boards/qil-a926x/env/bin/init_board
diff --git a/arch/arm/boards/qil-a9260/env/config b/arch/arm/boards/qil-a926x/env/config
index 99711062f8..793a73f11e 100644
--- a/arch/arm/boards/qil-a9260/env/config
+++ b/arch/arm/boards/qil-a926x/env/config
@@ -3,7 +3,8 @@
# use 'dhcp' to do dhcp in barebox and in kernel
# use 'none' if you want to skip kernel ip autoconfiguration
ip=dhcp-barebox
-global.dhcp.vendor_id=barebox-qil-a9260
+[ x$armlinux_architecture = x1711 ] && global.dhcp.vendor_id=barebox-qil-a9260
+[ x$armlinux_architecture = x1844 ] && global.dhcp.vendor_id=barebox-qil-a9g20
# or set your networking parameters here
#eth0.ipaddr=a.b.c.d
diff --git a/arch/arm/boards/qil-a9260/init.c b/arch/arm/boards/qil-a926x/init.c
index 56b51c245a..504abc6566 100644
--- a/arch/arm/boards/qil-a9260/init.c
+++ b/arch/arm/boards/qil-a926x/init.c
@@ -28,6 +28,14 @@
#include <mach/at91_pmc.h>
#include <mach/at91_rstc.h>
+static void qil_a9260_set_board_type(void)
+{
+ if (machine_is_qil_a9g20())
+ armlinux_set_architecture(MACH_TYPE_QIL_A9G20);
+ else
+ armlinux_set_architecture(MACH_TYPE_QIL_A9260);
+}
+
static struct atmel_nand_data nand_pdata = {
.ale = 21,
.cle = 22,
@@ -37,7 +45,7 @@ static struct atmel_nand_data nand_pdata = {
.on_flash_bbt = 1,
};
-static struct sam9_smc_config nand_smc_config = {
+static struct sam9_smc_config qil_a9260_nand_smc_config = {
.ncs_read_setup = 0,
.nrd_setup = 1,
.ncs_write_setup = 0,
@@ -55,10 +63,31 @@ static struct sam9_smc_config nand_smc_config = {
.tdf_cycles = 2,
};
+static struct sam9_smc_config qil_a9g20_nand_smc_config = {
+ .ncs_read_setup = 0,
+ .nrd_setup = 2,
+ .ncs_write_setup = 0,
+ .nwe_setup = 2,
+
+ .ncs_read_pulse = 4,
+ .nrd_pulse = 4,
+ .ncs_write_pulse = 4,
+ .nwe_pulse = 4,
+
+ .read_cycle = 7,
+ .write_cycle = 7,
+
+ .mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_DBW_8,
+ .tdf_cycles = 3,
+};
+
static void qil_a9260_add_device_nand(void)
{
/* configure chip-select 3 (NAND) */
- sam9_smc_configure(0, 3, &nand_smc_config);
+ if (machine_is_qil_a9g20())
+ sam9_smc_configure(0, 3, &qil_a9g20_nand_smc_config);
+ else
+ sam9_smc_configure(0, 3, &qil_a9260_nand_smc_config);
at91_add_device_nand(&nand_pdata);
}
@@ -174,7 +203,7 @@ static int qil_a9260_devices_init(void)
qil_a9260_add_device_mb();
armlinux_set_bootparams((void *)(AT91_CHIPSELECT_1 + 0x100));
- armlinux_set_architecture(MACH_TYPE_QIL_A9260);
+ qil_a9260_set_board_type();
devfs_add_partition("nand0", 0x00000, SZ_128K, DEVFS_PARTITION_FIXED, "at91bootstrap_raw");
dev_add_bb_dev("at91bootstrap_raw", "at91bootstrap");
diff --git a/arch/arm/boards/qil-a9260/qil-a9260.dox b/arch/arm/boards/qil-a926x/qil-a9260.dox
index da5c197b34..da5c197b34 100644
--- a/arch/arm/boards/qil-a9260/qil-a9260.dox
+++ b/arch/arm/boards/qil-a926x/qil-a9260.dox
diff --git a/arch/arm/boards/solidrun-cubox/Makefile b/arch/arm/boards/solidrun-cubox/Makefile
new file mode 100644
index 0000000000..9320510bab
--- /dev/null
+++ b/arch/arm/boards/solidrun-cubox/Makefile
@@ -0,0 +1 @@
+obj-y += board.c
diff --git a/arch/arm/boards/solidrun-cubox/board.c b/arch/arm/boards/solidrun-cubox/board.c
new file mode 100644
index 0000000000..a28f4197df
--- /dev/null
+++ b/arch/arm/boards/solidrun-cubox/board.c
@@ -0,0 +1,17 @@
+/*
+ * Copyright (C) 2013
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+/* empty */
diff --git a/arch/arm/boards/solidrun-cubox/config.h b/arch/arm/boards/solidrun-cubox/config.h
new file mode 100644
index 0000000000..ca15136817
--- /dev/null
+++ b/arch/arm/boards/solidrun-cubox/config.h
@@ -0,0 +1,4 @@
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif /* __CONFIG_H */
diff --git a/arch/arm/boards/solidrun-cubox/kwbimage.cfg b/arch/arm/boards/solidrun-cubox/kwbimage.cfg
new file mode 100644
index 0000000000..db35acacd4
--- /dev/null
+++ b/arch/arm/boards/solidrun-cubox/kwbimage.cfg
@@ -0,0 +1,37 @@
+VERSION 0
+BOOT_FROM spi
+DATA d0020104 00000000
+DATA d0800020 00022430
+DATA d0800030 00022430
+DATA d0800050 911500c3
+DATA d0800060 646602c4
+DATA d0800190 c2003053
+DATA d08001c0 34f4a187
+DATA d0800650 000f0121
+DATA d0800660 04040200
+DATA d0800080 00000000
+DATA d0800090 00080000
+DATA d08000f0 c0000000
+DATA d08001a0 20c0c009
+DATA d0800280 010e0202
+DATA d0800760 00000000
+DATA d0800770 0000000a
+DATA d0800140 20004044
+DATA d08001d0 133c2339
+DATA d08001e0 07700330
+DATA d08001f0 00000033
+DATA d0800200 0011311c
+DATA d0800210 00300000
+DATA d0800240 80000000
+DATA d0800510 010e0101
+DATA d0800230 2028006a
+DATA d0800e10 00280062
+DATA d0800e20 00280062
+DATA d0800e30 00280062
+DATA d0800100 000d0001
+DATA d0800110 200d0001
+DATA d0020104 00000000
+DATA d0020104 00000000
+DATA d0020104 00000000
+DATA d0020104 00000000
+DATA d0020104 00000000
diff --git a/arch/arm/configs/freescale-mx6-sabrelite_defconfig b/arch/arm/configs/freescale-mx6-sabrelite_defconfig
index be7919be4e..d4d6cf24a2 100644
--- a/arch/arm/configs/freescale-mx6-sabrelite_defconfig
+++ b/arch/arm/configs/freescale-mx6-sabrelite_defconfig
@@ -1,9 +1,10 @@
+CONFIG_BUILTIN_DTB=y
+CONFIG_BUILTIN_DTB_NAME="imx6q-sabrelite"
CONFIG_ARCH_IMX=y
CONFIG_ARCH_IMX6=y
CONFIG_MACH_SABRELITE=y
CONFIG_IMX_IIM=y
CONFIG_IMX_IIM_FUSE_BLOW=y
-CONFIG_AEABI=y
CONFIG_THUMB2_BAREBOX=y
CONFIG_CMD_ARM_MMUINFO=y
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
@@ -17,8 +18,10 @@ CONFIG_HUSH_FANCY_PROMPT=y
CONFIG_CMDLINE_EDITING=y
CONFIG_AUTO_COMPLETE=y
CONFIG_MENU=y
+CONFIG_CONSOLE_ACTIVATE_NONE=y
CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/freescale-mx6-sabrelite/env"
+CONFIG_RESET_SOURCE=y
CONFIG_CMD_EDIT=y
CONFIG_CMD_SLEEP=y
CONFIG_CMD_MSLEEP=y
@@ -28,8 +31,9 @@ CONFIG_CMD_READLINE=y
CONFIG_CMD_MENU=y
CONFIG_CMD_MENU_MANAGEMENT=y
CONFIG_CMD_TIME=y
-CONFIG_CMD_BASENAME=y
-CONFIG_CMD_DIRNAME=y
+CONFIG_CMD_LN=y
+CONFIG_CMD_TFTP=y
+CONFIG_CMD_FILETYPE=y
CONFIG_CMD_ECHO_E=y
CONFIG_CMD_MEMINFO=y
CONFIG_CMD_IOMEM=y
@@ -43,29 +47,37 @@ CONFIG_CMD_BOOTM_INITRD=y
CONFIG_CMD_BOOTM_OFTREE=y
CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
CONFIG_CMD_BOOTM_AIMAGE=y
-# CONFIG_CMD_BOOTZ is not set
# CONFIG_CMD_BOOTU is not set
CONFIG_CMD_RESET=y
CONFIG_CMD_GO=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OF_NODE=y
+CONFIG_CMD_BAREBOX_UPDATE=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_MAGICVAR=y
CONFIG_CMD_MAGICVAR_HELP=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_UNCOMPRESS=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_MIITOOL=y
+CONFIG_CMD_CLK=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
-CONFIG_NET_RESOLV=y
CONFIG_NET_PING=y
-CONFIG_CMD_TFTP=y
CONFIG_NET_NETCONSOLE=y
+CONFIG_NET_RESOLV=y
+CONFIG_OFDEVICE=y
CONFIG_DRIVER_NET_FEC_IMX=y
CONFIG_DRIVER_SPI_IMX=y
+CONFIG_MTD=y
CONFIG_MTD_M25P80=y
CONFIG_MTD_SST25L=y
-CONFIG_MTD=y
+CONFIG_USB=y
+CONFIG_USB_EHCI=y
+CONFIG_USB_STORAGE=y
CONFIG_MCI=y
-CONFIG_MCI_STARTUP=y
CONFIG_MCI_IMX_ESDHC=y
CONFIG_FS_TFTP=y
CONFIG_FS_NFS=y
diff --git a/arch/arm/configs/freescale_mx51_babbage_defconfig b/arch/arm/configs/freescale_mx51_babbage_defconfig
index 97963c1dca..2c03c14212 100644
--- a/arch/arm/configs/freescale_mx51_babbage_defconfig
+++ b/arch/arm/configs/freescale_mx51_babbage_defconfig
@@ -1,13 +1,13 @@
+CONFIG_BUILTIN_DTB=y
+CONFIG_BUILTIN_DTB_NAME="imx51-babbage"
CONFIG_ARCH_IMX=y
CONFIG_ARCH_IMX51=y
CONFIG_IMX_IIM=y
CONFIG_IMX_IIM_FUSE_BLOW=y
-CONFIG_AEABI=y
CONFIG_THUMB2_BAREBOX=y
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
CONFIG_ARM_UNWIND=y
CONFIG_MMU=y
-CONFIG_TEXT_BASE=0x97f00000
CONFIG_MALLOC_SIZE=0x2000000
CONFIG_MALLOC_TLSF=y
CONFIG_KALLSYMS=y
@@ -16,6 +16,7 @@ CONFIG_HUSH_FANCY_PROMPT=y
CONFIG_CMDLINE_EDITING=y
CONFIG_AUTO_COMPLETE=y
CONFIG_MENU=y
+CONFIG_CONSOLE_ACTIVATE_NONE=y
CONFIG_DEFAULT_ENVIRONMENT_COMPRESSED_LZO=y
CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/freescale-mx51-pdk/env/"
@@ -31,8 +32,10 @@ CONFIG_CMD_TIME=y
CONFIG_CMD_ECHO_E=y
CONFIG_CMD_MEMINFO=y
CONFIG_CMD_IOMEM=y
+CONFIG_CMD_MM=y
CONFIG_CMD_CRC=y
CONFIG_CMD_CRC_CMP=y
+CONFIG_CMD_MD5SUM=y
CONFIG_CMD_FLASH=y
CONFIG_CMD_BOOTM_SHOW_TYPE=y
CONFIG_CMD_BOOTM_VERBOSE=y
@@ -43,19 +46,28 @@ CONFIG_CMD_UIMAGE=y
# CONFIG_CMD_BOOTU is not set
CONFIG_CMD_RESET=y
CONFIG_CMD_GO=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OF_NODE=y
+CONFIG_CMD_BAREBOX_UPDATE=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_MAGICVAR=y
CONFIG_CMD_MAGICVAR_HELP=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_UNCOMPRESS=y
+CONFIG_CMD_SPI=y
+CONFIG_CMD_MIITOOL=y
+CONFIG_CMD_CLK=y
CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_PING=y
CONFIG_NET_RESOLV=y
+CONFIG_OFDEVICE=y
CONFIG_DRIVER_NET_FEC_IMX=y
CONFIG_DRIVER_SPI_IMX=y
CONFIG_MTD=y
+CONFIG_MTD_DATAFLASH=y
CONFIG_DRIVER_CFI=y
CONFIG_CFI_BUFFER_WRITE=y
CONFIG_MCI=y
diff --git a/arch/arm/configs/globalscale_guruplug_defconfig b/arch/arm/configs/globalscale_guruplug_defconfig
new file mode 100644
index 0000000000..d21de45c5d
--- /dev/null
+++ b/arch/arm/configs/globalscale_guruplug_defconfig
@@ -0,0 +1,6 @@
+CONFIG_ARCH_MVEBU=y
+CONFIG_ARCH_KIRKWOOD=y
+CONFIG_TEXT_BASE=0x2000000
+CONFIG_DEBUG_LL=y
+CONFIG_CMD_RESET=y
+CONFIG_DRIVER_SERIAL_NS16550=y
diff --git a/arch/arm/configs/globalscale_mirabox_defconfig b/arch/arm/configs/globalscale_mirabox_defconfig
new file mode 100644
index 0000000000..ed9d94d867
--- /dev/null
+++ b/arch/arm/configs/globalscale_mirabox_defconfig
@@ -0,0 +1,8 @@
+CONFIG_ARCH_MVEBU=y
+CONFIG_AEABI=y
+CONFIG_DEBUG_LL=y
+CONFIG_CMD_LOADY=y
+CONFIG_CMD_LOADS=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_CLK=y
+CONFIG_DRIVER_SERIAL_NS16550=y
diff --git a/arch/arm/configs/marvell_armada_xp_gp_defconfig b/arch/arm/configs/marvell_armada_xp_gp_defconfig
new file mode 100644
index 0000000000..5a7ef52b5f
--- /dev/null
+++ b/arch/arm/configs/marvell_armada_xp_gp_defconfig
@@ -0,0 +1,10 @@
+CONFIG_ARCH_MVEBU=y
+CONFIG_ARCH_ARMADA_XP=y
+CONFIG_MACH_MARVELL_ARMADA_XP_GP=y
+CONFIG_AEABI=y
+CONFIG_DEBUG_LL=y
+CONFIG_CMD_LOADY=y
+CONFIG_CMD_LOADS=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_CLK=y
+CONFIG_DRIVER_SERIAL_NS16550=y
diff --git a/arch/arm/configs/plathome_openblocks_ax3_defconfig b/arch/arm/configs/plathome_openblocks_ax3_defconfig
new file mode 100644
index 0000000000..95449c9741
--- /dev/null
+++ b/arch/arm/configs/plathome_openblocks_ax3_defconfig
@@ -0,0 +1,9 @@
+CONFIG_ARCH_MVEBU=y
+CONFIG_ARCH_ARMADA_XP=y
+CONFIG_AEABI=y
+CONFIG_DEBUG_LL=y
+CONFIG_CMD_LOADY=y
+CONFIG_CMD_LOADS=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_CLK=y
+CONFIG_DRIVER_SERIAL_NS16550=y
diff --git a/arch/arm/configs/qil_a9260_128mib_defconfig b/arch/arm/configs/qil_a9260_128mib_defconfig
index 8cd28f42c0..a19e083628 100644
--- a/arch/arm/configs/qil_a9260_128mib_defconfig
+++ b/arch/arm/configs/qil_a9260_128mib_defconfig
@@ -2,12 +2,12 @@ CONFIG_ARCH_AT91SAM9260=y
CONFIG_MACH_QIL_A9260=y
CONFIG_AT91_HAVE_SRAM_128M=y
CONFIG_CALAO_MB_QIL_A9260=y
+CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000
CONFIG_AEABI=y
# CONFIG_CMD_ARM_CPUINFO is not set
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
CONFIG_PBL_IMAGE=y
CONFIG_MMU=y
-CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000
CONFIG_EXPERIMENTAL=y
CONFIG_PROMPT="USB-9G20:"
CONFIG_LONGHELP=y
@@ -17,10 +17,9 @@ CONFIG_HUSH_FANCY_PROMPT=y
CONFIG_CMDLINE_EDITING=y
CONFIG_AUTO_COMPLETE=y
CONFIG_MENU=y
-# CONFIG_CONSOLE_ACTIVATE_FIRST is not set
CONFIG_CONSOLE_ACTIVATE_ALL=y
CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
-CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/qil-a9260/env"
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/qil-a926x/env"
CONFIG_CMD_EDIT=y
CONFIG_CMD_SLEEP=y
CONFIG_CMD_SAVEENV=y
@@ -29,11 +28,10 @@ CONFIG_CMD_PRINTENV=y
CONFIG_CMD_READLINE=y
CONFIG_CMD_MENU=y
CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_TFTP=y
CONFIG_CMD_ECHO_E=y
CONFIG_CMD_LOADB=y
CONFIG_CMD_MEMINFO=y
-CONFIG_CMD_MTEST=y
-CONFIG_CMD_MTEST_ALTERNATIVE=y
CONFIG_CMD_FLASH=y
CONFIG_CMD_BOOTM_SHOW_TYPE=y
CONFIG_CMD_BOOTM_VERBOSE=y
@@ -41,11 +39,12 @@ CONFIG_CMD_BOOTM_INITRD=y
CONFIG_CMD_BOOTM_OFTREE=y
CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
CONFIG_CMD_UIMAGE=y
-# CONFIG_CMD_BOOTZ is not set
# CONFIG_CMD_BOOTU is not set
CONFIG_CMD_RESET=y
CONFIG_CMD_GO=y
CONFIG_CMD_OFTREE=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
@@ -55,8 +54,6 @@ CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
CONFIG_NET_PING=y
-CONFIG_CMD_TFTP=y
-CONFIG_FS_TFTP=y
CONFIG_NET_NETCONSOLE=y
CONFIG_NET_RESOLV=y
CONFIG_DRIVER_NET_MACB=y
@@ -77,3 +74,4 @@ CONFIG_MCI_ATMEL=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
CONFIG_LED_TRIGGERS=y
+CONFIG_FS_TFTP=y
diff --git a/arch/arm/configs/qil_a9260_defconfig b/arch/arm/configs/qil_a9260_defconfig
index 13460e8e89..67ca804ea7 100644
--- a/arch/arm/configs/qil_a9260_defconfig
+++ b/arch/arm/configs/qil_a9260_defconfig
@@ -1,12 +1,12 @@
CONFIG_ARCH_AT91SAM9260=y
CONFIG_MACH_QIL_A9260=y
CONFIG_CALAO_MB_QIL_A9260=y
+CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000
CONFIG_AEABI=y
# CONFIG_CMD_ARM_CPUINFO is not set
CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
CONFIG_PBL_IMAGE=y
CONFIG_MMU=y
-CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000
CONFIG_EXPERIMENTAL=y
CONFIG_PROMPT="USB-9G20:"
CONFIG_LONGHELP=y
@@ -16,10 +16,9 @@ CONFIG_HUSH_FANCY_PROMPT=y
CONFIG_CMDLINE_EDITING=y
CONFIG_AUTO_COMPLETE=y
CONFIG_MENU=y
-# CONFIG_CONSOLE_ACTIVATE_FIRST is not set
CONFIG_CONSOLE_ACTIVATE_ALL=y
CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
-CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/qil-a9260/env"
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/qil-a926x/env"
CONFIG_CMD_EDIT=y
CONFIG_CMD_SLEEP=y
CONFIG_CMD_SAVEENV=y
@@ -28,11 +27,10 @@ CONFIG_CMD_PRINTENV=y
CONFIG_CMD_READLINE=y
CONFIG_CMD_MENU=y
CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_TFTP=y
CONFIG_CMD_ECHO_E=y
CONFIG_CMD_LOADB=y
CONFIG_CMD_MEMINFO=y
-CONFIG_CMD_MTEST=y
-CONFIG_CMD_MTEST_ALTERNATIVE=y
CONFIG_CMD_FLASH=y
CONFIG_CMD_BOOTM_SHOW_TYPE=y
CONFIG_CMD_BOOTM_VERBOSE=y
@@ -40,11 +38,12 @@ CONFIG_CMD_BOOTM_INITRD=y
CONFIG_CMD_BOOTM_OFTREE=y
CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
CONFIG_CMD_UIMAGE=y
-# CONFIG_CMD_BOOTZ is not set
# CONFIG_CMD_BOOTU is not set
CONFIG_CMD_RESET=y
CONFIG_CMD_GO=y
CONFIG_CMD_OFTREE=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_GPIO=y
@@ -54,8 +53,6 @@ CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
CONFIG_NET_PING=y
-CONFIG_CMD_TFTP=y
-CONFIG_FS_TFTP=y
CONFIG_NET_NETCONSOLE=y
CONFIG_NET_RESOLV=y
CONFIG_DRIVER_NET_MACB=y
@@ -76,3 +73,4 @@ CONFIG_MCI_ATMEL=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
CONFIG_LED_TRIGGERS=y
+CONFIG_FS_TFTP=y
diff --git a/arch/arm/configs/qil_a9g20_128mib_defconfig b/arch/arm/configs/qil_a9g20_128mib_defconfig
new file mode 100644
index 0000000000..2c4a1602aa
--- /dev/null
+++ b/arch/arm/configs/qil_a9g20_128mib_defconfig
@@ -0,0 +1,77 @@
+CONFIG_ARCH_AT91SAM9G20=y
+CONFIG_MACH_QIL_A9G20=y
+CONFIG_AT91_HAVE_SRAM_128M=y
+CONFIG_CALAO_MB_QIL_A9260=y
+CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000
+CONFIG_AEABI=y
+# CONFIG_CMD_ARM_CPUINFO is not set
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_PBL_IMAGE=y
+CONFIG_MMU=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_PROMPT="USB-9G20:"
+CONFIG_LONGHELP=y
+CONFIG_GLOB=y
+CONFIG_PROMPT_HUSH_PS2="y"
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_CONSOLE_ACTIVATE_ALL=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/qil-a926x/env"
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_TFTP=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_LOADB=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_BOOTM_VERBOSE=y
+CONFIG_CMD_BOOTM_INITRD=y
+CONFIG_CMD_BOOTM_OFTREE=y
+CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
+CONFIG_CMD_UIMAGE=y
+# CONFIG_CMD_BOOTU is not set
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_LED=y
+CONFIG_CMD_LED_TRIGGER=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_NFS=y
+CONFIG_NET_PING=y
+CONFIG_NET_NETCONSOLE=y
+CONFIG_NET_RESOLV=y
+CONFIG_DRIVER_NET_MACB=y
+# CONFIG_SPI is not set
+CONFIG_MTD=y
+# CONFIG_MTD_OOB_DEVICE is not set
+CONFIG_NAND=y
+# CONFIG_NAND_ECC_HW is not set
+# CONFIG_NAND_ECC_HW_SYNDROME is not set
+# CONFIG_NAND_ECC_HW_NONE is not set
+CONFIG_NAND_ATMEL=y
+CONFIG_UBI=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DFU=y
+CONFIG_USB_GADGET_SERIAL=y
+CONFIG_MCI=y
+CONFIG_MCI_ATMEL=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_LED_TRIGGERS=y
+CONFIG_FS_TFTP=y
diff --git a/arch/arm/configs/qil_a9g20_defconfig b/arch/arm/configs/qil_a9g20_defconfig
new file mode 100644
index 0000000000..5b2e9ef6e1
--- /dev/null
+++ b/arch/arm/configs/qil_a9g20_defconfig
@@ -0,0 +1,76 @@
+CONFIG_ARCH_AT91SAM9G20=y
+CONFIG_MACH_QIL_A9G20=y
+CONFIG_CALAO_MB_QIL_A9260=y
+CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x40000
+CONFIG_AEABI=y
+# CONFIG_CMD_ARM_CPUINFO is not set
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_PBL_IMAGE=y
+CONFIG_MMU=y
+CONFIG_EXPERIMENTAL=y
+CONFIG_PROMPT="USB-9G20:"
+CONFIG_LONGHELP=y
+CONFIG_GLOB=y
+CONFIG_PROMPT_HUSH_PS2="y"
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_CONSOLE_ACTIVATE_ALL=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/qil-a926x/env"
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_TFTP=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_LOADB=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_FLASH=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_BOOTM_VERBOSE=y
+CONFIG_CMD_BOOTM_INITRD=y
+CONFIG_CMD_BOOTM_OFTREE=y
+CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
+CONFIG_CMD_UIMAGE=y
+# CONFIG_CMD_BOOTU is not set
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_LED=y
+CONFIG_CMD_LED_TRIGGER=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_NFS=y
+CONFIG_NET_PING=y
+CONFIG_NET_NETCONSOLE=y
+CONFIG_NET_RESOLV=y
+CONFIG_DRIVER_NET_MACB=y
+# CONFIG_SPI is not set
+CONFIG_MTD=y
+# CONFIG_MTD_OOB_DEVICE is not set
+CONFIG_NAND=y
+# CONFIG_NAND_ECC_HW is not set
+# CONFIG_NAND_ECC_HW_SYNDROME is not set
+# CONFIG_NAND_ECC_HW_NONE is not set
+CONFIG_NAND_ATMEL=y
+CONFIG_UBI=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_DFU=y
+CONFIG_USB_GADGET_SERIAL=y
+CONFIG_MCI=y
+CONFIG_MCI_ATMEL=y
+CONFIG_LED=y
+CONFIG_LED_GPIO=y
+CONFIG_LED_TRIGGERS=y
+CONFIG_FS_TFTP=y
diff --git a/arch/arm/configs/solidrun_cubox_defconfig b/arch/arm/configs/solidrun_cubox_defconfig
new file mode 100644
index 0000000000..1a27d815a6
--- /dev/null
+++ b/arch/arm/configs/solidrun_cubox_defconfig
@@ -0,0 +1,9 @@
+CONFIG_ARCH_MVEBU=y
+CONFIG_ARCH_DOVE=y
+CONFIG_AEABI=y
+CONFIG_DEBUG_LL=y
+CONFIG_CMD_LOADY=y
+CONFIG_CMD_LOADS=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_CLK=y
+CONFIG_DRIVER_SERIAL_NS16550=y
diff --git a/arch/arm/configs/tegra20_colibri_iris_defconfig b/arch/arm/configs/tegra20_colibri_iris_defconfig
new file mode 100644
index 0000000000..37a0e8ac51
--- /dev/null
+++ b/arch/arm/configs/tegra20_colibri_iris_defconfig
@@ -0,0 +1,24 @@
+CONFIG_BUILTIN_DTB_NAME="tegra20-colibri-iris"
+CONFIG_ARCH_TEGRA=y
+CONFIG_AEABI=y
+CONFIG_CMD_ARM_MMUINFO=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_STACK_SIZE=0x10000
+CONFIG_MALLOC_SIZE=0x4000000
+CONFIG_LONGHELP=y
+CONFIG_GLOB=y
+CONFIG_GLOB_SORT=y
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_HUSH_GETOPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_IOMEM=y
+CONFIG_CMD_BOOTZ=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_GPIO=y
+CONFIG_CMD_CLK=y
+CONFIG_DRIVER_SERIAL_NS16550=y
diff --git a/arch/arm/cpu/Kconfig b/arch/arm/cpu/Kconfig
index 86bc174101..aed4cb7c63 100644
--- a/arch/arm/cpu/Kconfig
+++ b/arch/arm/cpu/Kconfig
@@ -39,6 +39,14 @@ config CPU_ARM926T
Say Y if you want support for the ARM926T processor.
Otherwise, say N.
+# Feroceon
+config CPU_FEROCEON
+ bool
+ select CPU_32v5
+ help
+ This is a Marvell implementation of an ARMv5TE compatible
+ ARM core, used in the Marvell Kirkwood SoC family.
+
# ARMv6
config CPU_V6
bool
diff --git a/arch/arm/cpu/cpuinfo.c b/arch/arm/cpu/cpuinfo.c
index 3c8fe4147f..8aea4b472d 100644
--- a/arch/arm/cpu/cpuinfo.c
+++ b/arch/arm/cpu/cpuinfo.c
@@ -155,7 +155,7 @@ static int do_cpuinfo(int argc, char *argv[])
implementer, architecture);
if (cache & (1 << 24)) {
- /* seperate I/D cache */
+ /* separate I/D cache */
printf("I-cache: ");
decode_cache(cache & 0xfff);
printf("D-cache: ");
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 3ee89247e0..fa6a330aa8 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1,10 +1,15 @@
+dtb-$(CONFIG_ARCH_IMX51) += imx51-babbage.dtb
+dtb-$(CONFIG_ARCH_IMX6) += imx6q-sabrelite.dtb \
+ imx6q-sabresd.dtb
-BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_NAME)).dtb.o
-obj-$(CONFIG_BUILTIN_DTB) += $(BUILTIN_DTB)
+BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_NAME))
+obj-$(CONFIG_BUILTIN_DTB) += $(BUILTIN_DTB).dtb.o
+
+.SECONDARY: $(obj)/$(BUILTIN_DTB).dtb.S
targets += dtbs
targets += $(dtb-y)
-dtbs: $(addprefix $(obj)/, $(dtb-y))
+extra-y += $(dtb-y)
clean-files := *.dtb *.dtb.S
diff --git a/arch/arm/dts/imx51-babbage.dts b/arch/arm/dts/imx51-babbage.dts
new file mode 100644
index 0000000000..4950eef606
--- /dev/null
+++ b/arch/arm/dts/imx51-babbage.dts
@@ -0,0 +1,307 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 "imx51.dtsi"
+
+/ {
+ model = "Freescale i.MX51 Babbage Board";
+ compatible = "fsl,imx51-babbage", "fsl,imx51";
+
+ chosen {
+ linux,stdout-path = "/soc/aips@70000000/serial@73fbc000";
+ };
+
+ memory {
+ reg = <0x90000000 0x20000000>;
+ };
+
+ display@di0 {
+ compatible = "fsl,imx-parallel-display";
+ crtcs = <&ipu 0>;
+ interface-pix-fmt = "rgb24";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu_disp1_1>;
+ };
+
+ display@di1 {
+ compatible = "fsl,imx-parallel-display";
+ crtcs = <&ipu 1>;
+ interface-pix-fmt = "rgb565";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ipu_disp2_1>;
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ power {
+ label = "Power Button";
+ gpios = <&gpio2 21 0>;
+ linux,code = <116>; /* KEY_POWER */
+ gpio-key,wakeup;
+ };
+ };
+
+ sound {
+ compatible = "fsl,imx51-babbage-sgtl5000",
+ "fsl,imx-audio-sgtl5000";
+ model = "imx51-babbage-sgtl5000";
+ ssi-controller = <&ssi2>;
+ audio-codec = <&sgtl5000>;
+ audio-routing =
+ "MIC_IN", "Mic Jack",
+ "Mic Jack", "Mic Bias",
+ "Headphone Jack", "HP_OUT";
+ mux-int-port = <2>;
+ mux-ext-port = <3>;
+ };
+};
+
+&esdhc1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc1_1>;
+ fsl,cd-controller;
+ fsl,wp-controller;
+ status = "okay";
+};
+
+&esdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_esdhc2_1>;
+ cd-gpios = <&gpio1 6 0>;
+ wp-gpios = <&gpio1 5 0>;
+ status = "okay";
+};
+
+&uart3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart3_1>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&ecspi1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1_1>;
+ fsl,spi-num-chipselects = <2>;
+ cs-gpios = <&gpio4 24 0>, <&gpio4 25 0>;
+ status = "okay";
+
+ pmic: mc13892@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,mc13892";
+ spi-max-frequency = <6000000>;
+ spi-cs-high;
+ reg = <0>;
+ interrupt-parent = <&gpio1>;
+ interrupts = <8 0x4>;
+
+ regulators {
+ sw1_reg: sw1 {
+ regulator-min-microvolt = <600000>;
+ regulator-max-microvolt = <1375000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw2_reg: sw2 {
+ regulator-min-microvolt = <900000>;
+ regulator-max-microvolt = <1850000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw3_reg: sw3 {
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1850000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ sw4_reg: sw4 {
+ regulator-min-microvolt = <1100000>;
+ regulator-max-microvolt = <1850000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vpll_reg: vpll {
+ regulator-min-microvolt = <1050000>;
+ regulator-max-microvolt = <1800000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vdig_reg: vdig {
+ regulator-min-microvolt = <1650000>;
+ regulator-max-microvolt = <1650000>;
+ regulator-boot-on;
+ };
+
+ vsd_reg: vsd {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <3150000>;
+ };
+
+ vusb2_reg: vusb2 {
+ regulator-min-microvolt = <2400000>;
+ regulator-max-microvolt = <2775000>;
+ regulator-boot-on;
+ regulator-always-on;
+ };
+
+ vvideo_reg: vvideo {
+ regulator-min-microvolt = <2775000>;
+ regulator-max-microvolt = <2775000>;
+ };
+
+ vaudio_reg: vaudio {
+ regulator-min-microvolt = <2300000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ vcam_reg: vcam {
+ regulator-min-microvolt = <2500000>;
+ regulator-max-microvolt = <3000000>;
+ };
+
+ vgen1_reg: vgen1 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <1200000>;
+ };
+
+ vgen2_reg: vgen2 {
+ regulator-min-microvolt = <1200000>;
+ regulator-max-microvolt = <3150000>;
+ regulator-always-on;
+ };
+
+ vgen3_reg: vgen3 {
+ regulator-min-microvolt = <1800000>;
+ regulator-max-microvolt = <2900000>;
+ regulator-always-on;
+ };
+ };
+ };
+
+ flash: at45db321d@1 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "atmel,at45db321d", "atmel,at45", "atmel,dataflash";
+ spi-max-frequency = <25000000>;
+ reg = <1>;
+
+ partition@0 {
+ label = "U-Boot";
+ reg = <0x0 0x40000>;
+ read-only;
+ };
+
+ partition@40000 {
+ label = "Kernel";
+ reg = <0x40000 0x3c0000>;
+ };
+ };
+};
+
+&ssi2 {
+ fsl,mode = "i2s-slave";
+ status = "okay";
+};
+
+&iim {
+ barebox,provide-mac-address = <&fec 1 9>;
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ hog {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX51_PAD_GPIO1_0__SD1_CD 0x20d5
+ MX51_PAD_GPIO1_1__SD1_WP 0x20d5
+ MX51_PAD_GPIO1_5__GPIO1_5 0x100
+ MX51_PAD_GPIO1_6__GPIO1_6 0x100
+ MX51_PAD_EIM_A27__GPIO2_21 0x5
+ MX51_PAD_CSPI1_SS0__GPIO4_24 0x85
+ MX51_PAD_CSPI1_SS1__GPIO4_25 0x85
+ MX51_PAD_EIM_A20__GPIO2_14 0x85
+ >;
+ };
+ };
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_1>;
+ fsl,uart-has-rtscts;
+ status = "okay";
+};
+
+&uart2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2_1>;
+ status = "okay";
+};
+
+&i2c2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c2_1>;
+ status = "okay";
+
+ sgtl5000: codec@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clock-frequency = <26000000>;
+ VDDA-supply = <&vdig_reg>;
+ VDDIO-supply = <&vvideo_reg>;
+ };
+};
+
+&audmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux_1>;
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_fec_1>;
+ phy-mode = "mii";
+ status = "okay";
+};
+
+&kpp {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_kpp_1>;
+ linux,keymap = <0x00000067 /* KEY_UP */
+ 0x0001006c /* KEY_DOWN */
+ 0x00020072 /* KEY_VOLUMEDOWN */
+ 0x00030066 /* KEY_HOME */
+ 0x0100006a /* KEY_RIGHT */
+ 0x01010069 /* KEY_LEFT */
+ 0x0102001c /* KEY_ENTER */
+ 0x01030073 /* KEY_VOLUMEUP */
+ 0x02000040 /* KEY_F6 */
+ 0x02010042 /* KEY_F8 */
+ 0x02020043 /* KEY_F9 */
+ 0x02030044 /* KEY_F10 */
+ 0x0300003b /* KEY_F1 */
+ 0x0301003c /* KEY_F2 */
+ 0x0302003d /* KEY_F3 */
+ 0x03030074>; /* KEY_POWER */
+ status = "okay";
+};
diff --git a/arch/arm/dts/imx51-pinfunc.h b/arch/arm/dts/imx51-pinfunc.h
new file mode 100644
index 0000000000..9eb92abaeb
--- /dev/null
+++ b/arch/arm/dts/imx51-pinfunc.h
@@ -0,0 +1,773 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX51_PINFUNC_H
+#define __DTS_IMX51_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX51_PAD_EIM_D16__AUD4_RXFS 0x05c 0x3f0 0x000 0x5 0x0
+#define MX51_PAD_EIM_D16__AUD5_TXD 0x05c 0x3f0 0x8d8 0x7 0x0
+#define MX51_PAD_EIM_D16__EIM_D16 0x05c 0x3f0 0x000 0x0 0x0
+#define MX51_PAD_EIM_D16__GPIO2_0 0x05c 0x3f0 0x000 0x1 0x0
+#define MX51_PAD_EIM_D16__I2C1_SDA 0x05c 0x3f0 0x9b4 0x4 0x0
+#define MX51_PAD_EIM_D16__UART2_CTS 0x05c 0x3f0 0x000 0x3 0x0
+#define MX51_PAD_EIM_D16__USBH2_DATA0 0x05c 0x3f0 0x000 0x2 0x0
+#define MX51_PAD_EIM_D17__AUD5_RXD 0x060 0x3f4 0x8d4 0x7 0x0
+#define MX51_PAD_EIM_D17__EIM_D17 0x060 0x3f4 0x000 0x0 0x0
+#define MX51_PAD_EIM_D17__GPIO2_1 0x060 0x3f4 0x000 0x1 0x0
+#define MX51_PAD_EIM_D17__UART2_RXD 0x060 0x3f4 0x9ec 0x3 0x0
+#define MX51_PAD_EIM_D17__UART3_CTS 0x060 0x3f4 0x000 0x4 0x0
+#define MX51_PAD_EIM_D17__USBH2_DATA1 0x060 0x3f4 0x000 0x2 0x0
+#define MX51_PAD_EIM_D18__AUD5_TXC 0x064 0x3f8 0x8e4 0x7 0x0
+#define MX51_PAD_EIM_D18__EIM_D18 0x064 0x3f8 0x000 0x0 0x0
+#define MX51_PAD_EIM_D18__GPIO2_2 0x064 0x3f8 0x000 0x1 0x0
+#define MX51_PAD_EIM_D18__UART2_TXD 0x064 0x3f8 0x000 0x3 0x0
+#define MX51_PAD_EIM_D18__UART3_RTS 0x064 0x3f8 0x9f0 0x4 0x1
+#define MX51_PAD_EIM_D18__USBH2_DATA2 0x064 0x3f8 0x000 0x2 0x0
+#define MX51_PAD_EIM_D19__AUD4_RXC 0x068 0x3fc 0x000 0x5 0x0
+#define MX51_PAD_EIM_D19__AUD5_TXFS 0x068 0x3fc 0x8e8 0x7 0x0
+#define MX51_PAD_EIM_D19__EIM_D19 0x068 0x3fc 0x000 0x0 0x0
+#define MX51_PAD_EIM_D19__GPIO2_3 0x068 0x3fc 0x000 0x1 0x0
+#define MX51_PAD_EIM_D19__I2C1_SCL 0x068 0x3fc 0x9b0 0x4 0x0
+#define MX51_PAD_EIM_D19__UART2_RTS 0x068 0x3fc 0x9e8 0x3 0x1
+#define MX51_PAD_EIM_D19__USBH2_DATA3 0x068 0x3fc 0x000 0x2 0x0
+#define MX51_PAD_EIM_D20__AUD4_TXD 0x06c 0x400 0x8c8 0x5 0x0
+#define MX51_PAD_EIM_D20__EIM_D20 0x06c 0x400 0x000 0x0 0x0
+#define MX51_PAD_EIM_D20__GPIO2_4 0x06c 0x400 0x000 0x1 0x0
+#define MX51_PAD_EIM_D20__SRTC_ALARM_DEB 0x06c 0x400 0x000 0x4 0x0
+#define MX51_PAD_EIM_D20__USBH2_DATA4 0x06c 0x400 0x000 0x2 0x0
+#define MX51_PAD_EIM_D21__AUD4_RXD 0x070 0x404 0x8c4 0x5 0x0
+#define MX51_PAD_EIM_D21__EIM_D21 0x070 0x404 0x000 0x0 0x0
+#define MX51_PAD_EIM_D21__GPIO2_5 0x070 0x404 0x000 0x1 0x0
+#define MX51_PAD_EIM_D21__SRTC_ALARM_DEB 0x070 0x404 0x000 0x3 0x0
+#define MX51_PAD_EIM_D21__USBH2_DATA5 0x070 0x404 0x000 0x2 0x0
+#define MX51_PAD_EIM_D22__AUD4_TXC 0x074 0x408 0x8cc 0x5 0x0
+#define MX51_PAD_EIM_D22__EIM_D22 0x074 0x408 0x000 0x0 0x0
+#define MX51_PAD_EIM_D22__GPIO2_6 0x074 0x408 0x000 0x1 0x0
+#define MX51_PAD_EIM_D22__USBH2_DATA6 0x074 0x408 0x000 0x2 0x0
+#define MX51_PAD_EIM_D23__AUD4_TXFS 0x078 0x40c 0x8d0 0x5 0x0
+#define MX51_PAD_EIM_D23__EIM_D23 0x078 0x40c 0x000 0x0 0x0
+#define MX51_PAD_EIM_D23__GPIO2_7 0x078 0x40c 0x000 0x1 0x0
+#define MX51_PAD_EIM_D23__SPDIF_OUT1 0x078 0x40c 0x000 0x4 0x0
+#define MX51_PAD_EIM_D23__USBH2_DATA7 0x078 0x40c 0x000 0x2 0x0
+#define MX51_PAD_EIM_D24__AUD6_RXFS 0x07c 0x410 0x8f8 0x5 0x0
+#define MX51_PAD_EIM_D24__EIM_D24 0x07c 0x410 0x000 0x0 0x0
+#define MX51_PAD_EIM_D24__GPIO2_8 0x07c 0x410 0x000 0x1 0x0
+#define MX51_PAD_EIM_D24__I2C2_SDA 0x07c 0x410 0x9bc 0x4 0x0
+#define MX51_PAD_EIM_D24__UART3_CTS 0x07c 0x410 0x000 0x3 0x0
+#define MX51_PAD_EIM_D24__USBOTG_DATA0 0x07c 0x410 0x000 0x2 0x0
+#define MX51_PAD_EIM_D25__EIM_D25 0x080 0x414 0x000 0x0 0x0
+#define MX51_PAD_EIM_D25__KEY_COL6 0x080 0x414 0x9c8 0x1 0x0
+#define MX51_PAD_EIM_D25__UART2_CTS 0x080 0x414 0x000 0x4 0x0
+#define MX51_PAD_EIM_D25__UART3_RXD 0x080 0x414 0x9f4 0x3 0x0
+#define MX51_PAD_EIM_D25__USBOTG_DATA1 0x080 0x414 0x000 0x2 0x0
+#define MX51_PAD_EIM_D26__EIM_D26 0x084 0x418 0x000 0x0 0x0
+#define MX51_PAD_EIM_D26__KEY_COL7 0x084 0x418 0x9cc 0x1 0x0
+#define MX51_PAD_EIM_D26__UART2_RTS 0x084 0x418 0x9e8 0x4 0x3
+#define MX51_PAD_EIM_D26__UART3_TXD 0x084 0x418 0x000 0x3 0x0
+#define MX51_PAD_EIM_D26__USBOTG_DATA2 0x084 0x418 0x000 0x2 0x0
+#define MX51_PAD_EIM_D27__AUD6_RXC 0x088 0x41c 0x8f4 0x5 0x0
+#define MX51_PAD_EIM_D27__EIM_D27 0x088 0x41c 0x000 0x0 0x0
+#define MX51_PAD_EIM_D27__GPIO2_9 0x088 0x41c 0x000 0x1 0x0
+#define MX51_PAD_EIM_D27__I2C2_SCL 0x088 0x41c 0x9b8 0x4 0x0
+#define MX51_PAD_EIM_D27__UART3_RTS 0x088 0x41c 0x9f0 0x3 0x3
+#define MX51_PAD_EIM_D27__USBOTG_DATA3 0x088 0x41c 0x000 0x2 0x0
+#define MX51_PAD_EIM_D28__AUD6_TXD 0x08c 0x420 0x8f0 0x5 0x0
+#define MX51_PAD_EIM_D28__EIM_D28 0x08c 0x420 0x000 0x0 0x0
+#define MX51_PAD_EIM_D28__KEY_ROW4 0x08c 0x420 0x9d0 0x1 0x0
+#define MX51_PAD_EIM_D28__USBOTG_DATA4 0x08c 0x420 0x000 0x2 0x0
+#define MX51_PAD_EIM_D29__AUD6_RXD 0x090 0x424 0x8ec 0x5 0x0
+#define MX51_PAD_EIM_D29__EIM_D29 0x090 0x424 0x000 0x0 0x0
+#define MX51_PAD_EIM_D29__KEY_ROW5 0x090 0x424 0x9d4 0x1 0x0
+#define MX51_PAD_EIM_D29__USBOTG_DATA5 0x090 0x424 0x000 0x2 0x0
+#define MX51_PAD_EIM_D30__AUD6_TXC 0x094 0x428 0x8fc 0x5 0x0
+#define MX51_PAD_EIM_D30__EIM_D30 0x094 0x428 0x000 0x0 0x0
+#define MX51_PAD_EIM_D30__KEY_ROW6 0x094 0x428 0x9d8 0x1 0x0
+#define MX51_PAD_EIM_D30__USBOTG_DATA6 0x094 0x428 0x000 0x2 0x0
+#define MX51_PAD_EIM_D31__AUD6_TXFS 0x098 0x42c 0x900 0x5 0x0
+#define MX51_PAD_EIM_D31__EIM_D31 0x098 0x42c 0x000 0x0 0x0
+#define MX51_PAD_EIM_D31__KEY_ROW7 0x098 0x42c 0x9dc 0x1 0x0
+#define MX51_PAD_EIM_D31__USBOTG_DATA7 0x098 0x42c 0x000 0x2 0x0
+#define MX51_PAD_EIM_A16__EIM_A16 0x09c 0x430 0x000 0x0 0x0
+#define MX51_PAD_EIM_A16__GPIO2_10 0x09c 0x430 0x000 0x1 0x0
+#define MX51_PAD_EIM_A16__OSC_FREQ_SEL0 0x09c 0x430 0x000 0x7 0x0
+#define MX51_PAD_EIM_A17__EIM_A17 0x0a0 0x434 0x000 0x0 0x0
+#define MX51_PAD_EIM_A17__GPIO2_11 0x0a0 0x434 0x000 0x1 0x0
+#define MX51_PAD_EIM_A17__OSC_FREQ_SEL1 0x0a0 0x434 0x000 0x7 0x0
+#define MX51_PAD_EIM_A18__BOOT_LPB0 0x0a4 0x438 0x000 0x7 0x0
+#define MX51_PAD_EIM_A18__EIM_A18 0x0a4 0x438 0x000 0x0 0x0
+#define MX51_PAD_EIM_A18__GPIO2_12 0x0a4 0x438 0x000 0x1 0x0
+#define MX51_PAD_EIM_A19__BOOT_LPB1 0x0a8 0x43c 0x000 0x7 0x0
+#define MX51_PAD_EIM_A19__EIM_A19 0x0a8 0x43c 0x000 0x0 0x0
+#define MX51_PAD_EIM_A19__GPIO2_13 0x0a8 0x43c 0x000 0x1 0x0
+#define MX51_PAD_EIM_A20__BOOT_UART_SRC0 0x0ac 0x440 0x000 0x7 0x0
+#define MX51_PAD_EIM_A20__EIM_A20 0x0ac 0x440 0x000 0x0 0x0
+#define MX51_PAD_EIM_A20__GPIO2_14 0x0ac 0x440 0x000 0x1 0x0
+#define MX51_PAD_EIM_A21__BOOT_UART_SRC1 0x0b0 0x444 0x000 0x7 0x0
+#define MX51_PAD_EIM_A21__EIM_A21 0x0b0 0x444 0x000 0x0 0x0
+#define MX51_PAD_EIM_A21__GPIO2_15 0x0b0 0x444 0x000 0x1 0x0
+#define MX51_PAD_EIM_A22__EIM_A22 0x0b4 0x448 0x000 0x0 0x0
+#define MX51_PAD_EIM_A22__GPIO2_16 0x0b4 0x448 0x000 0x1 0x0
+#define MX51_PAD_EIM_A23__BOOT_HPN_EN 0x0b8 0x44c 0x000 0x7 0x0
+#define MX51_PAD_EIM_A23__EIM_A23 0x0b8 0x44c 0x000 0x0 0x0
+#define MX51_PAD_EIM_A23__GPIO2_17 0x0b8 0x44c 0x000 0x1 0x0
+#define MX51_PAD_EIM_A24__EIM_A24 0x0bc 0x450 0x000 0x0 0x0
+#define MX51_PAD_EIM_A24__GPIO2_18 0x0bc 0x450 0x000 0x1 0x0
+#define MX51_PAD_EIM_A24__USBH2_CLK 0x0bc 0x450 0x000 0x2 0x0
+#define MX51_PAD_EIM_A25__DISP1_PIN4 0x0c0 0x454 0x000 0x6 0x0
+#define MX51_PAD_EIM_A25__EIM_A25 0x0c0 0x454 0x000 0x0 0x0
+#define MX51_PAD_EIM_A25__GPIO2_19 0x0c0 0x454 0x000 0x1 0x0
+#define MX51_PAD_EIM_A25__USBH2_DIR 0x0c0 0x454 0x000 0x2 0x0
+#define MX51_PAD_EIM_A26__CSI1_DATA_EN 0x0c4 0x458 0x9a0 0x5 0x0
+#define MX51_PAD_EIM_A26__DISP2_EXT_CLK 0x0c4 0x458 0x908 0x6 0x0
+#define MX51_PAD_EIM_A26__EIM_A26 0x0c4 0x458 0x000 0x0 0x0
+#define MX51_PAD_EIM_A26__GPIO2_20 0x0c4 0x458 0x000 0x1 0x0
+#define MX51_PAD_EIM_A26__USBH2_STP 0x0c4 0x458 0x000 0x2 0x0
+#define MX51_PAD_EIM_A27__CSI2_DATA_EN 0x0c8 0x45c 0x99c 0x5 0x0
+#define MX51_PAD_EIM_A27__DISP1_PIN1 0x0c8 0x45c 0x9a4 0x6 0x0
+#define MX51_PAD_EIM_A27__EIM_A27 0x0c8 0x45c 0x000 0x0 0x0
+#define MX51_PAD_EIM_A27__GPIO2_21 0x0c8 0x45c 0x000 0x1 0x0
+#define MX51_PAD_EIM_A27__USBH2_NXT 0x0c8 0x45c 0x000 0x2 0x0
+#define MX51_PAD_EIM_EB0__EIM_EB0 0x0cc 0x460 0x000 0x0 0x0
+#define MX51_PAD_EIM_EB1__EIM_EB1 0x0d0 0x464 0x000 0x0 0x0
+#define MX51_PAD_EIM_EB2__AUD5_RXFS 0x0d4 0x468 0x8e0 0x6 0x0
+#define MX51_PAD_EIM_EB2__CSI1_D2 0x0d4 0x468 0x000 0x5 0x0
+#define MX51_PAD_EIM_EB2__EIM_EB2 0x0d4 0x468 0x000 0x0 0x0
+#define MX51_PAD_EIM_EB2__FEC_MDIO 0x0d4 0x468 0x954 0x3 0x0
+#define MX51_PAD_EIM_EB2__GPIO2_22 0x0d4 0x468 0x000 0x1 0x0
+#define MX51_PAD_EIM_EB2__GPT_CMPOUT1 0x0d4 0x468 0x000 0x7 0x0
+#define MX51_PAD_EIM_EB3__AUD5_RXC 0x0d8 0x46c 0x8dc 0x6 0x0
+#define MX51_PAD_EIM_EB3__CSI1_D3 0x0d8 0x46c 0x000 0x5 0x0
+#define MX51_PAD_EIM_EB3__EIM_EB3 0x0d8 0x46c 0x000 0x0 0x0
+#define MX51_PAD_EIM_EB3__FEC_RDATA1 0x0d8 0x46c 0x95c 0x3 0x0
+#define MX51_PAD_EIM_EB3__GPIO2_23 0x0d8 0x46c 0x000 0x1 0x0
+#define MX51_PAD_EIM_EB3__GPT_CMPOUT2 0x0d8 0x46c 0x000 0x7 0x0
+#define MX51_PAD_EIM_OE__EIM_OE 0x0dc 0x470 0x000 0x0 0x0
+#define MX51_PAD_EIM_OE__GPIO2_24 0x0dc 0x470 0x000 0x1 0x0
+#define MX51_PAD_EIM_CS0__EIM_CS0 0x0e0 0x474 0x000 0x0 0x0
+#define MX51_PAD_EIM_CS0__GPIO2_25 0x0e0 0x474 0x000 0x1 0x0
+#define MX51_PAD_EIM_CS1__EIM_CS1 0x0e4 0x478 0x000 0x0 0x0
+#define MX51_PAD_EIM_CS1__GPIO2_26 0x0e4 0x478 0x000 0x1 0x0
+#define MX51_PAD_EIM_CS2__AUD5_TXD 0x0e8 0x47c 0x8d8 0x6 0x1
+#define MX51_PAD_EIM_CS2__CSI1_D4 0x0e8 0x47c 0x000 0x5 0x0
+#define MX51_PAD_EIM_CS2__EIM_CS2 0x0e8 0x47c 0x000 0x0 0x0
+#define MX51_PAD_EIM_CS2__FEC_RDATA2 0x0e8 0x47c 0x960 0x3 0x0
+#define MX51_PAD_EIM_CS2__GPIO2_27 0x0e8 0x47c 0x000 0x1 0x0
+#define MX51_PAD_EIM_CS2__USBOTG_STP 0x0e8 0x47c 0x000 0x2 0x0
+#define MX51_PAD_EIM_CS3__AUD5_RXD 0x0ec 0x480 0x8d4 0x6 0x1
+#define MX51_PAD_EIM_CS3__CSI1_D5 0x0ec 0x480 0x000 0x5 0x0
+#define MX51_PAD_EIM_CS3__EIM_CS3 0x0ec 0x480 0x000 0x0 0x0
+#define MX51_PAD_EIM_CS3__FEC_RDATA3 0x0ec 0x480 0x964 0x3 0x0
+#define MX51_PAD_EIM_CS3__GPIO2_28 0x0ec 0x480 0x000 0x1 0x0
+#define MX51_PAD_EIM_CS3__USBOTG_NXT 0x0ec 0x480 0x000 0x2 0x0
+#define MX51_PAD_EIM_CS4__AUD5_TXC 0x0f0 0x484 0x8e4 0x6 0x1
+#define MX51_PAD_EIM_CS4__CSI1_D6 0x0f0 0x484 0x000 0x5 0x0
+#define MX51_PAD_EIM_CS4__EIM_CS4 0x0f0 0x484 0x000 0x0 0x0
+#define MX51_PAD_EIM_CS4__FEC_RX_ER 0x0f0 0x484 0x970 0x3 0x0
+#define MX51_PAD_EIM_CS4__GPIO2_29 0x0f0 0x484 0x000 0x1 0x0
+#define MX51_PAD_EIM_CS4__USBOTG_CLK 0x0f0 0x484 0x000 0x2 0x0
+#define MX51_PAD_EIM_CS5__AUD5_TXFS 0x0f4 0x488 0x8e8 0x6 0x1
+#define MX51_PAD_EIM_CS5__CSI1_D7 0x0f4 0x488 0x000 0x5 0x0
+#define MX51_PAD_EIM_CS5__DISP1_EXT_CLK 0x0f4 0x488 0x904 0x4 0x0
+#define MX51_PAD_EIM_CS5__EIM_CS5 0x0f4 0x488 0x000 0x0 0x0
+#define MX51_PAD_EIM_CS5__FEC_CRS 0x0f4 0x488 0x950 0x3 0x0
+#define MX51_PAD_EIM_CS5__GPIO2_30 0x0f4 0x488 0x000 0x1 0x0
+#define MX51_PAD_EIM_CS5__USBOTG_DIR 0x0f4 0x488 0x000 0x2 0x0
+#define MX51_PAD_EIM_DTACK__EIM_DTACK 0x0f8 0x48c 0x000 0x0 0x0
+#define MX51_PAD_EIM_DTACK__GPIO2_31 0x0f8 0x48c 0x000 0x1 0x0
+#define MX51_PAD_EIM_LBA__EIM_LBA 0x0fc 0x494 0x000 0x0 0x0
+#define MX51_PAD_EIM_LBA__GPIO3_1 0x0fc 0x494 0x978 0x1 0x0
+#define MX51_PAD_EIM_CRE__EIM_CRE 0x100 0x4a0 0x000 0x0 0x0
+#define MX51_PAD_EIM_CRE__GPIO3_2 0x100 0x4a0 0x97c 0x1 0x0
+#define MX51_PAD_DRAM_CS1__DRAM_CS1 0x104 0x4d0 0x000 0x0 0x0
+#define MX51_PAD_NANDF_WE_B__GPIO3_3 0x108 0x4e4 0x980 0x3 0x0
+#define MX51_PAD_NANDF_WE_B__NANDF_WE_B 0x108 0x4e4 0x000 0x0 0x0
+#define MX51_PAD_NANDF_WE_B__PATA_DIOW 0x108 0x4e4 0x000 0x1 0x0
+#define MX51_PAD_NANDF_WE_B__SD3_DATA0 0x108 0x4e4 0x93c 0x2 0x0
+#define MX51_PAD_NANDF_RE_B__GPIO3_4 0x10c 0x4e8 0x984 0x3 0x0
+#define MX51_PAD_NANDF_RE_B__NANDF_RE_B 0x10c 0x4e8 0x000 0x0 0x0
+#define MX51_PAD_NANDF_RE_B__PATA_DIOR 0x10c 0x4e8 0x000 0x1 0x0
+#define MX51_PAD_NANDF_RE_B__SD3_DATA1 0x10c 0x4e8 0x940 0x2 0x0
+#define MX51_PAD_NANDF_ALE__GPIO3_5 0x110 0x4ec 0x988 0x3 0x0
+#define MX51_PAD_NANDF_ALE__NANDF_ALE 0x110 0x4ec 0x000 0x0 0x0
+#define MX51_PAD_NANDF_ALE__PATA_BUFFER_EN 0x110 0x4ec 0x000 0x1 0x0
+#define MX51_PAD_NANDF_CLE__GPIO3_6 0x114 0x4f0 0x98c 0x3 0x0
+#define MX51_PAD_NANDF_CLE__NANDF_CLE 0x114 0x4f0 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CLE__PATA_RESET_B 0x114 0x4f0 0x000 0x1 0x0
+#define MX51_PAD_NANDF_WP_B__GPIO3_7 0x118 0x4f4 0x990 0x3 0x0
+#define MX51_PAD_NANDF_WP_B__NANDF_WP_B 0x118 0x4f4 0x000 0x0 0x0
+#define MX51_PAD_NANDF_WP_B__PATA_DMACK 0x118 0x4f4 0x000 0x1 0x0
+#define MX51_PAD_NANDF_WP_B__SD3_DATA2 0x118 0x4f4 0x944 0x2 0x0
+#define MX51_PAD_NANDF_RB0__ECSPI2_SS1 0x11c 0x4f8 0x930 0x5 0x0
+#define MX51_PAD_NANDF_RB0__GPIO3_8 0x11c 0x4f8 0x994 0x3 0x0
+#define MX51_PAD_NANDF_RB0__NANDF_RB0 0x11c 0x4f8 0x000 0x0 0x0
+#define MX51_PAD_NANDF_RB0__PATA_DMARQ 0x11c 0x4f8 0x000 0x1 0x0
+#define MX51_PAD_NANDF_RB0__SD3_DATA3 0x11c 0x4f8 0x948 0x2 0x0
+#define MX51_PAD_NANDF_RB1__CSPI_MOSI 0x120 0x4fc 0x91c 0x6 0x0
+#define MX51_PAD_NANDF_RB1__ECSPI2_RDY 0x120 0x4fc 0x000 0x2 0x0
+#define MX51_PAD_NANDF_RB1__GPIO3_9 0x120 0x4fc 0x000 0x3 0x0
+#define MX51_PAD_NANDF_RB1__NANDF_RB1 0x120 0x4fc 0x000 0x0 0x0
+#define MX51_PAD_NANDF_RB1__PATA_IORDY 0x120 0x4fc 0x000 0x1 0x0
+#define MX51_PAD_NANDF_RB1__SD4_CMD 0x120 0x4fc 0x000 0x5 0x0
+#define MX51_PAD_NANDF_RB2__DISP2_WAIT 0x124 0x500 0x9a8 0x5 0x0
+#define MX51_PAD_NANDF_RB2__ECSPI2_SCLK 0x124 0x500 0x000 0x2 0x0
+#define MX51_PAD_NANDF_RB2__FEC_COL 0x124 0x500 0x94c 0x1 0x0
+#define MX51_PAD_NANDF_RB2__GPIO3_10 0x124 0x500 0x000 0x3 0x0
+#define MX51_PAD_NANDF_RB2__NANDF_RB2 0x124 0x500 0x000 0x0 0x0
+#define MX51_PAD_NANDF_RB2__USBH3_H3_DP 0x124 0x500 0x000 0x7 0x0
+#define MX51_PAD_NANDF_RB2__USBH3_NXT 0x124 0x500 0xa20 0x6 0x0
+#define MX51_PAD_NANDF_RB3__DISP1_WAIT 0x128 0x504 0x000 0x5 0x0
+#define MX51_PAD_NANDF_RB3__ECSPI2_MISO 0x128 0x504 0x000 0x2 0x0
+#define MX51_PAD_NANDF_RB3__FEC_RX_CLK 0x128 0x504 0x968 0x1 0x0
+#define MX51_PAD_NANDF_RB3__GPIO3_11 0x128 0x504 0x000 0x3 0x0
+#define MX51_PAD_NANDF_RB3__NANDF_RB3 0x128 0x504 0x000 0x0 0x0
+#define MX51_PAD_NANDF_RB3__USBH3_CLK 0x128 0x504 0x9f8 0x6 0x0
+#define MX51_PAD_NANDF_RB3__USBH3_H3_DM 0x128 0x504 0x000 0x7 0x0
+#define MX51_PAD_GPIO_NAND__GPIO_NAND 0x12c 0x514 0x998 0x0 0x0
+#define MX51_PAD_GPIO_NAND__PATA_INTRQ 0x12c 0x514 0x000 0x1 0x0
+#define MX51_PAD_NANDF_CS0__GPIO3_16 0x130 0x518 0x000 0x3 0x0
+#define MX51_PAD_NANDF_CS0__NANDF_CS0 0x130 0x518 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CS1__GPIO3_17 0x134 0x51c 0x000 0x3 0x0
+#define MX51_PAD_NANDF_CS1__NANDF_CS1 0x134 0x51c 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CS2__CSPI_SCLK 0x138 0x520 0x914 0x6 0x0
+#define MX51_PAD_NANDF_CS2__FEC_TX_ER 0x138 0x520 0x000 0x2 0x0
+#define MX51_PAD_NANDF_CS2__GPIO3_18 0x138 0x520 0x000 0x3 0x0
+#define MX51_PAD_NANDF_CS2__NANDF_CS2 0x138 0x520 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CS2__PATA_CS_0 0x138 0x520 0x000 0x1 0x0
+#define MX51_PAD_NANDF_CS2__SD4_CLK 0x138 0x520 0x000 0x5 0x0
+#define MX51_PAD_NANDF_CS2__USBH3_H1_DP 0x138 0x520 0x000 0x7 0x0
+#define MX51_PAD_NANDF_CS3__FEC_MDC 0x13c 0x524 0x000 0x2 0x0
+#define MX51_PAD_NANDF_CS3__GPIO3_19 0x13c 0x524 0x000 0x3 0x0
+#define MX51_PAD_NANDF_CS3__NANDF_CS3 0x13c 0x524 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CS3__PATA_CS_1 0x13c 0x524 0x000 0x1 0x0
+#define MX51_PAD_NANDF_CS3__SD4_DAT0 0x13c 0x524 0x000 0x5 0x0
+#define MX51_PAD_NANDF_CS3__USBH3_H1_DM 0x13c 0x524 0x000 0x7 0x0
+#define MX51_PAD_NANDF_CS4__FEC_TDATA1 0x140 0x528 0x000 0x2 0x0
+#define MX51_PAD_NANDF_CS4__GPIO3_20 0x140 0x528 0x000 0x3 0x0
+#define MX51_PAD_NANDF_CS4__NANDF_CS4 0x140 0x528 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CS4__PATA_DA_0 0x140 0x528 0x000 0x1 0x0
+#define MX51_PAD_NANDF_CS4__SD4_DAT1 0x140 0x528 0x000 0x5 0x0
+#define MX51_PAD_NANDF_CS4__USBH3_STP 0x140 0x528 0xa24 0x7 0x0
+#define MX51_PAD_NANDF_CS5__FEC_TDATA2 0x144 0x52c 0x000 0x2 0x0
+#define MX51_PAD_NANDF_CS5__GPIO3_21 0x144 0x52c 0x000 0x3 0x0
+#define MX51_PAD_NANDF_CS5__NANDF_CS5 0x144 0x52c 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CS5__PATA_DA_1 0x144 0x52c 0x000 0x1 0x0
+#define MX51_PAD_NANDF_CS5__SD4_DAT2 0x144 0x52c 0x000 0x5 0x0
+#define MX51_PAD_NANDF_CS5__USBH3_DIR 0x144 0x52c 0xa1c 0x7 0x0
+#define MX51_PAD_NANDF_CS6__CSPI_SS3 0x148 0x530 0x928 0x7 0x0
+#define MX51_PAD_NANDF_CS6__FEC_TDATA3 0x148 0x530 0x000 0x2 0x0
+#define MX51_PAD_NANDF_CS6__GPIO3_22 0x148 0x530 0x000 0x3 0x0
+#define MX51_PAD_NANDF_CS6__NANDF_CS6 0x148 0x530 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CS6__PATA_DA_2 0x148 0x530 0x000 0x1 0x0
+#define MX51_PAD_NANDF_CS6__SD4_DAT3 0x148 0x530 0x000 0x5 0x0
+#define MX51_PAD_NANDF_CS7__FEC_TX_EN 0x14c 0x534 0x000 0x1 0x0
+#define MX51_PAD_NANDF_CS7__GPIO3_23 0x14c 0x534 0x000 0x3 0x0
+#define MX51_PAD_NANDF_CS7__NANDF_CS7 0x14c 0x534 0x000 0x0 0x0
+#define MX51_PAD_NANDF_CS7__SD3_CLK 0x14c 0x534 0x000 0x5 0x0
+#define MX51_PAD_NANDF_RDY_INT__ECSPI2_SS0 0x150 0x538 0x000 0x2 0x0
+#define MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK 0x150 0x538 0x974 0x1 0x0
+#define MX51_PAD_NANDF_RDY_INT__GPIO3_24 0x150 0x538 0x000 0x3 0x0
+#define MX51_PAD_NANDF_RDY_INT__NANDF_RDY_INT 0x150 0x538 0x938 0x0 0x0
+#define MX51_PAD_NANDF_RDY_INT__SD3_CMD 0x150 0x538 0x000 0x5 0x0
+#define MX51_PAD_NANDF_D15__ECSPI2_MOSI 0x154 0x53c 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D15__GPIO3_25 0x154 0x53c 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D15__NANDF_D15 0x154 0x53c 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D15__PATA_DATA15 0x154 0x53c 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D15__SD3_DAT7 0x154 0x53c 0x000 0x5 0x0
+#define MX51_PAD_NANDF_D14__ECSPI2_SS3 0x158 0x540 0x934 0x2 0x0
+#define MX51_PAD_NANDF_D14__GPIO3_26 0x158 0x540 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D14__NANDF_D14 0x158 0x540 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D14__PATA_DATA14 0x158 0x540 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D14__SD3_DAT6 0x158 0x540 0x000 0x5 0x0
+#define MX51_PAD_NANDF_D13__ECSPI2_SS2 0x15c 0x544 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D13__GPIO3_27 0x15c 0x544 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D13__NANDF_D13 0x15c 0x544 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D13__PATA_DATA13 0x15c 0x544 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D13__SD3_DAT5 0x15c 0x544 0x000 0x5 0x0
+#define MX51_PAD_NANDF_D12__ECSPI2_SS1 0x160 0x548 0x930 0x2 0x1
+#define MX51_PAD_NANDF_D12__GPIO3_28 0x160 0x548 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D12__NANDF_D12 0x160 0x548 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D12__PATA_DATA12 0x160 0x548 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D12__SD3_DAT4 0x160 0x548 0x000 0x5 0x0
+#define MX51_PAD_NANDF_D11__FEC_RX_DV 0x164 0x54c 0x96c 0x2 0x0
+#define MX51_PAD_NANDF_D11__GPIO3_29 0x164 0x54c 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D11__NANDF_D11 0x164 0x54c 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D11__PATA_DATA11 0x164 0x54c 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D11__SD3_DATA3 0x164 0x54c 0x948 0x5 0x1
+#define MX51_PAD_NANDF_D10__GPIO3_30 0x168 0x550 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D10__NANDF_D10 0x168 0x550 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D10__PATA_DATA10 0x168 0x550 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D10__SD3_DATA2 0x168 0x550 0x944 0x5 0x1
+#define MX51_PAD_NANDF_D9__FEC_RDATA0 0x16c 0x554 0x958 0x2 0x0
+#define MX51_PAD_NANDF_D9__GPIO3_31 0x16c 0x554 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D9__NANDF_D9 0x16c 0x554 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D9__PATA_DATA9 0x16c 0x554 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D9__SD3_DATA1 0x16c 0x554 0x940 0x5 0x1
+#define MX51_PAD_NANDF_D8__FEC_TDATA0 0x170 0x558 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D8__GPIO4_0 0x170 0x558 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D8__NANDF_D8 0x170 0x558 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D8__PATA_DATA8 0x170 0x558 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D8__SD3_DATA0 0x170 0x558 0x93c 0x5 0x1
+#define MX51_PAD_NANDF_D7__GPIO4_1 0x174 0x55c 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D7__NANDF_D7 0x174 0x55c 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D7__PATA_DATA7 0x174 0x55c 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D7__USBH3_DATA0 0x174 0x55c 0x9fc 0x5 0x0
+#define MX51_PAD_NANDF_D6__GPIO4_2 0x178 0x560 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D6__NANDF_D6 0x178 0x560 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D6__PATA_DATA6 0x178 0x560 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D6__SD4_LCTL 0x178 0x560 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D6__USBH3_DATA1 0x178 0x560 0xa00 0x5 0x0
+#define MX51_PAD_NANDF_D5__GPIO4_3 0x17c 0x564 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D5__NANDF_D5 0x17c 0x564 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D5__PATA_DATA5 0x17c 0x564 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D5__SD4_WP 0x17c 0x564 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D5__USBH3_DATA2 0x17c 0x564 0xa04 0x5 0x0
+#define MX51_PAD_NANDF_D4__GPIO4_4 0x180 0x568 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D4__NANDF_D4 0x180 0x568 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D4__PATA_DATA4 0x180 0x568 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D4__SD4_CD 0x180 0x568 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D4__USBH3_DATA3 0x180 0x568 0xa08 0x5 0x0
+#define MX51_PAD_NANDF_D3__GPIO4_5 0x184 0x56c 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D3__NANDF_D3 0x184 0x56c 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D3__PATA_DATA3 0x184 0x56c 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D3__SD4_DAT4 0x184 0x56c 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D3__USBH3_DATA4 0x184 0x56c 0xa0c 0x5 0x0
+#define MX51_PAD_NANDF_D2__GPIO4_6 0x188 0x570 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D2__NANDF_D2 0x188 0x570 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D2__PATA_DATA2 0x188 0x570 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D2__SD4_DAT5 0x188 0x570 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D2__USBH3_DATA5 0x188 0x570 0xa10 0x5 0x0
+#define MX51_PAD_NANDF_D1__GPIO4_7 0x18c 0x574 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D1__NANDF_D1 0x18c 0x574 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D1__PATA_DATA1 0x18c 0x574 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D1__SD4_DAT6 0x18c 0x574 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D1__USBH3_DATA6 0x18c 0x574 0xa14 0x5 0x0
+#define MX51_PAD_NANDF_D0__GPIO4_8 0x190 0x578 0x000 0x3 0x0
+#define MX51_PAD_NANDF_D0__NANDF_D0 0x190 0x578 0x000 0x0 0x0
+#define MX51_PAD_NANDF_D0__PATA_DATA0 0x190 0x578 0x000 0x1 0x0
+#define MX51_PAD_NANDF_D0__SD4_DAT7 0x190 0x578 0x000 0x2 0x0
+#define MX51_PAD_NANDF_D0__USBH3_DATA7 0x190 0x578 0xa18 0x5 0x0
+#define MX51_PAD_CSI1_D8__CSI1_D8 0x194 0x57c 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D8__GPIO3_12 0x194 0x57c 0x998 0x3 0x1
+#define MX51_PAD_CSI1_D9__CSI1_D9 0x198 0x580 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D9__GPIO3_13 0x198 0x580 0x000 0x3 0x0
+#define MX51_PAD_CSI1_D10__CSI1_D10 0x19c 0x584 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D11__CSI1_D11 0x1a0 0x588 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D12__CSI1_D12 0x1a4 0x58c 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D13__CSI1_D13 0x1a8 0x590 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D14__CSI1_D14 0x1ac 0x594 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D15__CSI1_D15 0x1b0 0x598 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D16__CSI1_D16 0x1b4 0x59c 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D17__CSI1_D17 0x1b8 0x5a0 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D18__CSI1_D18 0x1bc 0x5a4 0x000 0x0 0x0
+#define MX51_PAD_CSI1_D19__CSI1_D19 0x1c0 0x5a8 0x000 0x0 0x0
+#define MX51_PAD_CSI1_VSYNC__CSI1_VSYNC 0x1c4 0x5ac 0x000 0x0 0x0
+#define MX51_PAD_CSI1_VSYNC__GPIO3_14 0x1c4 0x5ac 0x000 0x3 0x0
+#define MX51_PAD_CSI1_HSYNC__CSI1_HSYNC 0x1c8 0x5b0 0x000 0x0 0x0
+#define MX51_PAD_CSI1_HSYNC__GPIO3_15 0x1c8 0x5b0 0x000 0x3 0x0
+#define MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK 0x000 0x5b4 0x000 0x0 0x0
+#define MX51_PAD_CSI1_MCLK__CSI1_MCLK 0x000 0x5b8 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D12__CSI2_D12 0x1cc 0x5bc 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D12__GPIO4_9 0x1cc 0x5bc 0x000 0x3 0x0
+#define MX51_PAD_CSI2_D13__CSI2_D13 0x1d0 0x5c0 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D13__GPIO4_10 0x1d0 0x5c0 0x000 0x3 0x0
+#define MX51_PAD_CSI2_D14__CSI2_D14 0x1d4 0x5c4 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D15__CSI2_D15 0x1d8 0x5c8 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D16__CSI2_D16 0x1dc 0x5cc 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D17__CSI2_D17 0x1e0 0x5d0 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D18__CSI2_D18 0x1e4 0x5d4 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D18__GPIO4_11 0x1e4 0x5d4 0x000 0x3 0x0
+#define MX51_PAD_CSI2_D19__CSI2_D19 0x1e8 0x5d8 0x000 0x0 0x0
+#define MX51_PAD_CSI2_D19__GPIO4_12 0x1e8 0x5d8 0x000 0x3 0x0
+#define MX51_PAD_CSI2_VSYNC__CSI2_VSYNC 0x1ec 0x5dc 0x000 0x0 0x0
+#define MX51_PAD_CSI2_VSYNC__GPIO4_13 0x1ec 0x5dc 0x000 0x3 0x0
+#define MX51_PAD_CSI2_HSYNC__CSI2_HSYNC 0x1f0 0x5e0 0x000 0x0 0x0
+#define MX51_PAD_CSI2_HSYNC__GPIO4_14 0x1f0 0x5e0 0x000 0x3 0x0
+#define MX51_PAD_CSI2_PIXCLK__CSI2_PIXCLK 0x1f4 0x5e4 0x000 0x0 0x0
+#define MX51_PAD_CSI2_PIXCLK__GPIO4_15 0x1f4 0x5e4 0x000 0x3 0x0
+#define MX51_PAD_I2C1_CLK__GPIO4_16 0x1f8 0x5e8 0x000 0x3 0x0
+#define MX51_PAD_I2C1_CLK__I2C1_CLK 0x1f8 0x5e8 0x000 0x0 0x0
+#define MX51_PAD_I2C1_DAT__GPIO4_17 0x1fc 0x5ec 0x000 0x3 0x0
+#define MX51_PAD_I2C1_DAT__I2C1_DAT 0x1fc 0x5ec 0x000 0x0 0x0
+#define MX51_PAD_AUD3_BB_TXD__AUD3_TXD 0x200 0x5f0 0x000 0x0 0x0
+#define MX51_PAD_AUD3_BB_TXD__GPIO4_18 0x200 0x5f0 0x000 0x3 0x0
+#define MX51_PAD_AUD3_BB_RXD__AUD3_RXD 0x204 0x5f4 0x000 0x0 0x0
+#define MX51_PAD_AUD3_BB_RXD__GPIO4_19 0x204 0x5f4 0x000 0x3 0x0
+#define MX51_PAD_AUD3_BB_RXD__UART3_RXD 0x204 0x5f4 0x9f4 0x1 0x2
+#define MX51_PAD_AUD3_BB_CK__AUD3_TXC 0x208 0x5f8 0x000 0x0 0x0
+#define MX51_PAD_AUD3_BB_CK__GPIO4_20 0x208 0x5f8 0x000 0x3 0x0
+#define MX51_PAD_AUD3_BB_FS__AUD3_TXFS 0x20c 0x5fc 0x000 0x0 0x0
+#define MX51_PAD_AUD3_BB_FS__GPIO4_21 0x20c 0x5fc 0x000 0x3 0x0
+#define MX51_PAD_AUD3_BB_FS__UART3_TXD 0x20c 0x5fc 0x000 0x1 0x0
+#define MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI 0x210 0x600 0x000 0x0 0x0
+#define MX51_PAD_CSPI1_MOSI__GPIO4_22 0x210 0x600 0x000 0x3 0x0
+#define MX51_PAD_CSPI1_MOSI__I2C1_SDA 0x210 0x600 0x9b4 0x1 0x1
+#define MX51_PAD_CSPI1_MISO__AUD4_RXD 0x214 0x604 0x8c4 0x1 0x1
+#define MX51_PAD_CSPI1_MISO__ECSPI1_MISO 0x214 0x604 0x000 0x0 0x0
+#define MX51_PAD_CSPI1_MISO__GPIO4_23 0x214 0x604 0x000 0x3 0x0
+#define MX51_PAD_CSPI1_SS0__AUD4_TXC 0x218 0x608 0x8cc 0x1 0x1
+#define MX51_PAD_CSPI1_SS0__ECSPI1_SS0 0x218 0x608 0x000 0x0 0x0
+#define MX51_PAD_CSPI1_SS0__GPIO4_24 0x218 0x608 0x000 0x3 0x0
+#define MX51_PAD_CSPI1_SS1__AUD4_TXD 0x21c 0x60c 0x8c8 0x1 0x1
+#define MX51_PAD_CSPI1_SS1__ECSPI1_SS1 0x21c 0x60c 0x000 0x0 0x0
+#define MX51_PAD_CSPI1_SS1__GPIO4_25 0x21c 0x60c 0x000 0x3 0x0
+#define MX51_PAD_CSPI1_RDY__AUD4_TXFS 0x220 0x610 0x8d0 0x1 0x1
+#define MX51_PAD_CSPI1_RDY__ECSPI1_RDY 0x220 0x610 0x000 0x0 0x0
+#define MX51_PAD_CSPI1_RDY__GPIO4_26 0x220 0x610 0x000 0x3 0x0
+#define MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK 0x224 0x614 0x000 0x0 0x0
+#define MX51_PAD_CSPI1_SCLK__GPIO4_27 0x224 0x614 0x000 0x3 0x0
+#define MX51_PAD_CSPI1_SCLK__I2C1_SCL 0x224 0x614 0x9b0 0x1 0x1
+#define MX51_PAD_UART1_RXD__GPIO4_28 0x228 0x618 0x000 0x3 0x0
+#define MX51_PAD_UART1_RXD__UART1_RXD 0x228 0x618 0x9e4 0x0 0x0
+#define MX51_PAD_UART1_TXD__GPIO4_29 0x22c 0x61c 0x000 0x3 0x0
+#define MX51_PAD_UART1_TXD__PWM2_PWMO 0x22c 0x61c 0x000 0x1 0x0
+#define MX51_PAD_UART1_TXD__UART1_TXD 0x22c 0x61c 0x000 0x0 0x0
+#define MX51_PAD_UART1_RTS__GPIO4_30 0x230 0x620 0x000 0x3 0x0
+#define MX51_PAD_UART1_RTS__UART1_RTS 0x230 0x620 0x9e0 0x0 0x0
+#define MX51_PAD_UART1_CTS__GPIO4_31 0x234 0x624 0x000 0x3 0x0
+#define MX51_PAD_UART1_CTS__UART1_CTS 0x234 0x624 0x000 0x0 0x0
+#define MX51_PAD_UART2_RXD__FIRI_TXD 0x238 0x628 0x000 0x1 0x0
+#define MX51_PAD_UART2_RXD__GPIO1_20 0x238 0x628 0x000 0x3 0x0
+#define MX51_PAD_UART2_RXD__UART2_RXD 0x238 0x628 0x9ec 0x0 0x2
+#define MX51_PAD_UART2_TXD__FIRI_RXD 0x23c 0x62c 0x000 0x1 0x0
+#define MX51_PAD_UART2_TXD__GPIO1_21 0x23c 0x62c 0x000 0x3 0x0
+#define MX51_PAD_UART2_TXD__UART2_TXD 0x23c 0x62c 0x000 0x0 0x0
+#define MX51_PAD_UART3_RXD__CSI1_D0 0x240 0x630 0x000 0x2 0x0
+#define MX51_PAD_UART3_RXD__GPIO1_22 0x240 0x630 0x000 0x3 0x0
+#define MX51_PAD_UART3_RXD__UART1_DTR 0x240 0x630 0x000 0x0 0x0
+#define MX51_PAD_UART3_RXD__UART3_RXD 0x240 0x630 0x9f4 0x1 0x4
+#define MX51_PAD_UART3_TXD__CSI1_D1 0x244 0x634 0x000 0x2 0x0
+#define MX51_PAD_UART3_TXD__GPIO1_23 0x244 0x634 0x000 0x3 0x0
+#define MX51_PAD_UART3_TXD__UART1_DSR 0x244 0x634 0x000 0x0 0x0
+#define MX51_PAD_UART3_TXD__UART3_TXD 0x244 0x634 0x000 0x1 0x0
+#define MX51_PAD_OWIRE_LINE__GPIO1_24 0x248 0x638 0x000 0x3 0x0
+#define MX51_PAD_OWIRE_LINE__OWIRE_LINE 0x248 0x638 0x000 0x0 0x0
+#define MX51_PAD_OWIRE_LINE__SPDIF_OUT 0x248 0x638 0x000 0x6 0x0
+#define MX51_PAD_KEY_ROW0__KEY_ROW0 0x24c 0x63c 0x000 0x0 0x0
+#define MX51_PAD_KEY_ROW1__KEY_ROW1 0x250 0x640 0x000 0x0 0x0
+#define MX51_PAD_KEY_ROW2__KEY_ROW2 0x254 0x644 0x000 0x0 0x0
+#define MX51_PAD_KEY_ROW3__KEY_ROW3 0x258 0x648 0x000 0x0 0x0
+#define MX51_PAD_KEY_COL0__KEY_COL0 0x25c 0x64c 0x000 0x0 0x0
+#define MX51_PAD_KEY_COL0__PLL1_BYP 0x25c 0x64c 0x90c 0x7 0x0
+#define MX51_PAD_KEY_COL1__KEY_COL1 0x260 0x650 0x000 0x0 0x0
+#define MX51_PAD_KEY_COL1__PLL2_BYP 0x260 0x650 0x910 0x7 0x0
+#define MX51_PAD_KEY_COL2__KEY_COL2 0x264 0x654 0x000 0x0 0x0
+#define MX51_PAD_KEY_COL2__PLL3_BYP 0x264 0x654 0x000 0x7 0x0
+#define MX51_PAD_KEY_COL3__KEY_COL3 0x268 0x658 0x000 0x0 0x0
+#define MX51_PAD_KEY_COL4__I2C2_SCL 0x26c 0x65c 0x9b8 0x3 0x1
+#define MX51_PAD_KEY_COL4__KEY_COL4 0x26c 0x65c 0x000 0x0 0x0
+#define MX51_PAD_KEY_COL4__SPDIF_OUT1 0x26c 0x65c 0x000 0x6 0x0
+#define MX51_PAD_KEY_COL4__UART1_RI 0x26c 0x65c 0x000 0x1 0x0
+#define MX51_PAD_KEY_COL4__UART3_RTS 0x26c 0x65c 0x9f0 0x2 0x4
+#define MX51_PAD_KEY_COL5__I2C2_SDA 0x270 0x660 0x9bc 0x3 0x1
+#define MX51_PAD_KEY_COL5__KEY_COL5 0x270 0x660 0x000 0x0 0x0
+#define MX51_PAD_KEY_COL5__UART1_DCD 0x270 0x660 0x000 0x1 0x0
+#define MX51_PAD_KEY_COL5__UART3_CTS 0x270 0x660 0x000 0x2 0x0
+#define MX51_PAD_USBH1_CLK__CSPI_SCLK 0x278 0x678 0x914 0x1 0x1
+#define MX51_PAD_USBH1_CLK__GPIO1_25 0x278 0x678 0x000 0x2 0x0
+#define MX51_PAD_USBH1_CLK__I2C2_SCL 0x278 0x678 0x9b8 0x5 0x2
+#define MX51_PAD_USBH1_CLK__USBH1_CLK 0x278 0x678 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DIR__CSPI_MOSI 0x27c 0x67c 0x91c 0x1 0x1
+#define MX51_PAD_USBH1_DIR__GPIO1_26 0x27c 0x67c 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DIR__I2C2_SDA 0x27c 0x67c 0x9bc 0x5 0x2
+#define MX51_PAD_USBH1_DIR__USBH1_DIR 0x27c 0x67c 0x000 0x0 0x0
+#define MX51_PAD_USBH1_STP__CSPI_RDY 0x280 0x680 0x000 0x1 0x0
+#define MX51_PAD_USBH1_STP__GPIO1_27 0x280 0x680 0x000 0x2 0x0
+#define MX51_PAD_USBH1_STP__UART3_RXD 0x280 0x680 0x9f4 0x5 0x6
+#define MX51_PAD_USBH1_STP__USBH1_STP 0x280 0x680 0x000 0x0 0x0
+#define MX51_PAD_USBH1_NXT__CSPI_MISO 0x284 0x684 0x918 0x1 0x0
+#define MX51_PAD_USBH1_NXT__GPIO1_28 0x284 0x684 0x000 0x2 0x0
+#define MX51_PAD_USBH1_NXT__UART3_TXD 0x284 0x684 0x000 0x5 0x0
+#define MX51_PAD_USBH1_NXT__USBH1_NXT 0x284 0x684 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DATA0__GPIO1_11 0x288 0x688 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DATA0__UART2_CTS 0x288 0x688 0x000 0x1 0x0
+#define MX51_PAD_USBH1_DATA0__USBH1_DATA0 0x288 0x688 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DATA1__GPIO1_12 0x28c 0x68c 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DATA1__UART2_RXD 0x28c 0x68c 0x9ec 0x1 0x4
+#define MX51_PAD_USBH1_DATA1__USBH1_DATA1 0x28c 0x68c 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DATA2__GPIO1_13 0x290 0x690 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DATA2__UART2_TXD 0x290 0x690 0x000 0x1 0x0
+#define MX51_PAD_USBH1_DATA2__USBH1_DATA2 0x290 0x690 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DATA3__GPIO1_14 0x294 0x694 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DATA3__UART2_RTS 0x294 0x694 0x9e8 0x1 0x5
+#define MX51_PAD_USBH1_DATA3__USBH1_DATA3 0x294 0x694 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DATA4__CSPI_SS0 0x298 0x698 0x000 0x1 0x0
+#define MX51_PAD_USBH1_DATA4__GPIO1_15 0x298 0x698 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DATA4__USBH1_DATA4 0x298 0x698 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DATA5__CSPI_SS1 0x29c 0x69c 0x920 0x1 0x0
+#define MX51_PAD_USBH1_DATA5__GPIO1_16 0x29c 0x69c 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DATA5__USBH1_DATA5 0x29c 0x69c 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DATA6__CSPI_SS3 0x2a0 0x6a0 0x928 0x1 0x1
+#define MX51_PAD_USBH1_DATA6__GPIO1_17 0x2a0 0x6a0 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DATA6__USBH1_DATA6 0x2a0 0x6a0 0x000 0x0 0x0
+#define MX51_PAD_USBH1_DATA7__ECSPI1_SS3 0x2a4 0x6a4 0x000 0x1 0x0
+#define MX51_PAD_USBH1_DATA7__ECSPI2_SS3 0x2a4 0x6a4 0x934 0x5 0x1
+#define MX51_PAD_USBH1_DATA7__GPIO1_18 0x2a4 0x6a4 0x000 0x2 0x0
+#define MX51_PAD_USBH1_DATA7__USBH1_DATA7 0x2a4 0x6a4 0x000 0x0 0x0
+#define MX51_PAD_DI1_PIN11__DI1_PIN11 0x2a8 0x6a8 0x000 0x0 0x0
+#define MX51_PAD_DI1_PIN11__ECSPI1_SS2 0x2a8 0x6a8 0x000 0x7 0x0
+#define MX51_PAD_DI1_PIN11__GPIO3_0 0x2a8 0x6a8 0x000 0x4 0x0
+#define MX51_PAD_DI1_PIN12__DI1_PIN12 0x2ac 0x6ac 0x000 0x0 0x0
+#define MX51_PAD_DI1_PIN12__GPIO3_1 0x2ac 0x6ac 0x978 0x4 0x1
+#define MX51_PAD_DI1_PIN13__DI1_PIN13 0x2b0 0x6b0 0x000 0x0 0x0
+#define MX51_PAD_DI1_PIN13__GPIO3_2 0x2b0 0x6b0 0x97c 0x4 0x1
+#define MX51_PAD_DI1_D0_CS__DI1_D0_CS 0x2b4 0x6b4 0x000 0x0 0x0
+#define MX51_PAD_DI1_D0_CS__GPIO3_3 0x2b4 0x6b4 0x980 0x4 0x1
+#define MX51_PAD_DI1_D1_CS__DI1_D1_CS 0x2b8 0x6b8 0x000 0x0 0x0
+#define MX51_PAD_DI1_D1_CS__DISP1_PIN14 0x2b8 0x6b8 0x000 0x2 0x0
+#define MX51_PAD_DI1_D1_CS__DISP1_PIN5 0x2b8 0x6b8 0x000 0x3 0x0
+#define MX51_PAD_DI1_D1_CS__GPIO3_4 0x2b8 0x6b8 0x984 0x4 0x1
+#define MX51_PAD_DISPB2_SER_DIN__DISP1_PIN1 0x2bc 0x6bc 0x9a4 0x2 0x1
+#define MX51_PAD_DISPB2_SER_DIN__DISPB2_SER_DIN 0x2bc 0x6bc 0x9c4 0x0 0x0
+#define MX51_PAD_DISPB2_SER_DIN__GPIO3_5 0x2bc 0x6bc 0x988 0x4 0x1
+#define MX51_PAD_DISPB2_SER_DIO__DISP1_PIN6 0x2c0 0x6c0 0x000 0x3 0x0
+#define MX51_PAD_DISPB2_SER_DIO__DISPB2_SER_DIO 0x2c0 0x6c0 0x9c4 0x0 0x1
+#define MX51_PAD_DISPB2_SER_DIO__GPIO3_6 0x2c0 0x6c0 0x98c 0x4 0x1
+#define MX51_PAD_DISPB2_SER_CLK__DISP1_PIN17 0x2c4 0x6c4 0x000 0x2 0x0
+#define MX51_PAD_DISPB2_SER_CLK__DISP1_PIN7 0x2c4 0x6c4 0x000 0x3 0x0
+#define MX51_PAD_DISPB2_SER_CLK__DISPB2_SER_CLK 0x2c4 0x6c4 0x000 0x0 0x0
+#define MX51_PAD_DISPB2_SER_CLK__GPIO3_7 0x2c4 0x6c4 0x990 0x4 0x1
+#define MX51_PAD_DISPB2_SER_RS__DISP1_EXT_CLK 0x2c8 0x6c8 0x000 0x2 0x0
+#define MX51_PAD_DISPB2_SER_RS__DISP1_PIN16 0x2c8 0x6c8 0x000 0x2 0x0
+#define MX51_PAD_DISPB2_SER_RS__DISP1_PIN8 0x2c8 0x6c8 0x000 0x3 0x0
+#define MX51_PAD_DISPB2_SER_RS__DISPB2_SER_RS 0x2c8 0x6c8 0x000 0x0 0x0
+#define MX51_PAD_DISPB2_SER_RS__GPIO3_8 0x2c8 0x6c8 0x994 0x4 0x1
+#define MX51_PAD_DISP1_DAT0__DISP1_DAT0 0x2cc 0x6cc 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT1__DISP1_DAT1 0x2d0 0x6d0 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT2__DISP1_DAT2 0x2d4 0x6d4 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT3__DISP1_DAT3 0x2d8 0x6d8 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT4__DISP1_DAT4 0x2dc 0x6dc 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT5__DISP1_DAT5 0x2e0 0x6e0 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT6__BOOT_USB_SRC 0x2e4 0x6e4 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT6__DISP1_DAT6 0x2e4 0x6e4 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT7__BOOT_EEPROM_CFG 0x2e8 0x6e8 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT7__DISP1_DAT7 0x2e8 0x6e8 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT8__BOOT_SRC0 0x2ec 0x6ec 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT8__DISP1_DAT8 0x2ec 0x6ec 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT9__BOOT_SRC1 0x2f0 0x6f0 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT9__DISP1_DAT9 0x2f0 0x6f0 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT10__BOOT_SPARE_SIZE 0x2f4 0x6f4 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT10__DISP1_DAT10 0x2f4 0x6f4 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT11__BOOT_LPB_FREQ2 0x2f8 0x6f8 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT11__DISP1_DAT11 0x2f8 0x6f8 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT12__BOOT_MLC_SEL 0x2fc 0x6fc 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT12__DISP1_DAT12 0x2fc 0x6fc 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT13__BOOT_MEM_CTL0 0x300 0x700 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT13__DISP1_DAT13 0x300 0x700 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT14__BOOT_MEM_CTL1 0x304 0x704 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT14__DISP1_DAT14 0x304 0x704 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT15__BOOT_BUS_WIDTH 0x308 0x708 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT15__DISP1_DAT15 0x308 0x708 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT16__BOOT_PAGE_SIZE0 0x30c 0x70c 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT16__DISP1_DAT16 0x30c 0x70c 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT17__BOOT_PAGE_SIZE1 0x310 0x710 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT17__DISP1_DAT17 0x310 0x710 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT18__BOOT_WEIM_MUXED0 0x314 0x714 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT18__DISP1_DAT18 0x314 0x714 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT18__DISP2_PIN11 0x314 0x714 0x000 0x5 0x0
+#define MX51_PAD_DISP1_DAT18__DISP2_PIN5 0x314 0x714 0x000 0x4 0x0
+#define MX51_PAD_DISP1_DAT19__BOOT_WEIM_MUXED1 0x318 0x718 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT19__DISP1_DAT19 0x318 0x718 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT19__DISP2_PIN12 0x318 0x718 0x000 0x5 0x0
+#define MX51_PAD_DISP1_DAT19__DISP2_PIN6 0x318 0x718 0x000 0x4 0x0
+#define MX51_PAD_DISP1_DAT20__BOOT_MEM_TYPE0 0x31c 0x71c 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT20__DISP1_DAT20 0x31c 0x71c 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT20__DISP2_PIN13 0x31c 0x71c 0x000 0x5 0x0
+#define MX51_PAD_DISP1_DAT20__DISP2_PIN7 0x31c 0x71c 0x000 0x4 0x0
+#define MX51_PAD_DISP1_DAT21__BOOT_MEM_TYPE1 0x320 0x720 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT21__DISP1_DAT21 0x320 0x720 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT21__DISP2_PIN14 0x320 0x720 0x000 0x5 0x0
+#define MX51_PAD_DISP1_DAT21__DISP2_PIN8 0x320 0x720 0x000 0x4 0x0
+#define MX51_PAD_DISP1_DAT22__BOOT_LPB_FREQ0 0x324 0x724 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT22__DISP1_DAT22 0x324 0x724 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT22__DISP2_D0_CS 0x324 0x724 0x000 0x6 0x0
+#define MX51_PAD_DISP1_DAT22__DISP2_DAT16 0x324 0x724 0x000 0x5 0x0
+#define MX51_PAD_DISP1_DAT23__BOOT_LPB_FREQ1 0x328 0x728 0x000 0x7 0x0
+#define MX51_PAD_DISP1_DAT23__DISP1_DAT23 0x328 0x728 0x000 0x0 0x0
+#define MX51_PAD_DISP1_DAT23__DISP2_D1_CS 0x328 0x728 0x000 0x6 0x0
+#define MX51_PAD_DISP1_DAT23__DISP2_DAT17 0x328 0x728 0x000 0x5 0x0
+#define MX51_PAD_DISP1_DAT23__DISP2_SER_CS 0x328 0x728 0x000 0x4 0x0
+#define MX51_PAD_DI1_PIN3__DI1_PIN3 0x32c 0x72c 0x000 0x0 0x0
+#define MX51_PAD_DI1_PIN2__DI1_PIN2 0x330 0x734 0x000 0x0 0x0
+#define MX51_PAD_DI_GP2__DISP1_SER_CLK 0x338 0x740 0x000 0x0 0x0
+#define MX51_PAD_DI_GP2__DISP2_WAIT 0x338 0x740 0x9a8 0x2 0x1
+#define MX51_PAD_DI_GP3__CSI1_DATA_EN 0x33c 0x744 0x9a0 0x3 0x1
+#define MX51_PAD_DI_GP3__DISP1_SER_DIO 0x33c 0x744 0x9c0 0x0 0x0
+#define MX51_PAD_DI_GP3__FEC_TX_ER 0x33c 0x744 0x000 0x2 0x0
+#define MX51_PAD_DI2_PIN4__CSI2_DATA_EN 0x340 0x748 0x99c 0x3 0x1
+#define MX51_PAD_DI2_PIN4__DI2_PIN4 0x340 0x748 0x000 0x0 0x0
+#define MX51_PAD_DI2_PIN4__FEC_CRS 0x340 0x748 0x950 0x2 0x1
+#define MX51_PAD_DI2_PIN2__DI2_PIN2 0x344 0x74c 0x000 0x0 0x0
+#define MX51_PAD_DI2_PIN2__FEC_MDC 0x344 0x74c 0x000 0x2 0x0
+#define MX51_PAD_DI2_PIN3__DI2_PIN3 0x348 0x750 0x000 0x0 0x0
+#define MX51_PAD_DI2_PIN3__FEC_MDIO 0x348 0x750 0x954 0x2 0x1
+#define MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK 0x34c 0x754 0x000 0x0 0x0
+#define MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 0x34c 0x754 0x95c 0x2 0x1
+#define MX51_PAD_DI_GP4__DI2_PIN15 0x350 0x758 0x000 0x4 0x0
+#define MX51_PAD_DI_GP4__DISP1_SER_DIN 0x350 0x758 0x9c0 0x0 0x1
+#define MX51_PAD_DI_GP4__DISP2_PIN1 0x350 0x758 0x000 0x3 0x0
+#define MX51_PAD_DI_GP4__FEC_RDATA2 0x350 0x758 0x960 0x2 0x1
+#define MX51_PAD_DISP2_DAT0__DISP2_DAT0 0x354 0x75c 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT0__FEC_RDATA3 0x354 0x75c 0x964 0x2 0x1
+#define MX51_PAD_DISP2_DAT0__KEY_COL6 0x354 0x75c 0x9c8 0x4 0x1
+#define MX51_PAD_DISP2_DAT0__UART3_RXD 0x354 0x75c 0x9f4 0x5 0x8
+#define MX51_PAD_DISP2_DAT0__USBH3_CLK 0x354 0x75c 0x9f8 0x3 0x1
+#define MX51_PAD_DISP2_DAT1__DISP2_DAT1 0x358 0x760 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT1__FEC_RX_ER 0x358 0x760 0x970 0x2 0x1
+#define MX51_PAD_DISP2_DAT1__KEY_COL7 0x358 0x760 0x9cc 0x4 0x1
+#define MX51_PAD_DISP2_DAT1__UART3_TXD 0x358 0x760 0x000 0x5 0x0
+#define MX51_PAD_DISP2_DAT1__USBH3_DIR 0x358 0x760 0xa1c 0x3 0x1
+#define MX51_PAD_DISP2_DAT2__DISP2_DAT2 0x35c 0x764 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT3__DISP2_DAT3 0x360 0x768 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT4__DISP2_DAT4 0x364 0x76c 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT5__DISP2_DAT5 0x368 0x770 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT6__DISP2_DAT6 0x36c 0x774 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT6__FEC_TDATA1 0x36c 0x774 0x000 0x2 0x0
+#define MX51_PAD_DISP2_DAT6__GPIO1_19 0x36c 0x774 0x000 0x5 0x0
+#define MX51_PAD_DISP2_DAT6__KEY_ROW4 0x36c 0x774 0x9d0 0x4 0x1
+#define MX51_PAD_DISP2_DAT6__USBH3_STP 0x36c 0x774 0xa24 0x3 0x1
+#define MX51_PAD_DISP2_DAT7__DISP2_DAT7 0x370 0x778 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT7__FEC_TDATA2 0x370 0x778 0x000 0x2 0x0
+#define MX51_PAD_DISP2_DAT7__GPIO1_29 0x370 0x778 0x000 0x5 0x0
+#define MX51_PAD_DISP2_DAT7__KEY_ROW5 0x370 0x778 0x9d4 0x4 0x1
+#define MX51_PAD_DISP2_DAT7__USBH3_NXT 0x370 0x778 0xa20 0x3 0x1
+#define MX51_PAD_DISP2_DAT8__DISP2_DAT8 0x374 0x77c 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT8__FEC_TDATA3 0x374 0x77c 0x000 0x2 0x0
+#define MX51_PAD_DISP2_DAT8__GPIO1_30 0x374 0x77c 0x000 0x5 0x0
+#define MX51_PAD_DISP2_DAT8__KEY_ROW6 0x374 0x77c 0x9d8 0x4 0x1
+#define MX51_PAD_DISP2_DAT8__USBH3_DATA0 0x374 0x77c 0x9fc 0x3 0x1
+#define MX51_PAD_DISP2_DAT9__AUD6_RXC 0x378 0x780 0x8f4 0x4 0x1
+#define MX51_PAD_DISP2_DAT9__DISP2_DAT9 0x378 0x780 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT9__FEC_TX_EN 0x378 0x780 0x000 0x2 0x0
+#define MX51_PAD_DISP2_DAT9__GPIO1_31 0x378 0x780 0x000 0x5 0x0
+#define MX51_PAD_DISP2_DAT9__USBH3_DATA1 0x378 0x780 0xa00 0x3 0x1
+#define MX51_PAD_DISP2_DAT10__DISP2_DAT10 0x37c 0x784 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT10__DISP2_SER_CS 0x37c 0x784 0x000 0x5 0x0
+#define MX51_PAD_DISP2_DAT10__FEC_COL 0x37c 0x784 0x94c 0x2 0x1
+#define MX51_PAD_DISP2_DAT10__KEY_ROW7 0x37c 0x784 0x9dc 0x4 0x1
+#define MX51_PAD_DISP2_DAT10__USBH3_DATA2 0x37c 0x784 0xa04 0x3 0x1
+#define MX51_PAD_DISP2_DAT11__AUD6_TXD 0x380 0x788 0x8f0 0x4 0x1
+#define MX51_PAD_DISP2_DAT11__DISP2_DAT11 0x380 0x788 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT11__FEC_RX_CLK 0x380 0x788 0x968 0x2 0x1
+#define MX51_PAD_DISP2_DAT11__GPIO1_10 0x380 0x788 0x000 0x7 0x0
+#define MX51_PAD_DISP2_DAT11__USBH3_DATA3 0x380 0x788 0xa08 0x3 0x1
+#define MX51_PAD_DISP2_DAT12__AUD6_RXD 0x384 0x78c 0x8ec 0x4 0x1
+#define MX51_PAD_DISP2_DAT12__DISP2_DAT12 0x384 0x78c 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT12__FEC_RX_DV 0x384 0x78c 0x96c 0x2 0x1
+#define MX51_PAD_DISP2_DAT12__USBH3_DATA4 0x384 0x78c 0xa0c 0x3 0x1
+#define MX51_PAD_DISP2_DAT13__AUD6_TXC 0x388 0x790 0x8fc 0x4 0x1
+#define MX51_PAD_DISP2_DAT13__DISP2_DAT13 0x388 0x790 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT13__FEC_TX_CLK 0x388 0x790 0x974 0x2 0x1
+#define MX51_PAD_DISP2_DAT13__USBH3_DATA5 0x388 0x790 0xa10 0x3 0x1
+#define MX51_PAD_DISP2_DAT14__AUD6_TXFS 0x38c 0x794 0x900 0x4 0x1
+#define MX51_PAD_DISP2_DAT14__DISP2_DAT14 0x38c 0x794 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT14__FEC_RDATA0 0x38c 0x794 0x958 0x2 0x1
+#define MX51_PAD_DISP2_DAT14__USBH3_DATA6 0x38c 0x794 0xa14 0x3 0x1
+#define MX51_PAD_DISP2_DAT15__AUD6_RXFS 0x390 0x798 0x8f8 0x4 0x1
+#define MX51_PAD_DISP2_DAT15__DISP1_SER_CS 0x390 0x798 0x000 0x5 0x0
+#define MX51_PAD_DISP2_DAT15__DISP2_DAT15 0x390 0x798 0x000 0x0 0x0
+#define MX51_PAD_DISP2_DAT15__FEC_TDATA0 0x390 0x798 0x000 0x2 0x0
+#define MX51_PAD_DISP2_DAT15__USBH3_DATA7 0x390 0x798 0xa18 0x3 0x1
+#define MX51_PAD_SD1_CMD__AUD5_RXFS 0x394 0x79c 0x8e0 0x1 0x1
+#define MX51_PAD_SD1_CMD__CSPI_MOSI 0x394 0x79c 0x91c 0x2 0x2
+#define MX51_PAD_SD1_CMD__SD1_CMD 0x394 0x79c 0x000 0x0 0x0
+#define MX51_PAD_SD1_CLK__AUD5_RXC 0x398 0x7a0 0x8dc 0x1 0x1
+#define MX51_PAD_SD1_CLK__CSPI_SCLK 0x398 0x7a0 0x914 0x2 0x2
+#define MX51_PAD_SD1_CLK__SD1_CLK 0x398 0x7a0 0x000 0x0 0x0
+#define MX51_PAD_SD1_DATA0__AUD5_TXD 0x39c 0x7a4 0x8d8 0x1 0x2
+#define MX51_PAD_SD1_DATA0__CSPI_MISO 0x39c 0x7a4 0x918 0x2 0x1
+#define MX51_PAD_SD1_DATA0__SD1_DATA0 0x39c 0x7a4 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA0__EIM_DA0 0x01c 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA1__EIM_DA1 0x020 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA2__EIM_DA2 0x024 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA3__EIM_DA3 0x028 0x000 0x000 0x0 0x0
+#define MX51_PAD_SD1_DATA1__AUD5_RXD 0x3a0 0x7a8 0x8d4 0x1 0x2
+#define MX51_PAD_SD1_DATA1__SD1_DATA1 0x3a0 0x7a8 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA4__EIM_DA4 0x02c 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA5__EIM_DA5 0x030 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA6__EIM_DA6 0x034 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA7__EIM_DA7 0x038 0x000 0x000 0x0 0x0
+#define MX51_PAD_SD1_DATA2__AUD5_TXC 0x3a4 0x7ac 0x8e4 0x1 0x2
+#define MX51_PAD_SD1_DATA2__SD1_DATA2 0x3a4 0x7ac 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA10__EIM_DA10 0x044 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA11__EIM_DA11 0x048 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA8__EIM_DA8 0x03c 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA9__EIM_DA9 0x040 0x000 0x000 0x0 0x0
+#define MX51_PAD_SD1_DATA3__AUD5_TXFS 0x3a8 0x7b0 0x8e8 0x1 0x2
+#define MX51_PAD_SD1_DATA3__CSPI_SS1 0x3a8 0x7b0 0x920 0x2 0x1
+#define MX51_PAD_SD1_DATA3__SD1_DATA3 0x3a8 0x7b0 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_0__CSPI_SS2 0x3ac 0x7b4 0x924 0x2 0x0
+#define MX51_PAD_GPIO1_0__GPIO1_0 0x3ac 0x7b4 0x000 0x1 0x0
+#define MX51_PAD_GPIO1_0__SD1_CD 0x3ac 0x7b4 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_1__CSPI_MISO 0x3b0 0x7b8 0x918 0x2 0x2
+#define MX51_PAD_GPIO1_1__GPIO1_1 0x3b0 0x7b8 0x000 0x1 0x0
+#define MX51_PAD_GPIO1_1__SD1_WP 0x3b0 0x7b8 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA12__EIM_DA12 0x04c 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA13__EIM_DA13 0x050 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA14__EIM_DA14 0x054 0x000 0x000 0x0 0x0
+#define MX51_PAD_EIM_DA15__EIM_DA15 0x058 0x000 0x000 0x0 0x0
+#define MX51_PAD_SD2_CMD__CSPI_MOSI 0x3b4 0x7bc 0x91c 0x2 0x3
+#define MX51_PAD_SD2_CMD__I2C1_SCL 0x3b4 0x7bc 0x9b0 0x1 0x2
+#define MX51_PAD_SD2_CMD__SD2_CMD 0x3b4 0x7bc 0x000 0x0 0x0
+#define MX51_PAD_SD2_CLK__CSPI_SCLK 0x3b8 0x7c0 0x914 0x2 0x3
+#define MX51_PAD_SD2_CLK__I2C1_SDA 0x3b8 0x7c0 0x9b4 0x1 0x2
+#define MX51_PAD_SD2_CLK__SD2_CLK 0x3b8 0x7c0 0x000 0x0 0x0
+#define MX51_PAD_SD2_DATA0__CSPI_MISO 0x3bc 0x7c4 0x918 0x2 0x3
+#define MX51_PAD_SD2_DATA0__SD1_DAT4 0x3bc 0x7c4 0x000 0x1 0x0
+#define MX51_PAD_SD2_DATA0__SD2_DATA0 0x3bc 0x7c4 0x000 0x0 0x0
+#define MX51_PAD_SD2_DATA1__SD1_DAT5 0x3c0 0x7c8 0x000 0x1 0x0
+#define MX51_PAD_SD2_DATA1__SD2_DATA1 0x3c0 0x7c8 0x000 0x0 0x0
+#define MX51_PAD_SD2_DATA1__USBH3_H2_DP 0x3c0 0x7c8 0x000 0x2 0x0
+#define MX51_PAD_SD2_DATA2__SD1_DAT6 0x3c4 0x7cc 0x000 0x1 0x0
+#define MX51_PAD_SD2_DATA2__SD2_DATA2 0x3c4 0x7cc 0x000 0x0 0x0
+#define MX51_PAD_SD2_DATA2__USBH3_H2_DM 0x3c4 0x7cc 0x000 0x2 0x0
+#define MX51_PAD_SD2_DATA3__CSPI_SS2 0x3c8 0x7d0 0x924 0x2 0x1
+#define MX51_PAD_SD2_DATA3__SD1_DAT7 0x3c8 0x7d0 0x000 0x1 0x0
+#define MX51_PAD_SD2_DATA3__SD2_DATA3 0x3c8 0x7d0 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_2__CCM_OUT_2 0x3cc 0x7d4 0x000 0x5 0x0
+#define MX51_PAD_GPIO1_2__GPIO1_2 0x3cc 0x7d4 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_2__I2C2_SCL 0x3cc 0x7d4 0x9b8 0x2 0x3
+#define MX51_PAD_GPIO1_2__PLL1_BYP 0x3cc 0x7d4 0x90c 0x7 0x1
+#define MX51_PAD_GPIO1_2__PWM1_PWMO 0x3cc 0x7d4 0x000 0x1 0x0
+#define MX51_PAD_GPIO1_3__GPIO1_3 0x3d0 0x7d8 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_3__I2C2_SDA 0x3d0 0x7d8 0x9bc 0x2 0x3
+#define MX51_PAD_GPIO1_3__PLL2_BYP 0x3d0 0x7d8 0x910 0x7 0x1
+#define MX51_PAD_GPIO1_3__PWM2_PWMO 0x3d0 0x7d8 0x000 0x1 0x0
+#define MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ 0x3d4 0x7fc 0x000 0x0 0x0
+#define MX51_PAD_PMIC_INT_REQ__PMIC_PMU_IRQ_B 0x3d4 0x7fc 0x000 0x1 0x0
+#define MX51_PAD_GPIO1_4__DISP2_EXT_CLK 0x3d8 0x804 0x908 0x4 0x1
+#define MX51_PAD_GPIO1_4__EIM_RDY 0x3d8 0x804 0x938 0x3 0x1
+#define MX51_PAD_GPIO1_4__GPIO1_4 0x3d8 0x804 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_4__WDOG1_WDOG_B 0x3d8 0x804 0x000 0x2 0x0
+#define MX51_PAD_GPIO1_5__CSI2_MCLK 0x3dc 0x808 0x000 0x6 0x0
+#define MX51_PAD_GPIO1_5__DISP2_PIN16 0x3dc 0x808 0x000 0x3 0x0
+#define MX51_PAD_GPIO1_5__GPIO1_5 0x3dc 0x808 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_5__WDOG2_WDOG_B 0x3dc 0x808 0x000 0x2 0x0
+#define MX51_PAD_GPIO1_6__DISP2_PIN17 0x3e0 0x80c 0x000 0x4 0x0
+#define MX51_PAD_GPIO1_6__GPIO1_6 0x3e0 0x80c 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_6__REF_EN_B 0x3e0 0x80c 0x000 0x3 0x0
+#define MX51_PAD_GPIO1_7__CCM_OUT_0 0x3e4 0x810 0x000 0x3 0x0
+#define MX51_PAD_GPIO1_7__GPIO1_7 0x3e4 0x810 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_7__SD2_WP 0x3e4 0x810 0x000 0x6 0x0
+#define MX51_PAD_GPIO1_7__SPDIF_OUT1 0x3e4 0x810 0x000 0x2 0x0
+#define MX51_PAD_GPIO1_8__CSI2_DATA_EN 0x3e8 0x814 0x99c 0x2 0x2
+#define MX51_PAD_GPIO1_8__GPIO1_8 0x3e8 0x814 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_8__SD2_CD 0x3e8 0x814 0x000 0x6 0x0
+#define MX51_PAD_GPIO1_8__USBH3_PWR 0x3e8 0x814 0x000 0x1 0x0
+#define MX51_PAD_GPIO1_9__CCM_OUT_1 0x3ec 0x818 0x000 0x3 0x0
+#define MX51_PAD_GPIO1_9__DISP2_D1_CS 0x3ec 0x818 0x000 0x2 0x0
+#define MX51_PAD_GPIO1_9__DISP2_SER_CS 0x3ec 0x818 0x000 0x7 0x0
+#define MX51_PAD_GPIO1_9__GPIO1_9 0x3ec 0x818 0x000 0x0 0x0
+#define MX51_PAD_GPIO1_9__SD2_LCTL 0x3ec 0x818 0x000 0x6 0x0
+#define MX51_PAD_GPIO1_9__USBH3_OC 0x3ec 0x818 0x000 0x1 0x0
+
+#endif /* __DTS_IMX51_PINFUNC_H */
diff --git a/arch/arm/dts/imx51.dtsi b/arch/arm/dts/imx51.dtsi
new file mode 100644
index 0000000000..a9002878ba
--- /dev/null
+++ b/arch/arm/dts/imx51.dtsi
@@ -0,0 +1,723 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 "skeleton.dtsi"
+#include "imx51-pinfunc.h"
+
+/ {
+ aliases {
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ mmc0 = &esdhc1;
+ mmc1 = &esdhc2;
+ mmc2 = &esdhc3;
+ mmc3 = &esdhc4;
+ };
+
+ tzic: tz-interrupt-controller@e0000000 {
+ compatible = "fsl,imx51-tzic", "fsl,tzic";
+ interrupt-controller;
+ #interrupt-cells = <1>;
+ reg = <0xe0000000 0x4000>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ckil {
+ compatible = "fsl,imx-ckil", "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ ckih1 {
+ compatible = "fsl,imx-ckih1", "fixed-clock";
+ clock-frequency = <22579200>;
+ };
+
+ ckih2 {
+ compatible = "fsl,imx-ckih2", "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ osc {
+ compatible = "fsl,imx-osc", "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ cpu@0 {
+ device_type = "cpu";
+ compatible = "arm,cortex-a8";
+ reg = <0>;
+ clock-latency = <61036>; /* two CLK32 periods */
+ clocks = <&clks 24>;
+ clock-names = "cpu";
+ operating-points = <
+ /* kHz uV (No regulator support) */
+ 160000 0
+ 800000 0
+ >;
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&tzic>;
+ ranges;
+
+ ipu: ipu@40000000 {
+ #crtc-cells = <1>;
+ compatible = "fsl,imx51-ipu";
+ reg = <0x40000000 0x20000000>;
+ interrupts = <11 10>;
+ clocks = <&clks 59>, <&clks 110>, <&clks 61>;
+ clock-names = "bus", "di0", "di1";
+ resets = <&src 2>;
+ };
+
+ aips@70000000 { /* AIPS1 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x70000000 0x10000000>;
+ ranges;
+
+ spba@70000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x70000000 0x40000>;
+ ranges;
+
+ esdhc1: esdhc@70004000 {
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70004000 0x4000>;
+ interrupts = <1>;
+ clocks = <&clks 44>, <&clks 0>, <&clks 71>;
+ clock-names = "ipg", "ahb", "per";
+ status = "disabled";
+ };
+
+ esdhc2: esdhc@70008000 {
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70008000 0x4000>;
+ interrupts = <2>;
+ clocks = <&clks 45>, <&clks 0>, <&clks 72>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ uart3: serial@7000c000 {
+ compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+ reg = <0x7000c000 0x4000>;
+ interrupts = <33>;
+ clocks = <&clks 32>, <&clks 33>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi1: ecspi@70010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-ecspi";
+ reg = <0x70010000 0x4000>;
+ interrupts = <36>;
+ clocks = <&clks 51>, <&clks 52>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ssi2: ssi@70014000 {
+ compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
+ reg = <0x70014000 0x4000>;
+ interrupts = <30>;
+ clocks = <&clks 49>;
+ fsl,fifo-depth = <15>;
+ fsl,ssi-dma-events = <25 24 23 22>; /* TX0 RX0 TX1 RX1 */
+ status = "disabled";
+ };
+
+ esdhc3: esdhc@70020000 {
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70020000 0x4000>;
+ interrupts = <3>;
+ clocks = <&clks 46>, <&clks 0>, <&clks 73>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ esdhc4: esdhc@70024000 {
+ compatible = "fsl,imx51-esdhc";
+ reg = <0x70024000 0x4000>;
+ interrupts = <4>;
+ clocks = <&clks 47>, <&clks 0>, <&clks 74>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+ };
+
+ usbotg: usb@73f80000 {
+ compatible = "fsl,imx51-usb", "fsl,imx27-usb";
+ reg = <0x73f80000 0x0200>;
+ interrupts = <18>;
+ status = "disabled";
+ };
+
+ usbh1: usb@73f80200 {
+ compatible = "fsl,imx51-usb", "fsl,imx27-usb";
+ reg = <0x73f80200 0x0200>;
+ interrupts = <14>;
+ status = "disabled";
+ };
+
+ usbh2: usb@73f80400 {
+ compatible = "fsl,imx51-usb", "fsl,imx27-usb";
+ reg = <0x73f80400 0x0200>;
+ interrupts = <16>;
+ status = "disabled";
+ };
+
+ usbh3: usb@73f80600 {
+ compatible = "fsl,imx51-usb", "fsl,imx27-usb";
+ reg = <0x73f80600 0x0200>;
+ interrupts = <17>;
+ status = "disabled";
+ };
+
+ gpio1: gpio@73f84000 {
+ compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
+ reg = <0x73f84000 0x4000>;
+ interrupts = <50 51>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@73f88000 {
+ compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
+ reg = <0x73f88000 0x4000>;
+ interrupts = <52 53>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@73f8c000 {
+ compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
+ reg = <0x73f8c000 0x4000>;
+ interrupts = <54 55>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@73f90000 {
+ compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
+ reg = <0x73f90000 0x4000>;
+ interrupts = <56 57>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ kpp: kpp@73f94000 {
+ compatible = "fsl,imx51-kpp", "fsl,imx21-kpp";
+ reg = <0x73f94000 0x4000>;
+ interrupts = <60>;
+ clocks = <&clks 0>;
+ status = "disabled";
+ };
+
+ wdog1: wdog@73f98000 {
+ compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
+ reg = <0x73f98000 0x4000>;
+ interrupts = <58>;
+ clocks = <&clks 0>;
+ };
+
+ wdog2: wdog@73f9c000 {
+ compatible = "fsl,imx51-wdt", "fsl,imx21-wdt";
+ reg = <0x73f9c000 0x4000>;
+ interrupts = <59>;
+ clocks = <&clks 0>;
+ status = "disabled";
+ };
+
+ gpt: timer@73fa0000 {
+ compatible = "fsl,imx51-gpt", "fsl,imx31-gpt";
+ reg = <0x73fa0000 0x4000>;
+ interrupts = <39>;
+ clocks = <&clks 36>, <&clks 41>;
+ clock-names = "ipg", "per";
+ };
+
+ iomuxc: iomuxc@73fa8000 {
+ compatible = "fsl,imx51-iomuxc";
+ reg = <0x73fa8000 0x4000>;
+
+ audmux {
+ pinctrl_audmux_1: audmuxgrp-1 {
+ fsl,pins = <
+ MX51_PAD_AUD3_BB_TXD__AUD3_TXD 0x80000000
+ MX51_PAD_AUD3_BB_RXD__AUD3_RXD 0x80000000
+ MX51_PAD_AUD3_BB_CK__AUD3_TXC 0x80000000
+ MX51_PAD_AUD3_BB_FS__AUD3_TXFS 0x80000000
+ >;
+ };
+ };
+
+ fec {
+ pinctrl_fec_1: fecgrp-1 {
+ fsl,pins = <
+ MX51_PAD_EIM_EB2__FEC_MDIO 0x000001f5
+ MX51_PAD_EIM_EB3__FEC_RDATA1 0x00000085
+ MX51_PAD_EIM_CS2__FEC_RDATA2 0x00000085
+ MX51_PAD_EIM_CS3__FEC_RDATA3 0x00000085
+ MX51_PAD_EIM_CS4__FEC_RX_ER 0x00000180
+ MX51_PAD_EIM_CS5__FEC_CRS 0x00000180
+ MX51_PAD_NANDF_RB2__FEC_COL 0x00000180
+ MX51_PAD_NANDF_RB3__FEC_RX_CLK 0x00000180
+ MX51_PAD_NANDF_D9__FEC_RDATA0 0x00002180
+ MX51_PAD_NANDF_D8__FEC_TDATA0 0x00002004
+ MX51_PAD_NANDF_CS2__FEC_TX_ER 0x00002004
+ MX51_PAD_NANDF_CS3__FEC_MDC 0x00002004
+ MX51_PAD_NANDF_CS4__FEC_TDATA1 0x00002004
+ MX51_PAD_NANDF_CS5__FEC_TDATA2 0x00002004
+ MX51_PAD_NANDF_CS6__FEC_TDATA3 0x00002004
+ MX51_PAD_NANDF_CS7__FEC_TX_EN 0x00002004
+ MX51_PAD_NANDF_RDY_INT__FEC_TX_CLK 0x00002180
+ MX51_PAD_NANDF_D11__FEC_RX_DV 0x000020a4
+ >;
+ };
+
+ pinctrl_fec_2: fecgrp-2 {
+ fsl,pins = <
+ MX51_PAD_DI_GP3__FEC_TX_ER 0x80000000
+ MX51_PAD_DI2_PIN4__FEC_CRS 0x80000000
+ MX51_PAD_DI2_PIN2__FEC_MDC 0x80000000
+ MX51_PAD_DI2_PIN3__FEC_MDIO 0x80000000
+ MX51_PAD_DI2_DISP_CLK__FEC_RDATA1 0x80000000
+ MX51_PAD_DI_GP4__FEC_RDATA2 0x80000000
+ MX51_PAD_DISP2_DAT0__FEC_RDATA3 0x80000000
+ MX51_PAD_DISP2_DAT1__FEC_RX_ER 0x80000000
+ MX51_PAD_DISP2_DAT6__FEC_TDATA1 0x80000000
+ MX51_PAD_DISP2_DAT7__FEC_TDATA2 0x80000000
+ MX51_PAD_DISP2_DAT8__FEC_TDATA3 0x80000000
+ MX51_PAD_DISP2_DAT9__FEC_TX_EN 0x80000000
+ MX51_PAD_DISP2_DAT10__FEC_COL 0x80000000
+ MX51_PAD_DISP2_DAT11__FEC_RX_CLK 0x80000000
+ MX51_PAD_DISP2_DAT12__FEC_RX_DV 0x80000000
+ MX51_PAD_DISP2_DAT13__FEC_TX_CLK 0x80000000
+ MX51_PAD_DISP2_DAT14__FEC_RDATA0 0x80000000
+ MX51_PAD_DISP2_DAT15__FEC_TDATA0 0x80000000
+ >;
+ };
+ };
+
+ ecspi1 {
+ pinctrl_ecspi1_1: ecspi1grp-1 {
+ fsl,pins = <
+ MX51_PAD_CSPI1_MISO__ECSPI1_MISO 0x185
+ MX51_PAD_CSPI1_MOSI__ECSPI1_MOSI 0x185
+ MX51_PAD_CSPI1_SCLK__ECSPI1_SCLK 0x185
+ >;
+ };
+ };
+
+ ecspi2 {
+ pinctrl_ecspi2_1: ecspi2grp-1 {
+ fsl,pins = <
+ MX51_PAD_NANDF_RB3__ECSPI2_MISO 0x185
+ MX51_PAD_NANDF_D15__ECSPI2_MOSI 0x185
+ MX51_PAD_NANDF_RB2__ECSPI2_SCLK 0x185
+ >;
+ };
+ };
+
+ esdhc1 {
+ pinctrl_esdhc1_1: esdhc1grp-1 {
+ fsl,pins = <
+ MX51_PAD_SD1_CMD__SD1_CMD 0x400020d5
+ MX51_PAD_SD1_CLK__SD1_CLK 0x20d5
+ MX51_PAD_SD1_DATA0__SD1_DATA0 0x20d5
+ MX51_PAD_SD1_DATA1__SD1_DATA1 0x20d5
+ MX51_PAD_SD1_DATA2__SD1_DATA2 0x20d5
+ MX51_PAD_SD1_DATA3__SD1_DATA3 0x20d5
+ >;
+ };
+ };
+
+ esdhc2 {
+ pinctrl_esdhc2_1: esdhc2grp-1 {
+ fsl,pins = <
+ MX51_PAD_SD2_CMD__SD2_CMD 0x400020d5
+ MX51_PAD_SD2_CLK__SD2_CLK 0x20d5
+ MX51_PAD_SD2_DATA0__SD2_DATA0 0x20d5
+ MX51_PAD_SD2_DATA1__SD2_DATA1 0x20d5
+ MX51_PAD_SD2_DATA2__SD2_DATA2 0x20d5
+ MX51_PAD_SD2_DATA3__SD2_DATA3 0x20d5
+ >;
+ };
+ };
+
+ i2c2 {
+ pinctrl_i2c2_1: i2c2grp-1 {
+ fsl,pins = <
+ MX51_PAD_KEY_COL4__I2C2_SCL 0x400001ed
+ MX51_PAD_KEY_COL5__I2C2_SDA 0x400001ed
+ >;
+ };
+
+ pinctrl_i2c2_2: i2c2grp-2 {
+ fsl,pins = <
+ MX51_PAD_EIM_D27__I2C2_SCL 0x400001ed
+ MX51_PAD_EIM_D24__I2C2_SDA 0x400001ed
+ >;
+ };
+ };
+
+ ipu_disp1 {
+ pinctrl_ipu_disp1_1: ipudisp1grp-1 {
+ fsl,pins = <
+ MX51_PAD_DISP1_DAT0__DISP1_DAT0 0x5
+ MX51_PAD_DISP1_DAT1__DISP1_DAT1 0x5
+ MX51_PAD_DISP1_DAT2__DISP1_DAT2 0x5
+ MX51_PAD_DISP1_DAT3__DISP1_DAT3 0x5
+ MX51_PAD_DISP1_DAT4__DISP1_DAT4 0x5
+ MX51_PAD_DISP1_DAT5__DISP1_DAT5 0x5
+ MX51_PAD_DISP1_DAT6__DISP1_DAT6 0x5
+ MX51_PAD_DISP1_DAT7__DISP1_DAT7 0x5
+ MX51_PAD_DISP1_DAT8__DISP1_DAT8 0x5
+ MX51_PAD_DISP1_DAT9__DISP1_DAT9 0x5
+ MX51_PAD_DISP1_DAT10__DISP1_DAT10 0x5
+ MX51_PAD_DISP1_DAT11__DISP1_DAT11 0x5
+ MX51_PAD_DISP1_DAT12__DISP1_DAT12 0x5
+ MX51_PAD_DISP1_DAT13__DISP1_DAT13 0x5
+ MX51_PAD_DISP1_DAT14__DISP1_DAT14 0x5
+ MX51_PAD_DISP1_DAT15__DISP1_DAT15 0x5
+ MX51_PAD_DISP1_DAT16__DISP1_DAT16 0x5
+ MX51_PAD_DISP1_DAT17__DISP1_DAT17 0x5
+ MX51_PAD_DISP1_DAT18__DISP1_DAT18 0x5
+ MX51_PAD_DISP1_DAT19__DISP1_DAT19 0x5
+ MX51_PAD_DISP1_DAT20__DISP1_DAT20 0x5
+ MX51_PAD_DISP1_DAT21__DISP1_DAT21 0x5
+ MX51_PAD_DISP1_DAT22__DISP1_DAT22 0x5
+ MX51_PAD_DISP1_DAT23__DISP1_DAT23 0x5
+ MX51_PAD_DI1_PIN2__DI1_PIN2 0x5 /* hsync */
+ MX51_PAD_DI1_PIN3__DI1_PIN3 0x5 /* vsync */
+ >;
+ };
+ };
+
+ ipu_disp2 {
+ pinctrl_ipu_disp2_1: ipudisp2grp-1 {
+ fsl,pins = <
+ MX51_PAD_DISP2_DAT0__DISP2_DAT0 0x5
+ MX51_PAD_DISP2_DAT1__DISP2_DAT1 0x5
+ MX51_PAD_DISP2_DAT2__DISP2_DAT2 0x5
+ MX51_PAD_DISP2_DAT3__DISP2_DAT3 0x5
+ MX51_PAD_DISP2_DAT4__DISP2_DAT4 0x5
+ MX51_PAD_DISP2_DAT5__DISP2_DAT5 0x5
+ MX51_PAD_DISP2_DAT6__DISP2_DAT6 0x5
+ MX51_PAD_DISP2_DAT7__DISP2_DAT7 0x5
+ MX51_PAD_DISP2_DAT8__DISP2_DAT8 0x5
+ MX51_PAD_DISP2_DAT9__DISP2_DAT9 0x5
+ MX51_PAD_DISP2_DAT10__DISP2_DAT10 0x5
+ MX51_PAD_DISP2_DAT11__DISP2_DAT11 0x5
+ MX51_PAD_DISP2_DAT12__DISP2_DAT12 0x5
+ MX51_PAD_DISP2_DAT13__DISP2_DAT13 0x5
+ MX51_PAD_DISP2_DAT14__DISP2_DAT14 0x5
+ MX51_PAD_DISP2_DAT15__DISP2_DAT15 0x5
+ MX51_PAD_DI2_PIN2__DI2_PIN2 0x5 /* hsync */
+ MX51_PAD_DI2_PIN3__DI2_PIN3 0x5 /* vsync */
+ MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK 0x5
+ MX51_PAD_DI_GP4__DI2_PIN15 0x5
+ >;
+ };
+ };
+
+ pata {
+ pinctrl_pata_1: patagrp-1 {
+ fsl,pins = <
+ MX51_PAD_NANDF_WE_B__PATA_DIOW 0x2004
+ MX51_PAD_NANDF_RE_B__PATA_DIOR 0x2004
+ MX51_PAD_NANDF_ALE__PATA_BUFFER_EN 0x2004
+ MX51_PAD_NANDF_CLE__PATA_RESET_B 0x2004
+ MX51_PAD_NANDF_WP_B__PATA_DMACK 0x2004
+ MX51_PAD_NANDF_RB0__PATA_DMARQ 0x2004
+ MX51_PAD_NANDF_RB1__PATA_IORDY 0x2004
+ MX51_PAD_GPIO_NAND__PATA_INTRQ 0x2004
+ MX51_PAD_NANDF_CS2__PATA_CS_0 0x2004
+ MX51_PAD_NANDF_CS3__PATA_CS_1 0x2004
+ MX51_PAD_NANDF_CS4__PATA_DA_0 0x2004
+ MX51_PAD_NANDF_CS5__PATA_DA_1 0x2004
+ MX51_PAD_NANDF_CS6__PATA_DA_2 0x2004
+ MX51_PAD_NANDF_D15__PATA_DATA15 0x2004
+ MX51_PAD_NANDF_D14__PATA_DATA14 0x2004
+ MX51_PAD_NANDF_D13__PATA_DATA13 0x2004
+ MX51_PAD_NANDF_D12__PATA_DATA12 0x2004
+ MX51_PAD_NANDF_D11__PATA_DATA11 0x2004
+ MX51_PAD_NANDF_D10__PATA_DATA10 0x2004
+ MX51_PAD_NANDF_D9__PATA_DATA9 0x2004
+ MX51_PAD_NANDF_D8__PATA_DATA8 0x2004
+ MX51_PAD_NANDF_D7__PATA_DATA7 0x2004
+ MX51_PAD_NANDF_D6__PATA_DATA6 0x2004
+ MX51_PAD_NANDF_D5__PATA_DATA5 0x2004
+ MX51_PAD_NANDF_D4__PATA_DATA4 0x2004
+ MX51_PAD_NANDF_D3__PATA_DATA3 0x2004
+ MX51_PAD_NANDF_D2__PATA_DATA2 0x2004
+ MX51_PAD_NANDF_D1__PATA_DATA1 0x2004
+ MX51_PAD_NANDF_D0__PATA_DATA0 0x2004
+ >;
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1_1: uart1grp-1 {
+ fsl,pins = <
+ MX51_PAD_UART1_RXD__UART1_RXD 0x1c5
+ MX51_PAD_UART1_TXD__UART1_TXD 0x1c5
+ MX51_PAD_UART1_RTS__UART1_RTS 0x1c5
+ MX51_PAD_UART1_CTS__UART1_CTS 0x1c5
+ >;
+ };
+ };
+
+ uart2 {
+ pinctrl_uart2_1: uart2grp-1 {
+ fsl,pins = <
+ MX51_PAD_UART2_RXD__UART2_RXD 0x1c5
+ MX51_PAD_UART2_TXD__UART2_TXD 0x1c5
+ >;
+ };
+ };
+
+ uart3 {
+ pinctrl_uart3_1: uart3grp-1 {
+ fsl,pins = <
+ MX51_PAD_EIM_D25__UART3_RXD 0x1c5
+ MX51_PAD_EIM_D26__UART3_TXD 0x1c5
+ MX51_PAD_EIM_D27__UART3_RTS 0x1c5
+ MX51_PAD_EIM_D24__UART3_CTS 0x1c5
+ >;
+ };
+
+ pinctrl_uart3_2: uart3grp-2 {
+ fsl,pins = <
+ MX51_PAD_UART3_RXD__UART3_RXD 0x1c5
+ MX51_PAD_UART3_TXD__UART3_TXD 0x1c5
+ >;
+ };
+ };
+
+ kpp {
+ pinctrl_kpp_1: kppgrp-1 {
+ fsl,pins = <
+ MX51_PAD_KEY_ROW0__KEY_ROW0 0xe0
+ MX51_PAD_KEY_ROW1__KEY_ROW1 0xe0
+ MX51_PAD_KEY_ROW2__KEY_ROW2 0xe0
+ MX51_PAD_KEY_ROW3__KEY_ROW3 0xe0
+ MX51_PAD_KEY_COL0__KEY_COL0 0xe8
+ MX51_PAD_KEY_COL1__KEY_COL1 0xe8
+ MX51_PAD_KEY_COL2__KEY_COL2 0xe8
+ MX51_PAD_KEY_COL3__KEY_COL3 0xe8
+ >;
+ };
+ };
+ };
+
+ pwm1: pwm@73fb4000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx51-pwm", "fsl,imx27-pwm";
+ reg = <0x73fb4000 0x4000>;
+ clocks = <&clks 37>, <&clks 38>;
+ clock-names = "ipg", "per";
+ interrupts = <61>;
+ };
+
+ pwm2: pwm@73fb8000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx51-pwm", "fsl,imx27-pwm";
+ reg = <0x73fb8000 0x4000>;
+ clocks = <&clks 39>, <&clks 40>;
+ clock-names = "ipg", "per";
+ interrupts = <94>;
+ };
+
+ uart1: serial@73fbc000 {
+ compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+ reg = <0x73fbc000 0x4000>;
+ interrupts = <31>;
+ clocks = <&clks 28>, <&clks 29>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart2: serial@73fc0000 {
+ compatible = "fsl,imx51-uart", "fsl,imx21-uart";
+ reg = <0x73fc0000 0x4000>;
+ interrupts = <32>;
+ clocks = <&clks 30>, <&clks 31>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ src: src@73fd0000 {
+ compatible = "fsl,imx51-src";
+ reg = <0x73fd0000 0x4000>;
+ #reset-cells = <1>;
+ };
+
+ clks: ccm@73fd4000{
+ compatible = "fsl,imx51-ccm";
+ reg = <0x73fd4000 0x4000>;
+ interrupts = <0 71 0x04 0 72 0x04>;
+ #clock-cells = <1>;
+ };
+ };
+
+ aips@80000000 { /* AIPS2 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x80000000 0x10000000>;
+ ranges;
+
+ iim: iim@83f98000 {
+ compatible = "fsl,imx51-iim", "fsl,imx-iim";
+ reg = <0x83f98000 0x4000>;
+ interrupts = <69>;
+ clocks = <&clks 107>;
+ };
+
+ ecspi2: ecspi@83fac000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-ecspi";
+ reg = <0x83fac000 0x4000>;
+ interrupts = <37>;
+ clocks = <&clks 53>, <&clks 54>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ sdma: sdma@83fb0000 {
+ compatible = "fsl,imx51-sdma", "fsl,imx35-sdma";
+ reg = <0x83fb0000 0x4000>;
+ interrupts = <6>;
+ clocks = <&clks 56>, <&clks 56>;
+ clock-names = "ipg", "ahb";
+ fsl,sdma-ram-script-name = "imx/sdma/sdma-imx51.bin";
+ };
+
+ cspi: cspi@83fc0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-cspi", "fsl,imx35-cspi";
+ reg = <0x83fc0000 0x4000>;
+ interrupts = <38>;
+ clocks = <&clks 55>, <&clks 0>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ i2c2: i2c@83fc4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-i2c", "fsl,imx21-i2c";
+ reg = <0x83fc4000 0x4000>;
+ interrupts = <63>;
+ clocks = <&clks 35>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@83fc8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx51-i2c", "fsl,imx21-i2c";
+ reg = <0x83fc8000 0x4000>;
+ interrupts = <62>;
+ clocks = <&clks 34>;
+ status = "disabled";
+ };
+
+ ssi1: ssi@83fcc000 {
+ compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
+ reg = <0x83fcc000 0x4000>;
+ interrupts = <29>;
+ clocks = <&clks 48>;
+ fsl,fifo-depth = <15>;
+ fsl,ssi-dma-events = <29 28 27 26>; /* TX0 RX0 TX1 RX1 */
+ status = "disabled";
+ };
+
+ audmux: audmux@83fd0000 {
+ compatible = "fsl,imx51-audmux", "fsl,imx31-audmux";
+ reg = <0x83fd0000 0x4000>;
+ status = "disabled";
+ };
+
+ nfc: nand@83fdb000 {
+ compatible = "fsl,imx51-nand";
+ reg = <0x83fdb000 0x1000 0xcfff0000 0x10000>;
+ interrupts = <8>;
+ clocks = <&clks 60>;
+ status = "disabled";
+ };
+
+ pata: pata@83fe0000 {
+ compatible = "fsl,imx51-pata", "fsl,imx27-pata";
+ reg = <0x83fe0000 0x4000>;
+ interrupts = <70>;
+ clocks = <&clks 161>;
+ status = "disabled";
+ };
+
+ ssi3: ssi@83fe8000 {
+ compatible = "fsl,imx51-ssi", "fsl,imx21-ssi";
+ reg = <0x83fe8000 0x4000>;
+ interrupts = <96>;
+ clocks = <&clks 50>;
+ fsl,fifo-depth = <15>;
+ fsl,ssi-dma-events = <47 46 37 35>; /* TX0 RX0 TX1 RX1 */
+ status = "disabled";
+ };
+
+ fec: ethernet@83fec000 {
+ compatible = "fsl,imx51-fec", "fsl,imx27-fec";
+ reg = <0x83fec000 0x4000>;
+ interrupts = <87>;
+ clocks = <&clks 42>, <&clks 42>, <&clks 42>;
+ clock-names = "ipg", "ahb", "ptp";
+ status = "disabled";
+ };
+ };
+ };
+};
diff --git a/arch/arm/dts/imx6q-pinfunc.h b/arch/arm/dts/imx6q-pinfunc.h
new file mode 100644
index 0000000000..faea6e1ada
--- /dev/null
+++ b/arch/arm/dts/imx6q-pinfunc.h
@@ -0,0 +1,1041 @@
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#ifndef __DTS_IMX6Q_PINFUNC_H
+#define __DTS_IMX6Q_PINFUNC_H
+
+/*
+ * The pin function ID is a tuple of
+ * <mux_reg conf_reg input_reg mux_mode input_val>
+ */
+#define MX6Q_PAD_SD2_DAT1__SD2_DATA1 0x04c 0x360 0x000 0x0 0x0
+#define MX6Q_PAD_SD2_DAT1__ECSPI5_SS0 0x04c 0x360 0x834 0x1 0x0
+#define MX6Q_PAD_SD2_DAT1__EIM_CS2_B 0x04c 0x360 0x000 0x2 0x0
+#define MX6Q_PAD_SD2_DAT1__AUD4_TXFS 0x04c 0x360 0x7c8 0x3 0x0
+#define MX6Q_PAD_SD2_DAT1__KEY_COL7 0x04c 0x360 0x8f0 0x4 0x0
+#define MX6Q_PAD_SD2_DAT1__GPIO1_IO14 0x04c 0x360 0x000 0x5 0x0
+#define MX6Q_PAD_SD2_DAT2__SD2_DATA2 0x050 0x364 0x000 0x0 0x0
+#define MX6Q_PAD_SD2_DAT2__ECSPI5_SS1 0x050 0x364 0x838 0x1 0x0
+#define MX6Q_PAD_SD2_DAT2__EIM_CS3_B 0x050 0x364 0x000 0x2 0x0
+#define MX6Q_PAD_SD2_DAT2__AUD4_TXD 0x050 0x364 0x7b8 0x3 0x0
+#define MX6Q_PAD_SD2_DAT2__KEY_ROW6 0x050 0x364 0x8f8 0x4 0x0
+#define MX6Q_PAD_SD2_DAT2__GPIO1_IO13 0x050 0x364 0x000 0x5 0x0
+#define MX6Q_PAD_SD2_DAT0__SD2_DATA0 0x054 0x368 0x000 0x0 0x0
+#define MX6Q_PAD_SD2_DAT0__ECSPI5_MISO 0x054 0x368 0x82c 0x1 0x0
+#define MX6Q_PAD_SD2_DAT0__AUD4_RXD 0x054 0x368 0x7b4 0x3 0x0
+#define MX6Q_PAD_SD2_DAT0__KEY_ROW7 0x054 0x368 0x8fc 0x4 0x0
+#define MX6Q_PAD_SD2_DAT0__GPIO1_IO15 0x054 0x368 0x000 0x5 0x0
+#define MX6Q_PAD_SD2_DAT0__DCIC2_OUT 0x054 0x368 0x000 0x6 0x0
+#define MX6Q_PAD_RGMII_TXC__USB_H2_DATA 0x058 0x36c 0x000 0x0 0x0
+#define MX6Q_PAD_RGMII_TXC__RGMII_TXC 0x058 0x36c 0x000 0x1 0x0
+#define MX6Q_PAD_RGMII_TXC__SPDIF_EXT_CLK 0x058 0x36c 0x918 0x2 0x0
+#define MX6Q_PAD_RGMII_TXC__GPIO6_IO19 0x058 0x36c 0x000 0x5 0x0
+#define MX6Q_PAD_RGMII_TXC__XTALOSC_REF_CLK_24M 0x058 0x36c 0x000 0x7 0x0
+#define MX6Q_PAD_RGMII_TD0__HSI_TX_READY 0x05c 0x370 0x000 0x0 0x0
+#define MX6Q_PAD_RGMII_TD0__RGMII_TD0 0x05c 0x370 0x000 0x1 0x0
+#define MX6Q_PAD_RGMII_TD0__GPIO6_IO20 0x05c 0x370 0x000 0x5 0x0
+#define MX6Q_PAD_RGMII_TD1__HSI_RX_FLAG 0x060 0x374 0x000 0x0 0x0
+#define MX6Q_PAD_RGMII_TD1__RGMII_TD1 0x060 0x374 0x000 0x1 0x0
+#define MX6Q_PAD_RGMII_TD1__GPIO6_IO21 0x060 0x374 0x000 0x5 0x0
+#define MX6Q_PAD_RGMII_TD2__HSI_RX_DATA 0x064 0x378 0x000 0x0 0x0
+#define MX6Q_PAD_RGMII_TD2__RGMII_TD2 0x064 0x378 0x000 0x1 0x0
+#define MX6Q_PAD_RGMII_TD2__GPIO6_IO22 0x064 0x378 0x000 0x5 0x0
+#define MX6Q_PAD_RGMII_TD3__HSI_RX_WAKE 0x068 0x37c 0x000 0x0 0x0
+#define MX6Q_PAD_RGMII_TD3__RGMII_TD3 0x068 0x37c 0x000 0x1 0x0
+#define MX6Q_PAD_RGMII_TD3__GPIO6_IO23 0x068 0x37c 0x000 0x5 0x0
+#define MX6Q_PAD_RGMII_RX_CTL__USB_H3_DATA 0x06c 0x380 0x000 0x0 0x0
+#define MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x06c 0x380 0x858 0x1 0x0
+#define MX6Q_PAD_RGMII_RX_CTL__GPIO6_IO24 0x06c 0x380 0x000 0x5 0x0
+#define MX6Q_PAD_RGMII_RD0__HSI_RX_READY 0x070 0x384 0x000 0x0 0x0
+#define MX6Q_PAD_RGMII_RD0__RGMII_RD0 0x070 0x384 0x848 0x1 0x0
+#define MX6Q_PAD_RGMII_RD0__GPIO6_IO25 0x070 0x384 0x000 0x5 0x0
+#define MX6Q_PAD_RGMII_TX_CTL__USB_H2_STROBE 0x074 0x388 0x000 0x0 0x0
+#define MX6Q_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x074 0x388 0x000 0x1 0x0
+#define MX6Q_PAD_RGMII_TX_CTL__GPIO6_IO26 0x074 0x388 0x000 0x5 0x0
+#define MX6Q_PAD_RGMII_TX_CTL__ENET_REF_CLK 0x074 0x388 0x83c 0x7 0x0
+#define MX6Q_PAD_RGMII_RD1__HSI_TX_FLAG 0x078 0x38c 0x000 0x0 0x0
+#define MX6Q_PAD_RGMII_RD1__RGMII_RD1 0x078 0x38c 0x84c 0x1 0x0
+#define MX6Q_PAD_RGMII_RD1__GPIO6_IO27 0x078 0x38c 0x000 0x5 0x0
+#define MX6Q_PAD_RGMII_RD2__HSI_TX_DATA 0x07c 0x390 0x000 0x0 0x0
+#define MX6Q_PAD_RGMII_RD2__RGMII_RD2 0x07c 0x390 0x850 0x1 0x0
+#define MX6Q_PAD_RGMII_RD2__GPIO6_IO28 0x07c 0x390 0x000 0x5 0x0
+#define MX6Q_PAD_RGMII_RD3__HSI_TX_WAKE 0x080 0x394 0x000 0x0 0x0
+#define MX6Q_PAD_RGMII_RD3__RGMII_RD3 0x080 0x394 0x854 0x1 0x0
+#define MX6Q_PAD_RGMII_RD3__GPIO6_IO29 0x080 0x394 0x000 0x5 0x0
+#define MX6Q_PAD_RGMII_RXC__USB_H3_STROBE 0x084 0x398 0x000 0x0 0x0
+#define MX6Q_PAD_RGMII_RXC__RGMII_RXC 0x084 0x398 0x844 0x1 0x0
+#define MX6Q_PAD_RGMII_RXC__GPIO6_IO30 0x084 0x398 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_A25__EIM_ADDR25 0x088 0x39c 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_A25__ECSPI4_SS1 0x088 0x39c 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_A25__ECSPI2_RDY 0x088 0x39c 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_A25__IPU1_DI1_PIN12 0x088 0x39c 0x000 0x3 0x0
+#define MX6Q_PAD_EIM_A25__IPU1_DI0_D1_CS 0x088 0x39c 0x000 0x4 0x0
+#define MX6Q_PAD_EIM_A25__GPIO5_IO02 0x088 0x39c 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_A25__HDMI_TX_CEC_LINE 0x088 0x39c 0x88c 0x6 0x0
+#define MX6Q_PAD_EIM_EB2__EIM_EB2_B 0x08c 0x3a0 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_EB2__ECSPI1_SS0 0x08c 0x3a0 0x800 0x1 0x0
+#define MX6Q_PAD_EIM_EB2__IPU2_CSI1_DATA19 0x08c 0x3a0 0x8d4 0x3 0x0
+#define MX6Q_PAD_EIM_EB2__HDMI_TX_DDC_SCL 0x08c 0x3a0 0x890 0x4 0x0
+#define MX6Q_PAD_EIM_EB2__GPIO2_IO30 0x08c 0x3a0 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_EB2__I2C2_SCL 0x08c 0x3a0 0x8a0 0x6 0x0
+#define MX6Q_PAD_EIM_EB2__SRC_BOOT_CFG30 0x08c 0x3a0 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_D16__EIM_DATA16 0x090 0x3a4 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_D16__ECSPI1_SCLK 0x090 0x3a4 0x7f4 0x1 0x0
+#define MX6Q_PAD_EIM_D16__IPU1_DI0_PIN05 0x090 0x3a4 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_D16__IPU2_CSI1_DATA18 0x090 0x3a4 0x8d0 0x3 0x0
+#define MX6Q_PAD_EIM_D16__HDMI_TX_DDC_SDA 0x090 0x3a4 0x894 0x4 0x0
+#define MX6Q_PAD_EIM_D16__GPIO3_IO16 0x090 0x3a4 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_D16__I2C2_SDA 0x090 0x3a4 0x8a4 0x6 0x0
+#define MX6Q_PAD_EIM_D17__EIM_DATA17 0x094 0x3a8 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_D17__ECSPI1_MISO 0x094 0x3a8 0x7f8 0x1 0x0
+#define MX6Q_PAD_EIM_D17__IPU1_DI0_PIN06 0x094 0x3a8 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_D17__IPU2_CSI1_PIXCLK 0x094 0x3a8 0x8e0 0x3 0x0
+#define MX6Q_PAD_EIM_D17__DCIC1_OUT 0x094 0x3a8 0x000 0x4 0x0
+#define MX6Q_PAD_EIM_D17__GPIO3_IO17 0x094 0x3a8 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_D17__I2C3_SCL 0x094 0x3a8 0x8a8 0x6 0x0
+#define MX6Q_PAD_EIM_D18__EIM_DATA18 0x098 0x3ac 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_D18__ECSPI1_MOSI 0x098 0x3ac 0x7fc 0x1 0x0
+#define MX6Q_PAD_EIM_D18__IPU1_DI0_PIN07 0x098 0x3ac 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_D18__IPU2_CSI1_DATA17 0x098 0x3ac 0x8cc 0x3 0x0
+#define MX6Q_PAD_EIM_D18__IPU1_DI1_D0_CS 0x098 0x3ac 0x000 0x4 0x0
+#define MX6Q_PAD_EIM_D18__GPIO3_IO18 0x098 0x3ac 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_D18__I2C3_SDA 0x098 0x3ac 0x8ac 0x6 0x0
+#define MX6Q_PAD_EIM_D19__EIM_DATA19 0x09c 0x3b0 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_D19__ECSPI1_SS1 0x09c 0x3b0 0x804 0x1 0x0
+#define MX6Q_PAD_EIM_D19__IPU1_DI0_PIN08 0x09c 0x3b0 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_D19__IPU2_CSI1_DATA16 0x09c 0x3b0 0x8c8 0x3 0x0
+#define MX6Q_PAD_EIM_D19__UART1_CTS_B 0x09c 0x3b0 0x000 0x4 0x0
+#define MX6Q_PAD_EIM_D19__UART1_RTS_B 0x09c 0x3b0 0x91c 0x4 0x0
+#define MX6Q_PAD_EIM_D19__GPIO3_IO19 0x09c 0x3b0 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_D19__EPIT1_OUT 0x09c 0x3b0 0x000 0x6 0x0
+#define MX6Q_PAD_EIM_D20__EIM_DATA20 0x0a0 0x3b4 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_D20__ECSPI4_SS0 0x0a0 0x3b4 0x824 0x1 0x0
+#define MX6Q_PAD_EIM_D20__IPU1_DI0_PIN16 0x0a0 0x3b4 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_D20__IPU2_CSI1_DATA15 0x0a0 0x3b4 0x8c4 0x3 0x0
+#define MX6Q_PAD_EIM_D20__UART1_RTS_B 0x0a0 0x3b4 0x91c 0x4 0x1
+#define MX6Q_PAD_EIM_D20__UART1_CTS_B 0x0a0 0x3b4 0x000 0x4 0x0
+#define MX6Q_PAD_EIM_D20__GPIO3_IO20 0x0a0 0x3b4 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_D20__EPIT2_OUT 0x0a0 0x3b4 0x000 0x6 0x0
+#define MX6Q_PAD_EIM_D21__EIM_DATA21 0x0a4 0x3b8 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_D21__ECSPI4_SCLK 0x0a4 0x3b8 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_D21__IPU1_DI0_PIN17 0x0a4 0x3b8 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_D21__IPU2_CSI1_DATA11 0x0a4 0x3b8 0x8b4 0x3 0x0
+#define MX6Q_PAD_EIM_D21__USB_OTG_OC 0x0a4 0x3b8 0x944 0x4 0x0
+#define MX6Q_PAD_EIM_D21__GPIO3_IO21 0x0a4 0x3b8 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_D21__I2C1_SCL 0x0a4 0x3b8 0x898 0x6 0x0
+#define MX6Q_PAD_EIM_D21__SPDIF_IN 0x0a4 0x3b8 0x914 0x7 0x0
+#define MX6Q_PAD_EIM_D22__EIM_DATA22 0x0a8 0x3bc 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_D22__ECSPI4_MISO 0x0a8 0x3bc 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_D22__IPU1_DI0_PIN01 0x0a8 0x3bc 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_D22__IPU2_CSI1_DATA10 0x0a8 0x3bc 0x8b0 0x3 0x0
+#define MX6Q_PAD_EIM_D22__USB_OTG_PWR 0x0a8 0x3bc 0x000 0x4 0x0
+#define MX6Q_PAD_EIM_D22__GPIO3_IO22 0x0a8 0x3bc 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_D22__SPDIF_OUT 0x0a8 0x3bc 0x000 0x6 0x0
+#define MX6Q_PAD_EIM_D23__EIM_DATA23 0x0ac 0x3c0 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_D23__IPU1_DI0_D0_CS 0x0ac 0x3c0 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_D23__UART3_CTS_B 0x0ac 0x3c0 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_D23__UART3_RTS_B 0x0ac 0x3c0 0x92c 0x2 0x0
+#define MX6Q_PAD_EIM_D23__UART1_DCD_B 0x0ac 0x3c0 0x000 0x3 0x0
+#define MX6Q_PAD_EIM_D23__IPU2_CSI1_DATA_EN 0x0ac 0x3c0 0x8d8 0x4 0x0
+#define MX6Q_PAD_EIM_D23__GPIO3_IO23 0x0ac 0x3c0 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_D23__IPU1_DI1_PIN02 0x0ac 0x3c0 0x000 0x6 0x0
+#define MX6Q_PAD_EIM_D23__IPU1_DI1_PIN14 0x0ac 0x3c0 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_EB3__EIM_EB3_B 0x0b0 0x3c4 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_EB3__ECSPI4_RDY 0x0b0 0x3c4 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_EB3__UART3_RTS_B 0x0b0 0x3c4 0x92c 0x2 0x1
+#define MX6Q_PAD_EIM_EB3__UART3_CTS_B 0x0b0 0x3c4 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_EB3__UART1_RI_B 0x0b0 0x3c4 0x000 0x3 0x0
+#define MX6Q_PAD_EIM_EB3__IPU2_CSI1_HSYNC 0x0b0 0x3c4 0x8dc 0x4 0x0
+#define MX6Q_PAD_EIM_EB3__GPIO2_IO31 0x0b0 0x3c4 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_EB3__IPU1_DI1_PIN03 0x0b0 0x3c4 0x000 0x6 0x0
+#define MX6Q_PAD_EIM_EB3__SRC_BOOT_CFG31 0x0b0 0x3c4 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_D24__EIM_DATA24 0x0b4 0x3c8 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_D24__ECSPI4_SS2 0x0b4 0x3c8 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_D24__UART3_TX_DATA 0x0b4 0x3c8 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_D24__UART3_RX_DATA 0x0b4 0x3c8 0x930 0x2 0x0
+#define MX6Q_PAD_EIM_D24__ECSPI1_SS2 0x0b4 0x3c8 0x808 0x3 0x0
+#define MX6Q_PAD_EIM_D24__ECSPI2_SS2 0x0b4 0x3c8 0x000 0x4 0x0
+#define MX6Q_PAD_EIM_D24__GPIO3_IO24 0x0b4 0x3c8 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_D24__AUD5_RXFS 0x0b4 0x3c8 0x7d8 0x6 0x0
+#define MX6Q_PAD_EIM_D24__UART1_DTR_B 0x0b4 0x3c8 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_D25__EIM_DATA25 0x0b8 0x3cc 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_D25__ECSPI4_SS3 0x0b8 0x3cc 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_D25__UART3_RX_DATA 0x0b8 0x3cc 0x930 0x2 0x1
+#define MX6Q_PAD_EIM_D25__UART3_TX_DATA 0x0b8 0x3cc 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_D25__ECSPI1_SS3 0x0b8 0x3cc 0x80c 0x3 0x0
+#define MX6Q_PAD_EIM_D25__ECSPI2_SS3 0x0b8 0x3cc 0x000 0x4 0x0
+#define MX6Q_PAD_EIM_D25__GPIO3_IO25 0x0b8 0x3cc 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_D25__AUD5_RXC 0x0b8 0x3cc 0x7d4 0x6 0x0
+#define MX6Q_PAD_EIM_D25__UART1_DSR_B 0x0b8 0x3cc 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_D26__EIM_DATA26 0x0bc 0x3d0 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_D26__IPU1_DI1_PIN11 0x0bc 0x3d0 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_D26__IPU1_CSI0_DATA01 0x0bc 0x3d0 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_D26__IPU2_CSI1_DATA14 0x0bc 0x3d0 0x8c0 0x3 0x0
+#define MX6Q_PAD_EIM_D26__UART2_TX_DATA 0x0bc 0x3d0 0x000 0x4 0x0
+#define MX6Q_PAD_EIM_D26__UART2_RX_DATA 0x0bc 0x3d0 0x928 0x4 0x0
+#define MX6Q_PAD_EIM_D26__GPIO3_IO26 0x0bc 0x3d0 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_D26__IPU1_SISG2 0x0bc 0x3d0 0x000 0x6 0x0
+#define MX6Q_PAD_EIM_D26__IPU1_DISP1_DATA22 0x0bc 0x3d0 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_D27__EIM_DATA27 0x0c0 0x3d4 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_D27__IPU1_DI1_PIN13 0x0c0 0x3d4 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_D27__IPU1_CSI0_DATA00 0x0c0 0x3d4 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_D27__IPU2_CSI1_DATA13 0x0c0 0x3d4 0x8bc 0x3 0x0
+#define MX6Q_PAD_EIM_D27__UART2_RX_DATA 0x0c0 0x3d4 0x928 0x4 0x1
+#define MX6Q_PAD_EIM_D27__UART2_TX_DATA 0x0c0 0x3d4 0x000 0x4 0x0
+#define MX6Q_PAD_EIM_D27__GPIO3_IO27 0x0c0 0x3d4 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_D27__IPU1_SISG3 0x0c0 0x3d4 0x000 0x6 0x0
+#define MX6Q_PAD_EIM_D27__IPU1_DISP1_DATA23 0x0c0 0x3d4 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_D28__EIM_DATA28 0x0c4 0x3d8 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_D28__I2C1_SDA 0x0c4 0x3d8 0x89c 0x1 0x0
+#define MX6Q_PAD_EIM_D28__ECSPI4_MOSI 0x0c4 0x3d8 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_D28__IPU2_CSI1_DATA12 0x0c4 0x3d8 0x8b8 0x3 0x0
+#define MX6Q_PAD_EIM_D28__UART2_CTS_B 0x0c4 0x3d8 0x000 0x4 0x0
+#define MX6Q_PAD_EIM_D28__UART2_RTS_B 0x0c4 0x3d8 0x924 0x4 0x0
+#define MX6Q_PAD_EIM_D28__GPIO3_IO28 0x0c4 0x3d8 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_D28__IPU1_EXT_TRIG 0x0c4 0x3d8 0x000 0x6 0x0
+#define MX6Q_PAD_EIM_D28__IPU1_DI0_PIN13 0x0c4 0x3d8 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_D29__EIM_DATA29 0x0c8 0x3dc 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_D29__IPU1_DI1_PIN15 0x0c8 0x3dc 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_D29__ECSPI4_SS0 0x0c8 0x3dc 0x824 0x2 0x1
+#define MX6Q_PAD_EIM_D29__UART2_RTS_B 0x0c8 0x3dc 0x924 0x4 0x1
+#define MX6Q_PAD_EIM_D29__UART2_CTS_B 0x0c8 0x3dc 0x000 0x4 0x0
+#define MX6Q_PAD_EIM_D29__GPIO3_IO29 0x0c8 0x3dc 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_D29__IPU2_CSI1_VSYNC 0x0c8 0x3dc 0x8e4 0x6 0x0
+#define MX6Q_PAD_EIM_D29__IPU1_DI0_PIN14 0x0c8 0x3dc 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_D30__EIM_DATA30 0x0cc 0x3e0 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_D30__IPU1_DISP1_DATA21 0x0cc 0x3e0 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_D30__IPU1_DI0_PIN11 0x0cc 0x3e0 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_D30__IPU1_CSI0_DATA03 0x0cc 0x3e0 0x000 0x3 0x0
+#define MX6Q_PAD_EIM_D30__UART3_CTS_B 0x0cc 0x3e0 0x000 0x4 0x0
+#define MX6Q_PAD_EIM_D30__UART3_RTS_B 0x0cc 0x3e0 0x92c 0x4 0x2
+#define MX6Q_PAD_EIM_D30__GPIO3_IO30 0x0cc 0x3e0 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_D30__USB_H1_OC 0x0cc 0x3e0 0x948 0x6 0x0
+#define MX6Q_PAD_EIM_D31__EIM_DATA31 0x0d0 0x3e4 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_D31__IPU1_DISP1_DATA20 0x0d0 0x3e4 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_D31__IPU1_DI0_PIN12 0x0d0 0x3e4 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_D31__IPU1_CSI0_DATA02 0x0d0 0x3e4 0x000 0x3 0x0
+#define MX6Q_PAD_EIM_D31__UART3_RTS_B 0x0d0 0x3e4 0x92c 0x4 0x3
+#define MX6Q_PAD_EIM_D31__UART3_CTS_B 0x0d0 0x3e4 0x000 0x4 0x0
+#define MX6Q_PAD_EIM_D31__GPIO3_IO31 0x0d0 0x3e4 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_D31__USB_H1_PWR 0x0d0 0x3e4 0x000 0x6 0x0
+#define MX6Q_PAD_EIM_A24__EIM_ADDR24 0x0d4 0x3e8 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_A24__IPU1_DISP1_DATA19 0x0d4 0x3e8 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_A24__IPU2_CSI1_DATA19 0x0d4 0x3e8 0x8d4 0x2 0x1
+#define MX6Q_PAD_EIM_A24__IPU2_SISG2 0x0d4 0x3e8 0x000 0x3 0x0
+#define MX6Q_PAD_EIM_A24__IPU1_SISG2 0x0d4 0x3e8 0x000 0x4 0x0
+#define MX6Q_PAD_EIM_A24__GPIO5_IO04 0x0d4 0x3e8 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_A24__SRC_BOOT_CFG24 0x0d4 0x3e8 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_A23__EIM_ADDR23 0x0d8 0x3ec 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_A23__IPU1_DISP1_DATA18 0x0d8 0x3ec 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_A23__IPU2_CSI1_DATA18 0x0d8 0x3ec 0x8d0 0x2 0x1
+#define MX6Q_PAD_EIM_A23__IPU2_SISG3 0x0d8 0x3ec 0x000 0x3 0x0
+#define MX6Q_PAD_EIM_A23__IPU1_SISG3 0x0d8 0x3ec 0x000 0x4 0x0
+#define MX6Q_PAD_EIM_A23__GPIO6_IO06 0x0d8 0x3ec 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_A23__SRC_BOOT_CFG23 0x0d8 0x3ec 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_A22__EIM_ADDR22 0x0dc 0x3f0 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_A22__IPU1_DISP1_DATA17 0x0dc 0x3f0 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_A22__IPU2_CSI1_DATA17 0x0dc 0x3f0 0x8cc 0x2 0x1
+#define MX6Q_PAD_EIM_A22__GPIO2_IO16 0x0dc 0x3f0 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_A22__SRC_BOOT_CFG22 0x0dc 0x3f0 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_A21__EIM_ADDR21 0x0e0 0x3f4 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_A21__IPU1_DISP1_DATA16 0x0e0 0x3f4 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_A21__IPU2_CSI1_DATA16 0x0e0 0x3f4 0x8c8 0x2 0x1
+#define MX6Q_PAD_EIM_A21__GPIO2_IO17 0x0e0 0x3f4 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_A21__SRC_BOOT_CFG21 0x0e0 0x3f4 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_A20__EIM_ADDR20 0x0e4 0x3f8 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_A20__IPU1_DISP1_DATA15 0x0e4 0x3f8 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_A20__IPU2_CSI1_DATA15 0x0e4 0x3f8 0x8c4 0x2 0x1
+#define MX6Q_PAD_EIM_A20__GPIO2_IO18 0x0e4 0x3f8 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_A20__SRC_BOOT_CFG20 0x0e4 0x3f8 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_A19__EIM_ADDR19 0x0e8 0x3fc 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_A19__IPU1_DISP1_DATA14 0x0e8 0x3fc 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_A19__IPU2_CSI1_DATA14 0x0e8 0x3fc 0x8c0 0x2 0x1
+#define MX6Q_PAD_EIM_A19__GPIO2_IO19 0x0e8 0x3fc 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_A19__SRC_BOOT_CFG19 0x0e8 0x3fc 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_A18__EIM_ADDR18 0x0ec 0x400 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_A18__IPU1_DISP1_DATA13 0x0ec 0x400 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_A18__IPU2_CSI1_DATA13 0x0ec 0x400 0x8bc 0x2 0x1
+#define MX6Q_PAD_EIM_A18__GPIO2_IO20 0x0ec 0x400 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_A18__SRC_BOOT_CFG18 0x0ec 0x400 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_A17__EIM_ADDR17 0x0f0 0x404 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_A17__IPU1_DISP1_DATA12 0x0f0 0x404 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_A17__IPU2_CSI1_DATA12 0x0f0 0x404 0x8b8 0x2 0x1
+#define MX6Q_PAD_EIM_A17__GPIO2_IO21 0x0f0 0x404 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_A17__SRC_BOOT_CFG17 0x0f0 0x404 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_A16__EIM_ADDR16 0x0f4 0x408 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_A16__IPU1_DI1_DISP_CLK 0x0f4 0x408 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_A16__IPU2_CSI1_PIXCLK 0x0f4 0x408 0x8e0 0x2 0x1
+#define MX6Q_PAD_EIM_A16__GPIO2_IO22 0x0f4 0x408 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_A16__SRC_BOOT_CFG16 0x0f4 0x408 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_CS0__EIM_CS0_B 0x0f8 0x40c 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_CS0__IPU1_DI1_PIN05 0x0f8 0x40c 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_CS0__ECSPI2_SCLK 0x0f8 0x40c 0x810 0x2 0x0
+#define MX6Q_PAD_EIM_CS0__GPIO2_IO23 0x0f8 0x40c 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_CS1__EIM_CS1_B 0x0fc 0x410 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_CS1__IPU1_DI1_PIN06 0x0fc 0x410 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_CS1__ECSPI2_MOSI 0x0fc 0x410 0x818 0x2 0x0
+#define MX6Q_PAD_EIM_CS1__GPIO2_IO24 0x0fc 0x410 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_OE__EIM_OE_B 0x100 0x414 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_OE__IPU1_DI1_PIN07 0x100 0x414 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_OE__ECSPI2_MISO 0x100 0x414 0x814 0x2 0x0
+#define MX6Q_PAD_EIM_OE__GPIO2_IO25 0x100 0x414 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_RW__EIM_RW 0x104 0x418 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_RW__IPU1_DI1_PIN08 0x104 0x418 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_RW__ECSPI2_SS0 0x104 0x418 0x81c 0x2 0x0
+#define MX6Q_PAD_EIM_RW__GPIO2_IO26 0x104 0x418 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_RW__SRC_BOOT_CFG29 0x104 0x418 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_LBA__EIM_LBA_B 0x108 0x41c 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_LBA__IPU1_DI1_PIN17 0x108 0x41c 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_LBA__ECSPI2_SS1 0x108 0x41c 0x820 0x2 0x0
+#define MX6Q_PAD_EIM_LBA__GPIO2_IO27 0x108 0x41c 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_LBA__SRC_BOOT_CFG26 0x108 0x41c 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_EB0__EIM_EB0_B 0x10c 0x420 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_EB0__IPU1_DISP1_DATA11 0x10c 0x420 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_EB0__IPU2_CSI1_DATA11 0x10c 0x420 0x8b4 0x2 0x1
+#define MX6Q_PAD_EIM_EB0__CCM_PMIC_READY 0x10c 0x420 0x7f0 0x4 0x0
+#define MX6Q_PAD_EIM_EB0__GPIO2_IO28 0x10c 0x420 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_EB0__SRC_BOOT_CFG27 0x10c 0x420 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_EB1__EIM_EB1_B 0x110 0x424 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_EB1__IPU1_DISP1_DATA10 0x110 0x424 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_EB1__IPU2_CSI1_DATA10 0x110 0x424 0x8b0 0x2 0x1
+#define MX6Q_PAD_EIM_EB1__GPIO2_IO29 0x110 0x424 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_EB1__SRC_BOOT_CFG28 0x110 0x424 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_DA0__EIM_AD00 0x114 0x428 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_DA0__IPU1_DISP1_DATA09 0x114 0x428 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_DA0__IPU2_CSI1_DATA09 0x114 0x428 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_DA0__GPIO3_IO00 0x114 0x428 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_DA0__SRC_BOOT_CFG00 0x114 0x428 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_DA1__EIM_AD01 0x118 0x42c 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_DA1__IPU1_DISP1_DATA08 0x118 0x42c 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_DA1__IPU2_CSI1_DATA08 0x118 0x42c 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_DA1__GPIO3_IO01 0x118 0x42c 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_DA1__SRC_BOOT_CFG01 0x118 0x42c 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_DA2__EIM_AD02 0x11c 0x430 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_DA2__IPU1_DISP1_DATA07 0x11c 0x430 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_DA2__IPU2_CSI1_DATA07 0x11c 0x430 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_DA2__GPIO3_IO02 0x11c 0x430 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_DA2__SRC_BOOT_CFG02 0x11c 0x430 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_DA3__EIM_AD03 0x120 0x434 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_DA3__IPU1_DISP1_DATA06 0x120 0x434 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_DA3__IPU2_CSI1_DATA06 0x120 0x434 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_DA3__GPIO3_IO03 0x120 0x434 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_DA3__SRC_BOOT_CFG03 0x120 0x434 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_DA4__EIM_AD04 0x124 0x438 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_DA4__IPU1_DISP1_DATA05 0x124 0x438 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_DA4__IPU2_CSI1_DATA05 0x124 0x438 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_DA4__GPIO3_IO04 0x124 0x438 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_DA4__SRC_BOOT_CFG04 0x124 0x438 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_DA5__EIM_AD05 0x128 0x43c 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_DA5__IPU1_DISP1_DATA04 0x128 0x43c 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_DA5__IPU2_CSI1_DATA04 0x128 0x43c 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_DA5__GPIO3_IO05 0x128 0x43c 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_DA5__SRC_BOOT_CFG05 0x128 0x43c 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_DA6__EIM_AD06 0x12c 0x440 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_DA6__IPU1_DISP1_DATA03 0x12c 0x440 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_DA6__IPU2_CSI1_DATA03 0x12c 0x440 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_DA6__GPIO3_IO06 0x12c 0x440 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_DA6__SRC_BOOT_CFG06 0x12c 0x440 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_DA7__EIM_AD07 0x130 0x444 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_DA7__IPU1_DISP1_DATA02 0x130 0x444 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_DA7__IPU2_CSI1_DATA02 0x130 0x444 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_DA7__GPIO3_IO07 0x130 0x444 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_DA7__SRC_BOOT_CFG07 0x130 0x444 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_DA8__EIM_AD08 0x134 0x448 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_DA8__IPU1_DISP1_DATA01 0x134 0x448 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_DA8__IPU2_CSI1_DATA01 0x134 0x448 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_DA8__GPIO3_IO08 0x134 0x448 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_DA8__SRC_BOOT_CFG08 0x134 0x448 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_DA9__EIM_AD09 0x138 0x44c 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_DA9__IPU1_DISP1_DATA00 0x138 0x44c 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_DA9__IPU2_CSI1_DATA00 0x138 0x44c 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_DA9__GPIO3_IO09 0x138 0x44c 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_DA9__SRC_BOOT_CFG09 0x138 0x44c 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_DA10__EIM_AD10 0x13c 0x450 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_DA10__IPU1_DI1_PIN15 0x13c 0x450 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_DA10__IPU2_CSI1_DATA_EN 0x13c 0x450 0x8d8 0x2 0x1
+#define MX6Q_PAD_EIM_DA10__GPIO3_IO10 0x13c 0x450 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_DA10__SRC_BOOT_CFG10 0x13c 0x450 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_DA11__EIM_AD11 0x140 0x454 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_DA11__IPU1_DI1_PIN02 0x140 0x454 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_DA11__IPU2_CSI1_HSYNC 0x140 0x454 0x8dc 0x2 0x1
+#define MX6Q_PAD_EIM_DA11__GPIO3_IO11 0x140 0x454 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_DA11__SRC_BOOT_CFG11 0x140 0x454 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_DA12__EIM_AD12 0x144 0x458 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_DA12__IPU1_DI1_PIN03 0x144 0x458 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_DA12__IPU2_CSI1_VSYNC 0x144 0x458 0x8e4 0x2 0x1
+#define MX6Q_PAD_EIM_DA12__GPIO3_IO12 0x144 0x458 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_DA12__SRC_BOOT_CFG12 0x144 0x458 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_DA13__EIM_AD13 0x148 0x45c 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_DA13__IPU1_DI1_D0_CS 0x148 0x45c 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_DA13__GPIO3_IO13 0x148 0x45c 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_DA13__SRC_BOOT_CFG13 0x148 0x45c 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_DA14__EIM_AD14 0x14c 0x460 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_DA14__IPU1_DI1_D1_CS 0x14c 0x460 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_DA14__GPIO3_IO14 0x14c 0x460 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_DA14__SRC_BOOT_CFG14 0x14c 0x460 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_DA15__EIM_AD15 0x150 0x464 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_DA15__IPU1_DI1_PIN01 0x150 0x464 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_DA15__IPU1_DI1_PIN04 0x150 0x464 0x000 0x2 0x0
+#define MX6Q_PAD_EIM_DA15__GPIO3_IO15 0x150 0x464 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_DA15__SRC_BOOT_CFG15 0x150 0x464 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_WAIT__EIM_WAIT_B 0x154 0x468 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_WAIT__EIM_DTACK_B 0x154 0x468 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_WAIT__GPIO5_IO00 0x154 0x468 0x000 0x5 0x0
+#define MX6Q_PAD_EIM_WAIT__SRC_BOOT_CFG25 0x154 0x468 0x000 0x7 0x0
+#define MX6Q_PAD_EIM_BCLK__EIM_BCLK 0x158 0x46c 0x000 0x0 0x0
+#define MX6Q_PAD_EIM_BCLK__IPU1_DI1_PIN16 0x158 0x46c 0x000 0x1 0x0
+#define MX6Q_PAD_EIM_BCLK__GPIO6_IO31 0x158 0x46c 0x000 0x5 0x0
+#define MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK 0x15c 0x470 0x000 0x0 0x0
+#define MX6Q_PAD_DI0_DISP_CLK__IPU2_DI0_DISP_CLK 0x15c 0x470 0x000 0x1 0x0
+#define MX6Q_PAD_DI0_DISP_CLK__GPIO4_IO16 0x15c 0x470 0x000 0x5 0x0
+#define MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15 0x160 0x474 0x000 0x0 0x0
+#define MX6Q_PAD_DI0_PIN15__IPU2_DI0_PIN15 0x160 0x474 0x000 0x1 0x0
+#define MX6Q_PAD_DI0_PIN15__AUD6_TXC 0x160 0x474 0x000 0x2 0x0
+#define MX6Q_PAD_DI0_PIN15__GPIO4_IO17 0x160 0x474 0x000 0x5 0x0
+#define MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN02 0x164 0x478 0x000 0x0 0x0
+#define MX6Q_PAD_DI0_PIN2__IPU2_DI0_PIN02 0x164 0x478 0x000 0x1 0x0
+#define MX6Q_PAD_DI0_PIN2__AUD6_TXD 0x164 0x478 0x000 0x2 0x0
+#define MX6Q_PAD_DI0_PIN2__GPIO4_IO18 0x164 0x478 0x000 0x5 0x0
+#define MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN03 0x168 0x47c 0x000 0x0 0x0
+#define MX6Q_PAD_DI0_PIN3__IPU2_DI0_PIN03 0x168 0x47c 0x000 0x1 0x0
+#define MX6Q_PAD_DI0_PIN3__AUD6_TXFS 0x168 0x47c 0x000 0x2 0x0
+#define MX6Q_PAD_DI0_PIN3__GPIO4_IO19 0x168 0x47c 0x000 0x5 0x0
+#define MX6Q_PAD_DI0_PIN4__IPU1_DI0_PIN04 0x16c 0x480 0x000 0x0 0x0
+#define MX6Q_PAD_DI0_PIN4__IPU2_DI0_PIN04 0x16c 0x480 0x000 0x1 0x0
+#define MX6Q_PAD_DI0_PIN4__AUD6_RXD 0x16c 0x480 0x000 0x2 0x0
+#define MX6Q_PAD_DI0_PIN4__SD1_WP 0x16c 0x480 0x94c 0x3 0x0
+#define MX6Q_PAD_DI0_PIN4__GPIO4_IO20 0x16c 0x480 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DATA00 0x170 0x484 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT0__IPU2_DISP0_DATA00 0x170 0x484 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT0__ECSPI3_SCLK 0x170 0x484 0x000 0x2 0x0
+#define MX6Q_PAD_DISP0_DAT0__GPIO4_IO21 0x170 0x484 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DATA01 0x174 0x488 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT1__IPU2_DISP0_DATA01 0x174 0x488 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT1__ECSPI3_MOSI 0x174 0x488 0x000 0x2 0x0
+#define MX6Q_PAD_DISP0_DAT1__GPIO4_IO22 0x174 0x488 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DATA02 0x178 0x48c 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT2__IPU2_DISP0_DATA02 0x178 0x48c 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT2__ECSPI3_MISO 0x178 0x48c 0x000 0x2 0x0
+#define MX6Q_PAD_DISP0_DAT2__GPIO4_IO23 0x178 0x48c 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DATA03 0x17c 0x490 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT3__IPU2_DISP0_DATA03 0x17c 0x490 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT3__ECSPI3_SS0 0x17c 0x490 0x000 0x2 0x0
+#define MX6Q_PAD_DISP0_DAT3__GPIO4_IO24 0x17c 0x490 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT4__IPU1_DISP0_DATA04 0x180 0x494 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT4__IPU2_DISP0_DATA04 0x180 0x494 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT4__ECSPI3_SS1 0x180 0x494 0x000 0x2 0x0
+#define MX6Q_PAD_DISP0_DAT4__GPIO4_IO25 0x180 0x494 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT5__IPU1_DISP0_DATA05 0x184 0x498 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT5__IPU2_DISP0_DATA05 0x184 0x498 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT5__ECSPI3_SS2 0x184 0x498 0x000 0x2 0x0
+#define MX6Q_PAD_DISP0_DAT5__AUD6_RXFS 0x184 0x498 0x000 0x3 0x0
+#define MX6Q_PAD_DISP0_DAT5__GPIO4_IO26 0x184 0x498 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT6__IPU1_DISP0_DATA06 0x188 0x49c 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT6__IPU2_DISP0_DATA06 0x188 0x49c 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT6__ECSPI3_SS3 0x188 0x49c 0x000 0x2 0x0
+#define MX6Q_PAD_DISP0_DAT6__AUD6_RXC 0x188 0x49c 0x000 0x3 0x0
+#define MX6Q_PAD_DISP0_DAT6__GPIO4_IO27 0x188 0x49c 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT7__IPU1_DISP0_DATA07 0x18c 0x4a0 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT7__IPU2_DISP0_DATA07 0x18c 0x4a0 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT7__ECSPI3_RDY 0x18c 0x4a0 0x000 0x2 0x0
+#define MX6Q_PAD_DISP0_DAT7__GPIO4_IO28 0x18c 0x4a0 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT8__IPU1_DISP0_DATA08 0x190 0x4a4 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT8__IPU2_DISP0_DATA08 0x190 0x4a4 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT8__PWM1_OUT 0x190 0x4a4 0x000 0x2 0x0
+#define MX6Q_PAD_DISP0_DAT8__WDOG1_B 0x190 0x4a4 0x000 0x3 0x0
+#define MX6Q_PAD_DISP0_DAT8__GPIO4_IO29 0x190 0x4a4 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT9__IPU1_DISP0_DATA09 0x194 0x4a8 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT9__IPU2_DISP0_DATA09 0x194 0x4a8 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT9__PWM2_OUT 0x194 0x4a8 0x000 0x2 0x0
+#define MX6Q_PAD_DISP0_DAT9__WDOG2_B 0x194 0x4a8 0x000 0x3 0x0
+#define MX6Q_PAD_DISP0_DAT9__GPIO4_IO30 0x194 0x4a8 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT10__IPU1_DISP0_DATA10 0x198 0x4ac 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT10__IPU2_DISP0_DATA10 0x198 0x4ac 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT10__GPIO4_IO31 0x198 0x4ac 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT11__IPU1_DISP0_DATA11 0x19c 0x4b0 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT11__IPU2_DISP0_DATA11 0x19c 0x4b0 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT11__GPIO5_IO05 0x19c 0x4b0 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT12__IPU1_DISP0_DATA12 0x1a0 0x4b4 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT12__IPU2_DISP0_DATA12 0x1a0 0x4b4 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT12__GPIO5_IO06 0x1a0 0x4b4 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT13__IPU1_DISP0_DATA13 0x1a4 0x4b8 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT13__IPU2_DISP0_DATA13 0x1a4 0x4b8 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT13__AUD5_RXFS 0x1a4 0x4b8 0x7d8 0x3 0x1
+#define MX6Q_PAD_DISP0_DAT13__GPIO5_IO07 0x1a4 0x4b8 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT14__IPU1_DISP0_DATA14 0x1a8 0x4bc 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT14__IPU2_DISP0_DATA14 0x1a8 0x4bc 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT14__AUD5_RXC 0x1a8 0x4bc 0x7d4 0x3 0x1
+#define MX6Q_PAD_DISP0_DAT14__GPIO5_IO08 0x1a8 0x4bc 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT15__IPU1_DISP0_DATA15 0x1ac 0x4c0 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT15__IPU2_DISP0_DATA15 0x1ac 0x4c0 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT15__ECSPI1_SS1 0x1ac 0x4c0 0x804 0x2 0x1
+#define MX6Q_PAD_DISP0_DAT15__ECSPI2_SS1 0x1ac 0x4c0 0x820 0x3 0x1
+#define MX6Q_PAD_DISP0_DAT15__GPIO5_IO09 0x1ac 0x4c0 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT16__IPU1_DISP0_DATA16 0x1b0 0x4c4 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT16__IPU2_DISP0_DATA16 0x1b0 0x4c4 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT16__ECSPI2_MOSI 0x1b0 0x4c4 0x818 0x2 0x1
+#define MX6Q_PAD_DISP0_DAT16__AUD5_TXC 0x1b0 0x4c4 0x7dc 0x3 0x0
+#define MX6Q_PAD_DISP0_DAT16__SDMA_EXT_EVENT0 0x1b0 0x4c4 0x90c 0x4 0x0
+#define MX6Q_PAD_DISP0_DAT16__GPIO5_IO10 0x1b0 0x4c4 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT17__IPU1_DISP0_DATA17 0x1b4 0x4c8 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT17__IPU2_DISP0_DATA17 0x1b4 0x4c8 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT17__ECSPI2_MISO 0x1b4 0x4c8 0x814 0x2 0x1
+#define MX6Q_PAD_DISP0_DAT17__AUD5_TXD 0x1b4 0x4c8 0x7d0 0x3 0x0
+#define MX6Q_PAD_DISP0_DAT17__SDMA_EXT_EVENT1 0x1b4 0x4c8 0x910 0x4 0x0
+#define MX6Q_PAD_DISP0_DAT17__GPIO5_IO11 0x1b4 0x4c8 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT18__IPU1_DISP0_DATA18 0x1b8 0x4cc 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT18__IPU2_DISP0_DATA18 0x1b8 0x4cc 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT18__ECSPI2_SS0 0x1b8 0x4cc 0x81c 0x2 0x1
+#define MX6Q_PAD_DISP0_DAT18__AUD5_TXFS 0x1b8 0x4cc 0x7e0 0x3 0x0
+#define MX6Q_PAD_DISP0_DAT18__AUD4_RXFS 0x1b8 0x4cc 0x7c0 0x4 0x0
+#define MX6Q_PAD_DISP0_DAT18__GPIO5_IO12 0x1b8 0x4cc 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT18__EIM_CS2_B 0x1b8 0x4cc 0x000 0x7 0x0
+#define MX6Q_PAD_DISP0_DAT19__IPU1_DISP0_DATA19 0x1bc 0x4d0 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT19__IPU2_DISP0_DATA19 0x1bc 0x4d0 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT19__ECSPI2_SCLK 0x1bc 0x4d0 0x810 0x2 0x1
+#define MX6Q_PAD_DISP0_DAT19__AUD5_RXD 0x1bc 0x4d0 0x7cc 0x3 0x0
+#define MX6Q_PAD_DISP0_DAT19__AUD4_RXC 0x1bc 0x4d0 0x7bc 0x4 0x0
+#define MX6Q_PAD_DISP0_DAT19__GPIO5_IO13 0x1bc 0x4d0 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT19__EIM_CS3_B 0x1bc 0x4d0 0x000 0x7 0x0
+#define MX6Q_PAD_DISP0_DAT20__IPU1_DISP0_DATA20 0x1c0 0x4d4 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT20__IPU2_DISP0_DATA20 0x1c0 0x4d4 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT20__ECSPI1_SCLK 0x1c0 0x4d4 0x7f4 0x2 0x1
+#define MX6Q_PAD_DISP0_DAT20__AUD4_TXC 0x1c0 0x4d4 0x7c4 0x3 0x0
+#define MX6Q_PAD_DISP0_DAT20__GPIO5_IO14 0x1c0 0x4d4 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT21__IPU1_DISP0_DATA21 0x1c4 0x4d8 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT21__IPU2_DISP0_DATA21 0x1c4 0x4d8 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT21__ECSPI1_MOSI 0x1c4 0x4d8 0x7fc 0x2 0x1
+#define MX6Q_PAD_DISP0_DAT21__AUD4_TXD 0x1c4 0x4d8 0x7b8 0x3 0x1
+#define MX6Q_PAD_DISP0_DAT21__GPIO5_IO15 0x1c4 0x4d8 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DATA22 0x1c8 0x4dc 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT22__IPU2_DISP0_DATA22 0x1c8 0x4dc 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT22__ECSPI1_MISO 0x1c8 0x4dc 0x7f8 0x2 0x1
+#define MX6Q_PAD_DISP0_DAT22__AUD4_TXFS 0x1c8 0x4dc 0x7c8 0x3 0x1
+#define MX6Q_PAD_DISP0_DAT22__GPIO5_IO16 0x1c8 0x4dc 0x000 0x5 0x0
+#define MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DATA23 0x1cc 0x4e0 0x000 0x0 0x0
+#define MX6Q_PAD_DISP0_DAT23__IPU2_DISP0_DATA23 0x1cc 0x4e0 0x000 0x1 0x0
+#define MX6Q_PAD_DISP0_DAT23__ECSPI1_SS0 0x1cc 0x4e0 0x800 0x2 0x1
+#define MX6Q_PAD_DISP0_DAT23__AUD4_RXD 0x1cc 0x4e0 0x7b4 0x3 0x1
+#define MX6Q_PAD_DISP0_DAT23__GPIO5_IO17 0x1cc 0x4e0 0x000 0x5 0x0
+#define MX6Q_PAD_ENET_MDIO__ENET_MDIO 0x1d0 0x4e4 0x840 0x1 0x0
+#define MX6Q_PAD_ENET_MDIO__ESAI_RX_CLK 0x1d0 0x4e4 0x86c 0x2 0x0
+#define MX6Q_PAD_ENET_MDIO__ENET_1588_EVENT1_OUT 0x1d0 0x4e4 0x000 0x4 0x0
+#define MX6Q_PAD_ENET_MDIO__GPIO1_IO22 0x1d0 0x4e4 0x000 0x5 0x0
+#define MX6Q_PAD_ENET_MDIO__SPDIF_LOCK 0x1d0 0x4e4 0x000 0x6 0x0
+#define MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1d4 0x4e8 0x000 0x1 0x0
+#define MX6Q_PAD_ENET_REF_CLK__ESAI_RX_FS 0x1d4 0x4e8 0x85c 0x2 0x0
+#define MX6Q_PAD_ENET_REF_CLK__GPIO1_IO23 0x1d4 0x4e8 0x000 0x5 0x0
+#define MX6Q_PAD_ENET_REF_CLK__SPDIF_SR_CLK 0x1d4 0x4e8 0x000 0x6 0x0
+#define MX6Q_PAD_ENET_RX_ER__USB_OTG_ID 0x1d8 0x4ec 0x000 0x0 0x0
+#define MX6Q_PAD_ENET_RX_ER__ENET_RX_ER 0x1d8 0x4ec 0x000 0x1 0x0
+#define MX6Q_PAD_ENET_RX_ER__ESAI_RX_HF_CLK 0x1d8 0x4ec 0x864 0x2 0x0
+#define MX6Q_PAD_ENET_RX_ER__SPDIF_IN 0x1d8 0x4ec 0x914 0x3 0x1
+#define MX6Q_PAD_ENET_RX_ER__ENET_1588_EVENT2_OUT 0x1d8 0x4ec 0x000 0x4 0x0
+#define MX6Q_PAD_ENET_RX_ER__GPIO1_IO24 0x1d8 0x4ec 0x000 0x5 0x0
+#define MX6Q_PAD_ENET_CRS_DV__ENET_RX_EN 0x1dc 0x4f0 0x858 0x1 0x1
+#define MX6Q_PAD_ENET_CRS_DV__ESAI_TX_CLK 0x1dc 0x4f0 0x870 0x2 0x0
+#define MX6Q_PAD_ENET_CRS_DV__SPDIF_EXT_CLK 0x1dc 0x4f0 0x918 0x3 0x1
+#define MX6Q_PAD_ENET_CRS_DV__GPIO1_IO25 0x1dc 0x4f0 0x000 0x5 0x0
+#define MX6Q_PAD_ENET_RXD1__MLB_SIG 0x1e0 0x4f4 0x908 0x0 0x0
+#define MX6Q_PAD_ENET_RXD1__ENET_RX_DATA1 0x1e0 0x4f4 0x84c 0x1 0x1
+#define MX6Q_PAD_ENET_RXD1__ESAI_TX_FS 0x1e0 0x4f4 0x860 0x2 0x0
+#define MX6Q_PAD_ENET_RXD1__ENET_1588_EVENT3_OUT 0x1e0 0x4f4 0x000 0x4 0x0
+#define MX6Q_PAD_ENET_RXD1__GPIO1_IO26 0x1e0 0x4f4 0x000 0x5 0x0
+#define MX6Q_PAD_ENET_RXD0__ENET_RX_DATA0 0x1e4 0x4f8 0x848 0x1 0x1
+#define MX6Q_PAD_ENET_RXD0__ESAI_TX_HF_CLK 0x1e4 0x4f8 0x868 0x2 0x0
+#define MX6Q_PAD_ENET_RXD0__SPDIF_OUT 0x1e4 0x4f8 0x000 0x3 0x0
+#define MX6Q_PAD_ENET_RXD0__GPIO1_IO27 0x1e4 0x4f8 0x000 0x5 0x0
+#define MX6Q_PAD_ENET_TX_EN__ENET_TX_EN 0x1e8 0x4fc 0x000 0x1 0x0
+#define MX6Q_PAD_ENET_TX_EN__ESAI_TX3_RX2 0x1e8 0x4fc 0x880 0x2 0x0
+#define MX6Q_PAD_ENET_TX_EN__GPIO1_IO28 0x1e8 0x4fc 0x000 0x5 0x0
+#define MX6Q_PAD_ENET_TXD1__MLB_CLK 0x1ec 0x500 0x900 0x0 0x0
+#define MX6Q_PAD_ENET_TXD1__ENET_TX_DATA1 0x1ec 0x500 0x000 0x1 0x0
+#define MX6Q_PAD_ENET_TXD1__ESAI_TX2_RX3 0x1ec 0x500 0x87c 0x2 0x0
+#define MX6Q_PAD_ENET_TXD1__ENET_1588_EVENT0_IN 0x1ec 0x500 0x000 0x4 0x0
+#define MX6Q_PAD_ENET_TXD1__GPIO1_IO29 0x1ec 0x500 0x000 0x5 0x0
+#define MX6Q_PAD_ENET_TXD0__ENET_TX_DATA0 0x1f0 0x504 0x000 0x1 0x0
+#define MX6Q_PAD_ENET_TXD0__ESAI_TX4_RX1 0x1f0 0x504 0x884 0x2 0x0
+#define MX6Q_PAD_ENET_TXD0__GPIO1_IO30 0x1f0 0x504 0x000 0x5 0x0
+#define MX6Q_PAD_ENET_MDC__MLB_DATA 0x1f4 0x508 0x904 0x0 0x0
+#define MX6Q_PAD_ENET_MDC__ENET_MDC 0x1f4 0x508 0x000 0x1 0x0
+#define MX6Q_PAD_ENET_MDC__ESAI_TX5_RX0 0x1f4 0x508 0x888 0x2 0x0
+#define MX6Q_PAD_ENET_MDC__ENET_1588_EVENT1_IN 0x1f4 0x508 0x000 0x4 0x0
+#define MX6Q_PAD_ENET_MDC__GPIO1_IO31 0x1f4 0x508 0x000 0x5 0x0
+#define MX6Q_PAD_KEY_COL0__ECSPI1_SCLK 0x1f8 0x5c8 0x7f4 0x0 0x2
+#define MX6Q_PAD_KEY_COL0__ENET_RX_DATA3 0x1f8 0x5c8 0x854 0x1 0x1
+#define MX6Q_PAD_KEY_COL0__AUD5_TXC 0x1f8 0x5c8 0x7dc 0x2 0x1
+#define MX6Q_PAD_KEY_COL0__KEY_COL0 0x1f8 0x5c8 0x000 0x3 0x0
+#define MX6Q_PAD_KEY_COL0__UART4_TX_DATA 0x1f8 0x5c8 0x000 0x4 0x0
+#define MX6Q_PAD_KEY_COL0__UART4_RX_DATA 0x1f8 0x5c8 0x938 0x4 0x0
+#define MX6Q_PAD_KEY_COL0__GPIO4_IO06 0x1f8 0x5c8 0x000 0x5 0x0
+#define MX6Q_PAD_KEY_COL0__DCIC1_OUT 0x1f8 0x5c8 0x000 0x6 0x0
+#define MX6Q_PAD_KEY_ROW0__ECSPI1_MOSI 0x1fc 0x5cc 0x7fc 0x0 0x2
+#define MX6Q_PAD_KEY_ROW0__ENET_TX_DATA3 0x1fc 0x5cc 0x000 0x1 0x0
+#define MX6Q_PAD_KEY_ROW0__AUD5_TXD 0x1fc 0x5cc 0x7d0 0x2 0x1
+#define MX6Q_PAD_KEY_ROW0__KEY_ROW0 0x1fc 0x5cc 0x000 0x3 0x0
+#define MX6Q_PAD_KEY_ROW0__UART4_RX_DATA 0x1fc 0x5cc 0x938 0x4 0x1
+#define MX6Q_PAD_KEY_ROW0__UART4_TX_DATA 0x1fc 0x5cc 0x000 0x4 0x0
+#define MX6Q_PAD_KEY_ROW0__GPIO4_IO07 0x1fc 0x5cc 0x000 0x5 0x0
+#define MX6Q_PAD_KEY_ROW0__DCIC2_OUT 0x1fc 0x5cc 0x000 0x6 0x0
+#define MX6Q_PAD_KEY_COL1__ECSPI1_MISO 0x200 0x5d0 0x7f8 0x0 0x2
+#define MX6Q_PAD_KEY_COL1__ENET_MDIO 0x200 0x5d0 0x840 0x1 0x1
+#define MX6Q_PAD_KEY_COL1__AUD5_TXFS 0x200 0x5d0 0x7e0 0x2 0x1
+#define MX6Q_PAD_KEY_COL1__KEY_COL1 0x200 0x5d0 0x000 0x3 0x0
+#define MX6Q_PAD_KEY_COL1__UART5_TX_DATA 0x200 0x5d0 0x000 0x4 0x0
+#define MX6Q_PAD_KEY_COL1__UART5_RX_DATA 0x200 0x5d0 0x940 0x4 0x0
+#define MX6Q_PAD_KEY_COL1__GPIO4_IO08 0x200 0x5d0 0x000 0x5 0x0
+#define MX6Q_PAD_KEY_COL1__SD1_VSELECT 0x200 0x5d0 0x000 0x6 0x0
+#define MX6Q_PAD_KEY_ROW1__ECSPI1_SS0 0x204 0x5d4 0x800 0x0 0x2
+#define MX6Q_PAD_KEY_ROW1__ENET_COL 0x204 0x5d4 0x000 0x1 0x0
+#define MX6Q_PAD_KEY_ROW1__AUD5_RXD 0x204 0x5d4 0x7cc 0x2 0x1
+#define MX6Q_PAD_KEY_ROW1__KEY_ROW1 0x204 0x5d4 0x000 0x3 0x0
+#define MX6Q_PAD_KEY_ROW1__UART5_RX_DATA 0x204 0x5d4 0x940 0x4 0x1
+#define MX6Q_PAD_KEY_ROW1__UART5_TX_DATA 0x204 0x5d4 0x000 0x4 0x0
+#define MX6Q_PAD_KEY_ROW1__GPIO4_IO09 0x204 0x5d4 0x000 0x5 0x0
+#define MX6Q_PAD_KEY_ROW1__SD2_VSELECT 0x204 0x5d4 0x000 0x6 0x0
+#define MX6Q_PAD_KEY_COL2__ECSPI1_SS1 0x208 0x5d8 0x804 0x0 0x2
+#define MX6Q_PAD_KEY_COL2__ENET_RX_DATA2 0x208 0x5d8 0x850 0x1 0x1
+#define MX6Q_PAD_KEY_COL2__FLEXCAN1_TX 0x208 0x5d8 0x000 0x2 0x0
+#define MX6Q_PAD_KEY_COL2__KEY_COL2 0x208 0x5d8 0x000 0x3 0x0
+#define MX6Q_PAD_KEY_COL2__ENET_MDC 0x208 0x5d8 0x000 0x4 0x0
+#define MX6Q_PAD_KEY_COL2__GPIO4_IO10 0x208 0x5d8 0x000 0x5 0x0
+#define MX6Q_PAD_KEY_COL2__USB_H1_PWR_CTL_WAKE 0x208 0x5d8 0x000 0x6 0x0
+#define MX6Q_PAD_KEY_ROW2__ECSPI1_SS2 0x20c 0x5dc 0x808 0x0 0x1
+#define MX6Q_PAD_KEY_ROW2__ENET_TX_DATA2 0x20c 0x5dc 0x000 0x1 0x0
+#define MX6Q_PAD_KEY_ROW2__FLEXCAN1_RX 0x20c 0x5dc 0x7e4 0x2 0x0
+#define MX6Q_PAD_KEY_ROW2__KEY_ROW2 0x20c 0x5dc 0x000 0x3 0x0
+#define MX6Q_PAD_KEY_ROW2__SD2_VSELECT 0x20c 0x5dc 0x000 0x4 0x0
+#define MX6Q_PAD_KEY_ROW2__GPIO4_IO11 0x20c 0x5dc 0x000 0x5 0x0
+#define MX6Q_PAD_KEY_ROW2__HDMI_TX_CEC_LINE 0x20c 0x5dc 0x88c 0x6 0x1
+#define MX6Q_PAD_KEY_COL3__ECSPI1_SS3 0x210 0x5e0 0x80c 0x0 0x1
+#define MX6Q_PAD_KEY_COL3__ENET_CRS 0x210 0x5e0 0x000 0x1 0x0
+#define MX6Q_PAD_KEY_COL3__HDMI_TX_DDC_SCL 0x210 0x5e0 0x890 0x2 0x1
+#define MX6Q_PAD_KEY_COL3__KEY_COL3 0x210 0x5e0 0x000 0x3 0x0
+#define MX6Q_PAD_KEY_COL3__I2C2_SCL 0x210 0x5e0 0x8a0 0x4 0x1
+#define MX6Q_PAD_KEY_COL3__GPIO4_IO12 0x210 0x5e0 0x000 0x5 0x0
+#define MX6Q_PAD_KEY_COL3__SPDIF_IN 0x210 0x5e0 0x914 0x6 0x2
+#define MX6Q_PAD_KEY_ROW3__ASRC_EXT_CLK 0x214 0x5e4 0x7b0 0x1 0x0
+#define MX6Q_PAD_KEY_ROW3__HDMI_TX_DDC_SDA 0x214 0x5e4 0x894 0x2 0x1
+#define MX6Q_PAD_KEY_ROW3__KEY_ROW3 0x214 0x5e4 0x000 0x3 0x0
+#define MX6Q_PAD_KEY_ROW3__I2C2_SDA 0x214 0x5e4 0x8a4 0x4 0x1
+#define MX6Q_PAD_KEY_ROW3__GPIO4_IO13 0x214 0x5e4 0x000 0x5 0x0
+#define MX6Q_PAD_KEY_ROW3__SD1_VSELECT 0x214 0x5e4 0x000 0x6 0x0
+#define MX6Q_PAD_KEY_COL4__FLEXCAN2_TX 0x218 0x5e8 0x000 0x0 0x0
+#define MX6Q_PAD_KEY_COL4__IPU1_SISG4 0x218 0x5e8 0x000 0x1 0x0
+#define MX6Q_PAD_KEY_COL4__USB_OTG_OC 0x218 0x5e8 0x944 0x2 0x1
+#define MX6Q_PAD_KEY_COL4__KEY_COL4 0x218 0x5e8 0x000 0x3 0x0
+#define MX6Q_PAD_KEY_COL4__UART5_RTS_B 0x218 0x5e8 0x93c 0x4 0x0
+#define MX6Q_PAD_KEY_COL4__UART5_CTS_B 0x218 0x5e8 0x000 0x4 0x0
+#define MX6Q_PAD_KEY_COL4__GPIO4_IO14 0x218 0x5e8 0x000 0x5 0x0
+#define MX6Q_PAD_KEY_ROW4__FLEXCAN2_RX 0x21c 0x5ec 0x7e8 0x0 0x0
+#define MX6Q_PAD_KEY_ROW4__IPU1_SISG5 0x21c 0x5ec 0x000 0x1 0x0
+#define MX6Q_PAD_KEY_ROW4__USB_OTG_PWR 0x21c 0x5ec 0x000 0x2 0x0
+#define MX6Q_PAD_KEY_ROW4__KEY_ROW4 0x21c 0x5ec 0x000 0x3 0x0
+#define MX6Q_PAD_KEY_ROW4__UART5_CTS_B 0x21c 0x5ec 0x000 0x4 0x0
+#define MX6Q_PAD_KEY_ROW4__UART5_RTS_B 0x21c 0x5ec 0x93c 0x4 0x1
+#define MX6Q_PAD_KEY_ROW4__GPIO4_IO15 0x21c 0x5ec 0x000 0x5 0x0
+#define MX6Q_PAD_GPIO_0__CCM_CLKO1 0x220 0x5f0 0x000 0x0 0x0
+#define MX6Q_PAD_GPIO_0__KEY_COL5 0x220 0x5f0 0x8e8 0x2 0x0
+#define MX6Q_PAD_GPIO_0__ASRC_EXT_CLK 0x220 0x5f0 0x7b0 0x3 0x1
+#define MX6Q_PAD_GPIO_0__EPIT1_OUT 0x220 0x5f0 0x000 0x4 0x0
+#define MX6Q_PAD_GPIO_0__GPIO1_IO00 0x220 0x5f0 0x000 0x5 0x0
+#define MX6Q_PAD_GPIO_0__USB_H1_PWR 0x220 0x5f0 0x000 0x6 0x0
+#define MX6Q_PAD_GPIO_0__SNVS_VIO_5 0x220 0x5f0 0x000 0x7 0x0
+#define MX6Q_PAD_GPIO_1__ESAI_RX_CLK 0x224 0x5f4 0x86c 0x0 0x1
+#define MX6Q_PAD_GPIO_1__WDOG2_B 0x224 0x5f4 0x000 0x1 0x0
+#define MX6Q_PAD_GPIO_1__KEY_ROW5 0x224 0x5f4 0x8f4 0x2 0x0
+#define MX6Q_PAD_GPIO_1__USB_OTG_ID 0x224 0x5f4 0x000 0x3 0x0
+#define MX6Q_PAD_GPIO_1__PWM2_OUT 0x224 0x5f4 0x000 0x4 0x0
+#define MX6Q_PAD_GPIO_1__GPIO1_IO01 0x224 0x5f4 0x000 0x5 0x0
+#define MX6Q_PAD_GPIO_1__SD1_CD_B 0x224 0x5f4 0x000 0x6 0x0
+#define MX6Q_PAD_GPIO_9__ESAI_RX_FS 0x228 0x5f8 0x85c 0x0 0x1
+#define MX6Q_PAD_GPIO_9__WDOG1_B 0x228 0x5f8 0x000 0x1 0x0
+#define MX6Q_PAD_GPIO_9__KEY_COL6 0x228 0x5f8 0x8ec 0x2 0x0
+#define MX6Q_PAD_GPIO_9__CCM_REF_EN_B 0x228 0x5f8 0x000 0x3 0x0
+#define MX6Q_PAD_GPIO_9__PWM1_OUT 0x228 0x5f8 0x000 0x4 0x0
+#define MX6Q_PAD_GPIO_9__GPIO1_IO09 0x228 0x5f8 0x000 0x5 0x0
+#define MX6Q_PAD_GPIO_9__SD1_WP 0x228 0x5f8 0x94c 0x6 0x1
+#define MX6Q_PAD_GPIO_3__ESAI_RX_HF_CLK 0x22c 0x5fc 0x864 0x0 0x1
+#define MX6Q_PAD_GPIO_3__I2C3_SCL 0x22c 0x5fc 0x8a8 0x2 0x1
+#define MX6Q_PAD_GPIO_3__XTALOSC_REF_CLK_24M 0x22c 0x5fc 0x000 0x3 0x0
+#define MX6Q_PAD_GPIO_3__CCM_CLKO2 0x22c 0x5fc 0x000 0x4 0x0
+#define MX6Q_PAD_GPIO_3__GPIO1_IO03 0x22c 0x5fc 0x000 0x5 0x0
+#define MX6Q_PAD_GPIO_3__USB_H1_OC 0x22c 0x5fc 0x948 0x6 0x1
+#define MX6Q_PAD_GPIO_3__MLB_CLK 0x22c 0x5fc 0x900 0x7 0x1
+#define MX6Q_PAD_GPIO_6__ESAI_TX_CLK 0x230 0x600 0x870 0x0 0x1
+#define MX6Q_PAD_GPIO_6__I2C3_SDA 0x230 0x600 0x8ac 0x2 0x1
+#define MX6Q_PAD_GPIO_6__GPIO1_IO06 0x230 0x600 0x000 0x5 0x0
+#define MX6Q_PAD_GPIO_6__SD2_LCTL 0x230 0x600 0x000 0x6 0x0
+#define MX6Q_PAD_GPIO_6__MLB_SIG 0x230 0x600 0x908 0x7 0x1
+#define MX6Q_PAD_GPIO_2__ESAI_TX_FS 0x234 0x604 0x860 0x0 0x1
+#define MX6Q_PAD_GPIO_2__KEY_ROW6 0x234 0x604 0x8f8 0x2 0x1
+#define MX6Q_PAD_GPIO_2__GPIO1_IO02 0x234 0x604 0x000 0x5 0x0
+#define MX6Q_PAD_GPIO_2__SD2_WP 0x234 0x604 0x000 0x6 0x0
+#define MX6Q_PAD_GPIO_2__MLB_DATA 0x234 0x604 0x904 0x7 0x1
+#define MX6Q_PAD_GPIO_4__ESAI_TX_HF_CLK 0x238 0x608 0x868 0x0 0x1
+#define MX6Q_PAD_GPIO_4__KEY_COL7 0x238 0x608 0x8f0 0x2 0x1
+#define MX6Q_PAD_GPIO_4__GPIO1_IO04 0x238 0x608 0x000 0x5 0x0
+#define MX6Q_PAD_GPIO_4__SD2_CD_B 0x238 0x608 0x000 0x6 0x0
+#define MX6Q_PAD_GPIO_5__ESAI_TX2_RX3 0x23c 0x60c 0x87c 0x0 0x1
+#define MX6Q_PAD_GPIO_5__KEY_ROW7 0x23c 0x60c 0x8fc 0x2 0x1
+#define MX6Q_PAD_GPIO_5__CCM_CLKO1 0x23c 0x60c 0x000 0x3 0x0
+#define MX6Q_PAD_GPIO_5__GPIO1_IO05 0x23c 0x60c 0x000 0x5 0x0
+#define MX6Q_PAD_GPIO_5__I2C3_SCL 0x23c 0x60c 0x8a8 0x6 0x2
+#define MX6Q_PAD_GPIO_5__ARM_EVENTI 0x23c 0x60c 0x000 0x7 0x0
+#define MX6Q_PAD_GPIO_7__ESAI_TX4_RX1 0x240 0x610 0x884 0x0 0x1
+#define MX6Q_PAD_GPIO_7__ECSPI5_RDY 0x240 0x610 0x000 0x1 0x0
+#define MX6Q_PAD_GPIO_7__EPIT1_OUT 0x240 0x610 0x000 0x2 0x0
+#define MX6Q_PAD_GPIO_7__FLEXCAN1_TX 0x240 0x610 0x000 0x3 0x0
+#define MX6Q_PAD_GPIO_7__UART2_TX_DATA 0x240 0x610 0x000 0x4 0x0
+#define MX6Q_PAD_GPIO_7__UART2_RX_DATA 0x240 0x610 0x928 0x4 0x2
+#define MX6Q_PAD_GPIO_7__GPIO1_IO07 0x240 0x610 0x000 0x5 0x0
+#define MX6Q_PAD_GPIO_7__SPDIF_LOCK 0x240 0x610 0x000 0x6 0x0
+#define MX6Q_PAD_GPIO_7__USB_OTG_HOST_MODE 0x240 0x610 0x000 0x7 0x0
+#define MX6Q_PAD_GPIO_8__ESAI_TX5_RX0 0x244 0x614 0x888 0x0 0x1
+#define MX6Q_PAD_GPIO_8__XTALOSC_REF_CLK_32K 0x244 0x614 0x000 0x1 0x0
+#define MX6Q_PAD_GPIO_8__EPIT2_OUT 0x244 0x614 0x000 0x2 0x0
+#define MX6Q_PAD_GPIO_8__FLEXCAN1_RX 0x244 0x614 0x7e4 0x3 0x1
+#define MX6Q_PAD_GPIO_8__UART2_RX_DATA 0x244 0x614 0x928 0x4 0x3
+#define MX6Q_PAD_GPIO_8__UART2_TX_DATA 0x244 0x614 0x000 0x4 0x0
+#define MX6Q_PAD_GPIO_8__GPIO1_IO08 0x244 0x614 0x000 0x5 0x0
+#define MX6Q_PAD_GPIO_8__SPDIF_SR_CLK 0x244 0x614 0x000 0x6 0x0
+#define MX6Q_PAD_GPIO_8__USB_OTG_PWR_CTL_WAKE 0x244 0x614 0x000 0x7 0x0
+#define MX6Q_PAD_GPIO_16__ESAI_TX3_RX2 0x248 0x618 0x880 0x0 0x1
+#define MX6Q_PAD_GPIO_16__ENET_1588_EVENT2_IN 0x248 0x618 0x000 0x1 0x0
+#define MX6Q_PAD_GPIO_16__ENET_REF_CLK 0x248 0x618 0x83c 0x2 0x1
+#define MX6Q_PAD_GPIO_16__SD1_LCTL 0x248 0x618 0x000 0x3 0x0
+#define MX6Q_PAD_GPIO_16__SPDIF_IN 0x248 0x618 0x914 0x4 0x3
+#define MX6Q_PAD_GPIO_16__GPIO7_IO11 0x248 0x618 0x000 0x5 0x0
+#define MX6Q_PAD_GPIO_16__I2C3_SDA 0x248 0x618 0x8ac 0x6 0x2
+#define MX6Q_PAD_GPIO_16__JTAG_DE_B 0x248 0x618 0x000 0x7 0x0
+#define MX6Q_PAD_GPIO_17__ESAI_TX0 0x24c 0x61c 0x874 0x0 0x0
+#define MX6Q_PAD_GPIO_17__ENET_1588_EVENT3_IN 0x24c 0x61c 0x000 0x1 0x0
+#define MX6Q_PAD_GPIO_17__CCM_PMIC_READY 0x24c 0x61c 0x7f0 0x2 0x1
+#define MX6Q_PAD_GPIO_17__SDMA_EXT_EVENT0 0x24c 0x61c 0x90c 0x3 0x1
+#define MX6Q_PAD_GPIO_17__SPDIF_OUT 0x24c 0x61c 0x000 0x4 0x0
+#define MX6Q_PAD_GPIO_17__GPIO7_IO12 0x24c 0x61c 0x000 0x5 0x0
+#define MX6Q_PAD_GPIO_18__ESAI_TX1 0x250 0x620 0x878 0x0 0x0
+#define MX6Q_PAD_GPIO_18__ENET_RX_CLK 0x250 0x620 0x844 0x1 0x1
+#define MX6Q_PAD_GPIO_18__SD3_VSELECT 0x250 0x620 0x000 0x2 0x0
+#define MX6Q_PAD_GPIO_18__SDMA_EXT_EVENT1 0x250 0x620 0x910 0x3 0x1
+#define MX6Q_PAD_GPIO_18__ASRC_EXT_CLK 0x250 0x620 0x7b0 0x4 0x2
+#define MX6Q_PAD_GPIO_18__GPIO7_IO13 0x250 0x620 0x000 0x5 0x0
+#define MX6Q_PAD_GPIO_18__SNVS_VIO_5_CTL 0x250 0x620 0x000 0x6 0x0
+#define MX6Q_PAD_GPIO_19__KEY_COL5 0x254 0x624 0x8e8 0x0 0x1
+#define MX6Q_PAD_GPIO_19__ENET_1588_EVENT0_OUT 0x254 0x624 0x000 0x1 0x0
+#define MX6Q_PAD_GPIO_19__SPDIF_OUT 0x254 0x624 0x000 0x2 0x0
+#define MX6Q_PAD_GPIO_19__CCM_CLKO1 0x254 0x624 0x000 0x3 0x0
+#define MX6Q_PAD_GPIO_19__ECSPI1_RDY 0x254 0x624 0x000 0x4 0x0
+#define MX6Q_PAD_GPIO_19__GPIO4_IO05 0x254 0x624 0x000 0x5 0x0
+#define MX6Q_PAD_GPIO_19__ENET_TX_ER 0x254 0x624 0x000 0x6 0x0
+#define MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK 0x258 0x628 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_PIXCLK__GPIO5_IO18 0x258 0x628 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_PIXCLK__ARM_EVENTO 0x258 0x628 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC 0x25c 0x62c 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_MCLK__CCM_CLKO1 0x25c 0x62c 0x000 0x3 0x0
+#define MX6Q_PAD_CSI0_MCLK__GPIO5_IO19 0x25c 0x62c 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_MCLK__ARM_TRACE_CTL 0x25c 0x62c 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN 0x260 0x630 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DATA_EN__EIM_DATA00 0x260 0x630 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DATA_EN__GPIO5_IO20 0x260 0x630 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_DATA_EN__ARM_TRACE_CLK 0x260 0x630 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC 0x264 0x634 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_VSYNC__EIM_DATA01 0x264 0x634 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_VSYNC__GPIO5_IO21 0x264 0x634 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_VSYNC__ARM_TRACE00 0x264 0x634 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DAT4__IPU1_CSI0_DATA04 0x268 0x638 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DAT4__EIM_DATA02 0x268 0x638 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DAT4__ECSPI1_SCLK 0x268 0x638 0x7f4 0x2 0x3
+#define MX6Q_PAD_CSI0_DAT4__KEY_COL5 0x268 0x638 0x8e8 0x3 0x2
+#define MX6Q_PAD_CSI0_DAT4__AUD3_TXC 0x268 0x638 0x000 0x4 0x0
+#define MX6Q_PAD_CSI0_DAT4__GPIO5_IO22 0x268 0x638 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_DAT4__ARM_TRACE01 0x268 0x638 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DAT5__IPU1_CSI0_DATA05 0x26c 0x63c 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DAT5__EIM_DATA03 0x26c 0x63c 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DAT5__ECSPI1_MOSI 0x26c 0x63c 0x7fc 0x2 0x3
+#define MX6Q_PAD_CSI0_DAT5__KEY_ROW5 0x26c 0x63c 0x8f4 0x3 0x1
+#define MX6Q_PAD_CSI0_DAT5__AUD3_TXD 0x26c 0x63c 0x000 0x4 0x0
+#define MX6Q_PAD_CSI0_DAT5__GPIO5_IO23 0x26c 0x63c 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_DAT5__ARM_TRACE02 0x26c 0x63c 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DAT6__IPU1_CSI0_DATA06 0x270 0x640 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DAT6__EIM_DATA04 0x270 0x640 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DAT6__ECSPI1_MISO 0x270 0x640 0x7f8 0x2 0x3
+#define MX6Q_PAD_CSI0_DAT6__KEY_COL6 0x270 0x640 0x8ec 0x3 0x1
+#define MX6Q_PAD_CSI0_DAT6__AUD3_TXFS 0x270 0x640 0x000 0x4 0x0
+#define MX6Q_PAD_CSI0_DAT6__GPIO5_IO24 0x270 0x640 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_DAT6__ARM_TRACE03 0x270 0x640 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DAT7__IPU1_CSI0_DATA07 0x274 0x644 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DAT7__EIM_DATA05 0x274 0x644 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DAT7__ECSPI1_SS0 0x274 0x644 0x800 0x2 0x3
+#define MX6Q_PAD_CSI0_DAT7__KEY_ROW6 0x274 0x644 0x8f8 0x3 0x2
+#define MX6Q_PAD_CSI0_DAT7__AUD3_RXD 0x274 0x644 0x000 0x4 0x0
+#define MX6Q_PAD_CSI0_DAT7__GPIO5_IO25 0x274 0x644 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_DAT7__ARM_TRACE04 0x274 0x644 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DAT8__IPU1_CSI0_DATA08 0x278 0x648 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DAT8__EIM_DATA06 0x278 0x648 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DAT8__ECSPI2_SCLK 0x278 0x648 0x810 0x2 0x2
+#define MX6Q_PAD_CSI0_DAT8__KEY_COL7 0x278 0x648 0x8f0 0x3 0x2
+#define MX6Q_PAD_CSI0_DAT8__I2C1_SDA 0x278 0x648 0x89c 0x4 0x1
+#define MX6Q_PAD_CSI0_DAT8__GPIO5_IO26 0x278 0x648 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_DAT8__ARM_TRACE05 0x278 0x648 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DAT9__IPU1_CSI0_DATA09 0x27c 0x64c 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DAT9__EIM_DATA07 0x27c 0x64c 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DAT9__ECSPI2_MOSI 0x27c 0x64c 0x818 0x2 0x2
+#define MX6Q_PAD_CSI0_DAT9__KEY_ROW7 0x27c 0x64c 0x8fc 0x3 0x2
+#define MX6Q_PAD_CSI0_DAT9__I2C1_SCL 0x27c 0x64c 0x898 0x4 0x1
+#define MX6Q_PAD_CSI0_DAT9__GPIO5_IO27 0x27c 0x64c 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_DAT9__ARM_TRACE06 0x27c 0x64c 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DAT10__IPU1_CSI0_DATA10 0x280 0x650 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DAT10__AUD3_RXC 0x280 0x650 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DAT10__ECSPI2_MISO 0x280 0x650 0x814 0x2 0x2
+#define MX6Q_PAD_CSI0_DAT10__UART1_TX_DATA 0x280 0x650 0x000 0x3 0x0
+#define MX6Q_PAD_CSI0_DAT10__UART1_RX_DATA 0x280 0x650 0x920 0x3 0x0
+#define MX6Q_PAD_CSI0_DAT10__GPIO5_IO28 0x280 0x650 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_DAT10__ARM_TRACE07 0x280 0x650 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DAT11__IPU1_CSI0_DATA11 0x284 0x654 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DAT11__AUD3_RXFS 0x284 0x654 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DAT11__ECSPI2_SS0 0x284 0x654 0x81c 0x2 0x2
+#define MX6Q_PAD_CSI0_DAT11__UART1_RX_DATA 0x284 0x654 0x920 0x3 0x1
+#define MX6Q_PAD_CSI0_DAT11__UART1_TX_DATA 0x284 0x654 0x000 0x3 0x0
+#define MX6Q_PAD_CSI0_DAT11__GPIO5_IO29 0x284 0x654 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_DAT11__ARM_TRACE08 0x284 0x654 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_DATA12 0x288 0x658 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DAT12__EIM_DATA08 0x288 0x658 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DAT12__UART4_TX_DATA 0x288 0x658 0x000 0x3 0x0
+#define MX6Q_PAD_CSI0_DAT12__UART4_RX_DATA 0x288 0x658 0x938 0x3 0x2
+#define MX6Q_PAD_CSI0_DAT12__GPIO5_IO30 0x288 0x658 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_DAT12__ARM_TRACE09 0x288 0x658 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_DATA13 0x28c 0x65c 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DAT13__EIM_DATA09 0x28c 0x65c 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DAT13__UART4_RX_DATA 0x28c 0x65c 0x938 0x3 0x3
+#define MX6Q_PAD_CSI0_DAT13__UART4_TX_DATA 0x28c 0x65c 0x000 0x3 0x0
+#define MX6Q_PAD_CSI0_DAT13__GPIO5_IO31 0x28c 0x65c 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_DAT13__ARM_TRACE10 0x28c 0x65c 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_DATA14 0x290 0x660 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DAT14__EIM_DATA10 0x290 0x660 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DAT14__UART5_TX_DATA 0x290 0x660 0x000 0x3 0x0
+#define MX6Q_PAD_CSI0_DAT14__UART5_RX_DATA 0x290 0x660 0x940 0x3 0x2
+#define MX6Q_PAD_CSI0_DAT14__GPIO6_IO00 0x290 0x660 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_DAT14__ARM_TRACE11 0x290 0x660 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_DATA15 0x294 0x664 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DAT15__EIM_DATA11 0x294 0x664 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DAT15__UART5_RX_DATA 0x294 0x664 0x940 0x3 0x3
+#define MX6Q_PAD_CSI0_DAT15__UART5_TX_DATA 0x294 0x664 0x000 0x3 0x0
+#define MX6Q_PAD_CSI0_DAT15__GPIO6_IO01 0x294 0x664 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_DAT15__ARM_TRACE12 0x294 0x664 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_DATA16 0x298 0x668 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DAT16__EIM_DATA12 0x298 0x668 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DAT16__UART4_RTS_B 0x298 0x668 0x934 0x3 0x0
+#define MX6Q_PAD_CSI0_DAT16__UART4_CTS_B 0x298 0x668 0x000 0x3 0x0
+#define MX6Q_PAD_CSI0_DAT16__GPIO6_IO02 0x298 0x668 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_DAT16__ARM_TRACE13 0x298 0x668 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_DATA17 0x29c 0x66c 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DAT17__EIM_DATA13 0x29c 0x66c 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DAT17__UART4_CTS_B 0x29c 0x66c 0x000 0x3 0x0
+#define MX6Q_PAD_CSI0_DAT17__UART4_RTS_B 0x29c 0x66c 0x934 0x3 0x1
+#define MX6Q_PAD_CSI0_DAT17__GPIO6_IO03 0x29c 0x66c 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_DAT17__ARM_TRACE14 0x29c 0x66c 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_DATA18 0x2a0 0x670 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DAT18__EIM_DATA14 0x2a0 0x670 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DAT18__UART5_RTS_B 0x2a0 0x670 0x93c 0x3 0x2
+#define MX6Q_PAD_CSI0_DAT18__UART5_CTS_B 0x2a0 0x670 0x000 0x3 0x0
+#define MX6Q_PAD_CSI0_DAT18__GPIO6_IO04 0x2a0 0x670 0x000 0x5 0x0
+#define MX6Q_PAD_CSI0_DAT18__ARM_TRACE15 0x2a0 0x670 0x000 0x7 0x0
+#define MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_DATA19 0x2a4 0x674 0x000 0x0 0x0
+#define MX6Q_PAD_CSI0_DAT19__EIM_DATA15 0x2a4 0x674 0x000 0x1 0x0
+#define MX6Q_PAD_CSI0_DAT19__UART5_CTS_B 0x2a4 0x674 0x000 0x3 0x0
+#define MX6Q_PAD_CSI0_DAT19__UART5_RTS_B 0x2a4 0x674 0x93c 0x3 0x3
+#define MX6Q_PAD_CSI0_DAT19__GPIO6_IO05 0x2a4 0x674 0x000 0x5 0x0
+#define MX6Q_PAD_SD3_DAT7__SD3_DATA7 0x2a8 0x690 0x000 0x0 0x0
+#define MX6Q_PAD_SD3_DAT7__UART1_TX_DATA 0x2a8 0x690 0x000 0x1 0x0
+#define MX6Q_PAD_SD3_DAT7__UART1_RX_DATA 0x2a8 0x690 0x920 0x1 0x2
+#define MX6Q_PAD_SD3_DAT7__GPIO6_IO17 0x2a8 0x690 0x000 0x5 0x0
+#define MX6Q_PAD_SD3_DAT6__SD3_DATA6 0x2ac 0x694 0x000 0x0 0x0
+#define MX6Q_PAD_SD3_DAT6__UART1_RX_DATA 0x2ac 0x694 0x920 0x1 0x3
+#define MX6Q_PAD_SD3_DAT6__UART1_TX_DATA 0x2ac 0x694 0x000 0x1 0x0
+#define MX6Q_PAD_SD3_DAT6__GPIO6_IO18 0x2ac 0x694 0x000 0x5 0x0
+#define MX6Q_PAD_SD3_DAT5__SD3_DATA5 0x2b0 0x698 0x000 0x0 0x0
+#define MX6Q_PAD_SD3_DAT5__UART2_TX_DATA 0x2b0 0x698 0x000 0x1 0x0
+#define MX6Q_PAD_SD3_DAT5__UART2_RX_DATA 0x2b0 0x698 0x928 0x1 0x4
+#define MX6Q_PAD_SD3_DAT5__GPIO7_IO00 0x2b0 0x698 0x000 0x5 0x0
+#define MX6Q_PAD_SD3_DAT4__SD3_DATA4 0x2b4 0x69c 0x000 0x0 0x0
+#define MX6Q_PAD_SD3_DAT4__UART2_RX_DATA 0x2b4 0x69c 0x928 0x1 0x5
+#define MX6Q_PAD_SD3_DAT4__UART2_TX_DATA 0x2b4 0x69c 0x000 0x1 0x0
+#define MX6Q_PAD_SD3_DAT4__GPIO7_IO01 0x2b4 0x69c 0x000 0x5 0x0
+#define MX6Q_PAD_SD3_CMD__SD3_CMD 0x2b8 0x6a0 0x000 0x0 0x0
+#define MX6Q_PAD_SD3_CMD__UART2_CTS_B 0x2b8 0x6a0 0x000 0x1 0x0
+#define MX6Q_PAD_SD3_CMD__UART2_RTS_B 0x2b8 0x6a0 0x924 0x1 0x2
+#define MX6Q_PAD_SD3_CMD__FLEXCAN1_TX 0x2b8 0x6a0 0x000 0x2 0x0
+#define MX6Q_PAD_SD3_CMD__GPIO7_IO02 0x2b8 0x6a0 0x000 0x5 0x0
+#define MX6Q_PAD_SD3_CLK__SD3_CLK 0x2bc 0x6a4 0x000 0x0 0x0
+#define MX6Q_PAD_SD3_CLK__UART2_RTS_B 0x2bc 0x6a4 0x924 0x1 0x3
+#define MX6Q_PAD_SD3_CLK__UART2_CTS_B 0x2bc 0x6a4 0x000 0x1 0x0
+#define MX6Q_PAD_SD3_CLK__FLEXCAN1_RX 0x2bc 0x6a4 0x7e4 0x2 0x2
+#define MX6Q_PAD_SD3_CLK__GPIO7_IO03 0x2bc 0x6a4 0x000 0x5 0x0
+#define MX6Q_PAD_SD3_DAT0__SD3_DATA0 0x2c0 0x6a8 0x000 0x0 0x0
+#define MX6Q_PAD_SD3_DAT0__UART1_CTS_B 0x2c0 0x6a8 0x000 0x1 0x0
+#define MX6Q_PAD_SD3_DAT0__UART1_RTS_B 0x2c0 0x6a8 0x91c 0x1 0x2
+#define MX6Q_PAD_SD3_DAT0__FLEXCAN2_TX 0x2c0 0x6a8 0x000 0x2 0x0
+#define MX6Q_PAD_SD3_DAT0__GPIO7_IO04 0x2c0 0x6a8 0x000 0x5 0x0
+#define MX6Q_PAD_SD3_DAT1__SD3_DATA1 0x2c4 0x6ac 0x000 0x0 0x0
+#define MX6Q_PAD_SD3_DAT1__UART1_RTS_B 0x2c4 0x6ac 0x91c 0x1 0x3
+#define MX6Q_PAD_SD3_DAT1__UART1_CTS_B 0x2c4 0x6ac 0x000 0x1 0x0
+#define MX6Q_PAD_SD3_DAT1__FLEXCAN2_RX 0x2c4 0x6ac 0x7e8 0x2 0x1
+#define MX6Q_PAD_SD3_DAT1__GPIO7_IO05 0x2c4 0x6ac 0x000 0x5 0x0
+#define MX6Q_PAD_SD3_DAT2__SD3_DATA2 0x2c8 0x6b0 0x000 0x0 0x0
+#define MX6Q_PAD_SD3_DAT2__GPIO7_IO06 0x2c8 0x6b0 0x000 0x5 0x0
+#define MX6Q_PAD_SD3_DAT3__SD3_DATA3 0x2cc 0x6b4 0x000 0x0 0x0
+#define MX6Q_PAD_SD3_DAT3__UART3_CTS_B 0x2cc 0x6b4 0x000 0x1 0x0
+#define MX6Q_PAD_SD3_DAT3__UART3_RTS_B 0x2cc 0x6b4 0x92c 0x1 0x4
+#define MX6Q_PAD_SD3_DAT3__GPIO7_IO07 0x2cc 0x6b4 0x000 0x5 0x0
+#define MX6Q_PAD_SD3_RST__SD3_RESET 0x2d0 0x6b8 0x000 0x0 0x0
+#define MX6Q_PAD_SD3_RST__UART3_RTS_B 0x2d0 0x6b8 0x92c 0x1 0x5
+#define MX6Q_PAD_SD3_RST__UART3_CTS_B 0x2d0 0x6b8 0x000 0x1 0x0
+#define MX6Q_PAD_SD3_RST__GPIO7_IO08 0x2d0 0x6b8 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_CLE__NAND_CLE 0x2d4 0x6bc 0x000 0x0 0x0
+#define MX6Q_PAD_NANDF_CLE__IPU2_SISG4 0x2d4 0x6bc 0x000 0x1 0x0
+#define MX6Q_PAD_NANDF_CLE__GPIO6_IO07 0x2d4 0x6bc 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_ALE__NAND_ALE 0x2d8 0x6c0 0x000 0x0 0x0
+#define MX6Q_PAD_NANDF_ALE__SD4_RESET 0x2d8 0x6c0 0x000 0x1 0x0
+#define MX6Q_PAD_NANDF_ALE__GPIO6_IO08 0x2d8 0x6c0 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_WP_B__NAND_WP_B 0x2dc 0x6c4 0x000 0x0 0x0
+#define MX6Q_PAD_NANDF_WP_B__IPU2_SISG5 0x2dc 0x6c4 0x000 0x1 0x0
+#define MX6Q_PAD_NANDF_WP_B__GPIO6_IO09 0x2dc 0x6c4 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_RB0__NAND_READY_B 0x2e0 0x6c8 0x000 0x0 0x0
+#define MX6Q_PAD_NANDF_RB0__IPU2_DI0_PIN01 0x2e0 0x6c8 0x000 0x1 0x0
+#define MX6Q_PAD_NANDF_RB0__GPIO6_IO10 0x2e0 0x6c8 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_CS0__NAND_CE0_B 0x2e4 0x6cc 0x000 0x0 0x0
+#define MX6Q_PAD_NANDF_CS0__GPIO6_IO11 0x2e4 0x6cc 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_CS1__NAND_CE1_B 0x2e8 0x6d0 0x000 0x0 0x0
+#define MX6Q_PAD_NANDF_CS1__SD4_VSELECT 0x2e8 0x6d0 0x000 0x1 0x0
+#define MX6Q_PAD_NANDF_CS1__SD3_VSELECT 0x2e8 0x6d0 0x000 0x2 0x0
+#define MX6Q_PAD_NANDF_CS1__GPIO6_IO14 0x2e8 0x6d0 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_CS2__NAND_CE2_B 0x2ec 0x6d4 0x000 0x0 0x0
+#define MX6Q_PAD_NANDF_CS2__IPU1_SISG0 0x2ec 0x6d4 0x000 0x1 0x0
+#define MX6Q_PAD_NANDF_CS2__ESAI_TX0 0x2ec 0x6d4 0x874 0x2 0x1
+#define MX6Q_PAD_NANDF_CS2__EIM_CRE 0x2ec 0x6d4 0x000 0x3 0x0
+#define MX6Q_PAD_NANDF_CS2__CCM_CLKO2 0x2ec 0x6d4 0x000 0x4 0x0
+#define MX6Q_PAD_NANDF_CS2__GPIO6_IO15 0x2ec 0x6d4 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_CS2__IPU2_SISG0 0x2ec 0x6d4 0x000 0x6 0x0
+#define MX6Q_PAD_NANDF_CS3__NAND_CE3_B 0x2f0 0x6d8 0x000 0x0 0x0
+#define MX6Q_PAD_NANDF_CS3__IPU1_SISG1 0x2f0 0x6d8 0x000 0x1 0x0
+#define MX6Q_PAD_NANDF_CS3__ESAI_TX1 0x2f0 0x6d8 0x878 0x2 0x1
+#define MX6Q_PAD_NANDF_CS3__EIM_ADDR26 0x2f0 0x6d8 0x000 0x3 0x0
+#define MX6Q_PAD_NANDF_CS3__GPIO6_IO16 0x2f0 0x6d8 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_CS3__IPU2_SISG1 0x2f0 0x6d8 0x000 0x6 0x0
+#define MX6Q_PAD_SD4_CMD__SD4_CMD 0x2f4 0x6dc 0x000 0x0 0x0
+#define MX6Q_PAD_SD4_CMD__NAND_RE_B 0x2f4 0x6dc 0x000 0x1 0x0
+#define MX6Q_PAD_SD4_CMD__UART3_TX_DATA 0x2f4 0x6dc 0x000 0x2 0x0
+#define MX6Q_PAD_SD4_CMD__UART3_RX_DATA 0x2f4 0x6dc 0x930 0x2 0x2
+#define MX6Q_PAD_SD4_CMD__GPIO7_IO09 0x2f4 0x6dc 0x000 0x5 0x0
+#define MX6Q_PAD_SD4_CLK__SD4_CLK 0x2f8 0x6e0 0x000 0x0 0x0
+#define MX6Q_PAD_SD4_CLK__NAND_WE_B 0x2f8 0x6e0 0x000 0x1 0x0
+#define MX6Q_PAD_SD4_CLK__UART3_RX_DATA 0x2f8 0x6e0 0x930 0x2 0x3
+#define MX6Q_PAD_SD4_CLK__UART3_TX_DATA 0x2f8 0x6e0 0x000 0x2 0x0
+#define MX6Q_PAD_SD4_CLK__GPIO7_IO10 0x2f8 0x6e0 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_D0__NAND_DATA00 0x2fc 0x6e4 0x000 0x0 0x0
+#define MX6Q_PAD_NANDF_D0__SD1_DATA4 0x2fc 0x6e4 0x000 0x1 0x0
+#define MX6Q_PAD_NANDF_D0__GPIO2_IO00 0x2fc 0x6e4 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_D1__NAND_DATA01 0x300 0x6e8 0x000 0x0 0x0
+#define MX6Q_PAD_NANDF_D1__SD1_DATA5 0x300 0x6e8 0x000 0x1 0x0
+#define MX6Q_PAD_NANDF_D1__GPIO2_IO01 0x300 0x6e8 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_D2__NAND_DATA02 0x304 0x6ec 0x000 0x0 0x0
+#define MX6Q_PAD_NANDF_D2__SD1_DATA6 0x304 0x6ec 0x000 0x1 0x0
+#define MX6Q_PAD_NANDF_D2__GPIO2_IO02 0x304 0x6ec 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_D3__NAND_DATA03 0x308 0x6f0 0x000 0x0 0x0
+#define MX6Q_PAD_NANDF_D3__SD1_DATA7 0x308 0x6f0 0x000 0x1 0x0
+#define MX6Q_PAD_NANDF_D3__GPIO2_IO03 0x308 0x6f0 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_D4__NAND_DATA04 0x30c 0x6f4 0x000 0x0 0x0
+#define MX6Q_PAD_NANDF_D4__SD2_DATA4 0x30c 0x6f4 0x000 0x1 0x0
+#define MX6Q_PAD_NANDF_D4__GPIO2_IO04 0x30c 0x6f4 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_D5__NAND_DATA05 0x310 0x6f8 0x000 0x0 0x0
+#define MX6Q_PAD_NANDF_D5__SD2_DATA5 0x310 0x6f8 0x000 0x1 0x0
+#define MX6Q_PAD_NANDF_D5__GPIO2_IO05 0x310 0x6f8 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_D6__NAND_DATA06 0x314 0x6fc 0x000 0x0 0x0
+#define MX6Q_PAD_NANDF_D6__SD2_DATA6 0x314 0x6fc 0x000 0x1 0x0
+#define MX6Q_PAD_NANDF_D6__GPIO2_IO06 0x314 0x6fc 0x000 0x5 0x0
+#define MX6Q_PAD_NANDF_D7__NAND_DATA07 0x318 0x700 0x000 0x0 0x0
+#define MX6Q_PAD_NANDF_D7__SD2_DATA7 0x318 0x700 0x000 0x1 0x0
+#define MX6Q_PAD_NANDF_D7__GPIO2_IO07 0x318 0x700 0x000 0x5 0x0
+#define MX6Q_PAD_SD4_DAT0__SD4_DATA0 0x31c 0x704 0x000 0x1 0x0
+#define MX6Q_PAD_SD4_DAT0__NAND_DQS 0x31c 0x704 0x000 0x2 0x0
+#define MX6Q_PAD_SD4_DAT0__GPIO2_IO08 0x31c 0x704 0x000 0x5 0x0
+#define MX6Q_PAD_SD4_DAT1__SD4_DATA1 0x320 0x708 0x000 0x1 0x0
+#define MX6Q_PAD_SD4_DAT1__PWM3_OUT 0x320 0x708 0x000 0x2 0x0
+#define MX6Q_PAD_SD4_DAT1__GPIO2_IO09 0x320 0x708 0x000 0x5 0x0
+#define MX6Q_PAD_SD4_DAT2__SD4_DATA2 0x324 0x70c 0x000 0x1 0x0
+#define MX6Q_PAD_SD4_DAT2__PWM4_OUT 0x324 0x70c 0x000 0x2 0x0
+#define MX6Q_PAD_SD4_DAT2__GPIO2_IO10 0x324 0x70c 0x000 0x5 0x0
+#define MX6Q_PAD_SD4_DAT3__SD4_DATA3 0x328 0x710 0x000 0x1 0x0
+#define MX6Q_PAD_SD4_DAT3__GPIO2_IO11 0x328 0x710 0x000 0x5 0x0
+#define MX6Q_PAD_SD4_DAT4__SD4_DATA4 0x32c 0x714 0x000 0x1 0x0
+#define MX6Q_PAD_SD4_DAT4__UART2_RX_DATA 0x32c 0x714 0x928 0x2 0x6
+#define MX6Q_PAD_SD4_DAT4__UART2_TX_DATA 0x32c 0x714 0x000 0x2 0x0
+#define MX6Q_PAD_SD4_DAT4__GPIO2_IO12 0x32c 0x714 0x000 0x5 0x0
+#define MX6Q_PAD_SD4_DAT5__SD4_DATA5 0x330 0x718 0x000 0x1 0x0
+#define MX6Q_PAD_SD4_DAT5__UART2_RTS_B 0x330 0x718 0x924 0x2 0x4
+#define MX6Q_PAD_SD4_DAT5__UART2_CTS_B 0x330 0x718 0x000 0x2 0x0
+#define MX6Q_PAD_SD4_DAT5__GPIO2_IO13 0x330 0x718 0x000 0x5 0x0
+#define MX6Q_PAD_SD4_DAT6__SD4_DATA6 0x334 0x71c 0x000 0x1 0x0
+#define MX6Q_PAD_SD4_DAT6__UART2_CTS_B 0x334 0x71c 0x000 0x2 0x0
+#define MX6Q_PAD_SD4_DAT6__UART2_RTS_B 0x334 0x71c 0x924 0x2 0x5
+#define MX6Q_PAD_SD4_DAT6__GPIO2_IO14 0x334 0x71c 0x000 0x5 0x0
+#define MX6Q_PAD_SD4_DAT7__SD4_DATA7 0x338 0x720 0x000 0x1 0x0
+#define MX6Q_PAD_SD4_DAT7__UART2_TX_DATA 0x338 0x720 0x000 0x2 0x0
+#define MX6Q_PAD_SD4_DAT7__UART2_RX_DATA 0x338 0x720 0x928 0x2 0x7
+#define MX6Q_PAD_SD4_DAT7__GPIO2_IO15 0x338 0x720 0x000 0x5 0x0
+#define MX6Q_PAD_SD1_DAT1__SD1_DATA1 0x33c 0x724 0x000 0x0 0x0
+#define MX6Q_PAD_SD1_DAT1__ECSPI5_SS0 0x33c 0x724 0x834 0x1 0x1
+#define MX6Q_PAD_SD1_DAT1__PWM3_OUT 0x33c 0x724 0x000 0x2 0x0
+#define MX6Q_PAD_SD1_DAT1__GPT_CAPTURE2 0x33c 0x724 0x000 0x3 0x0
+#define MX6Q_PAD_SD1_DAT1__GPIO1_IO17 0x33c 0x724 0x000 0x5 0x0
+#define MX6Q_PAD_SD1_DAT0__SD1_DATA0 0x340 0x728 0x000 0x0 0x0
+#define MX6Q_PAD_SD1_DAT0__ECSPI5_MISO 0x340 0x728 0x82c 0x1 0x1
+#define MX6Q_PAD_SD1_DAT0__GPT_CAPTURE1 0x340 0x728 0x000 0x3 0x0
+#define MX6Q_PAD_SD1_DAT0__GPIO1_IO16 0x340 0x728 0x000 0x5 0x0
+#define MX6Q_PAD_SD1_DAT3__SD1_DATA3 0x344 0x72c 0x000 0x0 0x0
+#define MX6Q_PAD_SD1_DAT3__ECSPI5_SS2 0x344 0x72c 0x000 0x1 0x0
+#define MX6Q_PAD_SD1_DAT3__GPT_COMPARE3 0x344 0x72c 0x000 0x2 0x0
+#define MX6Q_PAD_SD1_DAT3__PWM1_OUT 0x344 0x72c 0x000 0x3 0x0
+#define MX6Q_PAD_SD1_DAT3__WDOG2_B 0x344 0x72c 0x000 0x4 0x0
+#define MX6Q_PAD_SD1_DAT3__GPIO1_IO21 0x344 0x72c 0x000 0x5 0x0
+#define MX6Q_PAD_SD1_DAT3__WDOG2_RESET_B_DEB 0x344 0x72c 0x000 0x6 0x0
+#define MX6Q_PAD_SD1_CMD__SD1_CMD 0x348 0x730 0x000 0x0 0x0
+#define MX6Q_PAD_SD1_CMD__ECSPI5_MOSI 0x348 0x730 0x830 0x1 0x0
+#define MX6Q_PAD_SD1_CMD__PWM4_OUT 0x348 0x730 0x000 0x2 0x0
+#define MX6Q_PAD_SD1_CMD__GPT_COMPARE1 0x348 0x730 0x000 0x3 0x0
+#define MX6Q_PAD_SD1_CMD__GPIO1_IO18 0x348 0x730 0x000 0x5 0x0
+#define MX6Q_PAD_SD1_DAT2__SD1_DATA2 0x34c 0x734 0x000 0x0 0x0
+#define MX6Q_PAD_SD1_DAT2__ECSPI5_SS1 0x34c 0x734 0x838 0x1 0x1
+#define MX6Q_PAD_SD1_DAT2__GPT_COMPARE2 0x34c 0x734 0x000 0x2 0x0
+#define MX6Q_PAD_SD1_DAT2__PWM2_OUT 0x34c 0x734 0x000 0x3 0x0
+#define MX6Q_PAD_SD1_DAT2__WDOG1_B 0x34c 0x734 0x000 0x4 0x0
+#define MX6Q_PAD_SD1_DAT2__GPIO1_IO19 0x34c 0x734 0x000 0x5 0x0
+#define MX6Q_PAD_SD1_DAT2__WDOG1_RESET_B_DEB 0x34c 0x734 0x000 0x6 0x0
+#define MX6Q_PAD_SD1_CLK__SD1_CLK 0x350 0x738 0x000 0x0 0x0
+#define MX6Q_PAD_SD1_CLK__ECSPI5_SCLK 0x350 0x738 0x828 0x1 0x0
+#define MX6Q_PAD_SD1_CLK__GPT_CLKIN 0x350 0x738 0x000 0x3 0x0
+#define MX6Q_PAD_SD1_CLK__GPIO1_IO20 0x350 0x738 0x000 0x5 0x0
+#define MX6Q_PAD_SD2_CLK__SD2_CLK 0x354 0x73c 0x000 0x0 0x0
+#define MX6Q_PAD_SD2_CLK__ECSPI5_SCLK 0x354 0x73c 0x828 0x1 0x1
+#define MX6Q_PAD_SD2_CLK__KEY_COL5 0x354 0x73c 0x8e8 0x2 0x3
+#define MX6Q_PAD_SD2_CLK__AUD4_RXFS 0x354 0x73c 0x7c0 0x3 0x1
+#define MX6Q_PAD_SD2_CLK__GPIO1_IO10 0x354 0x73c 0x000 0x5 0x0
+#define MX6Q_PAD_SD2_CMD__SD2_CMD 0x358 0x740 0x000 0x0 0x0
+#define MX6Q_PAD_SD2_CMD__ECSPI5_MOSI 0x358 0x740 0x830 0x1 0x1
+#define MX6Q_PAD_SD2_CMD__KEY_ROW5 0x358 0x740 0x8f4 0x2 0x2
+#define MX6Q_PAD_SD2_CMD__AUD4_RXC 0x358 0x740 0x7bc 0x3 0x1
+#define MX6Q_PAD_SD2_CMD__GPIO1_IO11 0x358 0x740 0x000 0x5 0x0
+#define MX6Q_PAD_SD2_DAT3__SD2_DATA3 0x35c 0x744 0x000 0x0 0x0
+#define MX6Q_PAD_SD2_DAT3__ECSPI5_SS3 0x35c 0x744 0x000 0x1 0x0
+#define MX6Q_PAD_SD2_DAT3__KEY_COL6 0x35c 0x744 0x8ec 0x2 0x2
+#define MX6Q_PAD_SD2_DAT3__AUD4_TXC 0x35c 0x744 0x7c4 0x3 0x1
+#define MX6Q_PAD_SD2_DAT3__GPIO1_IO12 0x35c 0x744 0x000 0x5 0x0
+
+#endif /* __DTS_IMX6Q_PINFUNC_H */
diff --git a/arch/arm/dts/imx6q-sabrelite.dts b/arch/arm/dts/imx6q-sabrelite.dts
new file mode 100644
index 0000000000..483a39d9a1
--- /dev/null
+++ b/arch/arm/dts/imx6q-sabrelite.dts
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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.dtsi"
+
+/ {
+ model = "Freescale i.MX6 Quad SABRE Lite Board";
+ compatible = "fsl,imx6q-sabrelite", "fsl,imx6q";
+
+ chosen {
+ linux,stdout-path = "/soc/aips-bus@02100000/serial@021e8000";
+ };
+
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ 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>;
+ };
+};
+
+&ecspi1 {
+ fsl,spi-num-chipselects = <1>;
+ cs-gpios = <&gpio3 19 0>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_ecspi1_1>;
+ status = "okay";
+
+ flash: m25p80@0 {
+ compatible = "sst,sst25vf016b", "m25p80";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&ssi1 {
+ fsl,mode = "i2s-slave";
+ status = "okay";
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ hog {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6Q_PAD_NANDF_D6__GPIO2_IO06 0x80000000
+ MX6Q_PAD_NANDF_D7__GPIO2_IO07 0x80000000
+ MX6Q_PAD_EIM_D19__GPIO3_IO19 0x80000000
+ MX6Q_PAD_EIM_D22__GPIO3_IO22 0x80000000
+ MX6Q_PAD_EIM_D23__GPIO3_IO23 0x80000000
+ MX6Q_PAD_SD3_DAT5__GPIO7_IO00 0x80000000
+ MX6Q_PAD_SD3_DAT4__GPIO7_IO01 0x1f0b0
+ MX6Q_PAD_GPIO_0__CCM_CLKO1 0x80000000
+ >;
+ };
+ };
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg_1>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usbh1 {
+ status = "okay";
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet_1>;
+ phy-mode = "rgmii";
+ phy-reset-gpios = <&gpio3 23 0>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3_2>;
+ cd-gpios = <&gpio7 0 0>;
+ wp-gpios = <&gpio7 1 0>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&usdhc4 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc4_2>;
+ cd-gpios = <&gpio2 6 0>;
+ wp-gpios = <&gpio2 7 0>;
+ vmmc-supply = <&reg_3p3v>;
+ status = "okay";
+};
+
+&audmux {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_audmux_1>;
+};
+
+&uart2 {
+ status = "okay";
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart2_1>;
+};
+
+&i2c1 {
+ status = "okay";
+ clock-frequency = <100000>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_i2c1_1>;
+
+ codec: sgtl5000@0a {
+ compatible = "fsl,sgtl5000";
+ reg = <0x0a>;
+ clocks = <&clks 169>;
+ VDDA-supply = <&reg_2p5v>;
+ VDDIO-supply = <&reg_3p3v>;
+ };
+};
diff --git a/arch/arm/dts/imx6q-sabresd.dts b/arch/arm/dts/imx6q-sabresd.dts
new file mode 100644
index 0000000000..1b64ad1c31
--- /dev/null
+++ b/arch/arm/dts/imx6q-sabresd.dts
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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.dtsi"
+#include "imx6qdl-sabresd.dtsi"
+
+/ {
+ model = "Freescale i.MX6 Quad SABRE Smart Device Board";
+ compatible = "fsl,imx6q-sabresd", "fsl,imx6q";
+
+ chosen {
+ linux,stdout-path = "/soc/aips-bus@02000000/spba-bus@02000000/serial@02020000";
+ };
+};
+
+&iomuxc {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_hog>;
+
+ hog {
+ pinctrl_hog: hoggrp {
+ fsl,pins = <
+ MX6Q_PAD_GPIO_4__GPIO1_IO04 0x80000000
+ MX6Q_PAD_GPIO_5__GPIO1_IO05 0x80000000
+ MX6Q_PAD_NANDF_D0__GPIO2_IO00 0x80000000
+ MX6Q_PAD_NANDF_D1__GPIO2_IO01 0x80000000
+ MX6Q_PAD_NANDF_D2__GPIO2_IO02 0x80000000
+ MX6Q_PAD_NANDF_D3__GPIO2_IO03 0x80000000
+ >;
+ };
+ };
+};
diff --git a/arch/arm/dts/imx6q.dtsi b/arch/arm/dts/imx6q.dtsi
new file mode 100644
index 0000000000..21e675848b
--- /dev/null
+++ b/arch/arm/dts/imx6q.dtsi
@@ -0,0 +1,358 @@
+
+/*
+ * Copyright 2013 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include "imx6qdl.dtsi"
+#include "imx6q-pinfunc.h"
+
+/ {
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ reg = <0>;
+ next-level-cache = <&L2>;
+ operating-points = <
+ /* kHz uV */
+ 1200000 1275000
+ 996000 1250000
+ 792000 1150000
+ 396000 950000
+ >;
+ clock-latency = <61036>; /* two CLK32 periods */
+ clocks = <&clks 104>, <&clks 6>, <&clks 16>,
+ <&clks 17>, <&clks 170>;
+ clock-names = "arm", "pll2_pfd2_396m", "step",
+ "pll1_sw", "pll1_sys";
+ arm-supply = <&reg_arm>;
+ pu-supply = <&reg_pu>;
+ soc-supply = <&reg_soc>;
+ };
+
+ cpu@1 {
+ compatible = "arm,cortex-a9";
+ reg = <1>;
+ next-level-cache = <&L2>;
+ };
+
+ cpu@2 {
+ compatible = "arm,cortex-a9";
+ reg = <2>;
+ next-level-cache = <&L2>;
+ };
+
+ cpu@3 {
+ compatible = "arm,cortex-a9";
+ reg = <3>;
+ next-level-cache = <&L2>;
+ };
+ };
+
+ soc {
+ aips-bus@02000000 { /* AIPS1 */
+ spba-bus@02000000 {
+ ecspi5: ecspi@02018000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02018000 0x4000>;
+ interrupts = <0 35 0x04>;
+ clocks = <&clks 116>, <&clks 116>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+ };
+
+ iomuxc: iomuxc@020e0000 {
+ compatible = "fsl,imx6q-iomuxc";
+ reg = <0x020e0000 0x4000>;
+
+ /* shared pinctrl settings */
+ audmux {
+ pinctrl_audmux_1: audmux-1 {
+ fsl,pins = <
+ MX6Q_PAD_SD2_DAT0__AUD4_RXD 0x80000000
+ MX6Q_PAD_SD2_DAT3__AUD4_TXC 0x80000000
+ MX6Q_PAD_SD2_DAT2__AUD4_TXD 0x80000000
+ MX6Q_PAD_SD2_DAT1__AUD4_TXFS 0x80000000
+ >;
+ };
+
+ pinctrl_audmux_2: audmux-2 {
+ fsl,pins = <
+ MX6Q_PAD_CSI0_DAT7__AUD3_RXD 0x80000000
+ MX6Q_PAD_CSI0_DAT4__AUD3_TXC 0x80000000
+ MX6Q_PAD_CSI0_DAT5__AUD3_TXD 0x80000000
+ MX6Q_PAD_CSI0_DAT6__AUD3_TXFS 0x80000000
+ >;
+ };
+ };
+
+ ecspi1 {
+ pinctrl_ecspi1_1: ecspi1grp-1 {
+ fsl,pins = <
+ MX6Q_PAD_EIM_D17__ECSPI1_MISO 0x100b1
+ MX6Q_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
+ MX6Q_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
+ >;
+ };
+ };
+
+ ecspi3 {
+ pinctrl_ecspi3_1: ecspi3grp-1 {
+ fsl,pins = <
+ MX6Q_PAD_DISP0_DAT2__ECSPI3_MISO 0x100b1
+ MX6Q_PAD_DISP0_DAT1__ECSPI3_MOSI 0x100b1
+ MX6Q_PAD_DISP0_DAT0__ECSPI3_SCLK 0x100b1
+ >;
+ };
+ };
+
+ enet {
+ pinctrl_enet_1: enetgrp-1 {
+ fsl,pins = <
+ MX6Q_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
+ MX6Q_PAD_ENET_MDC__ENET_MDC 0x1b0b0
+ MX6Q_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6Q_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6Q_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6Q_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6Q_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6Q_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6Q_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6Q_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6Q_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6Q_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6Q_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ MX6Q_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
+ >;
+ };
+
+ pinctrl_enet_2: enetgrp-2 {
+ fsl,pins = <
+ MX6Q_PAD_KEY_COL1__ENET_MDIO 0x1b0b0
+ MX6Q_PAD_KEY_COL2__ENET_MDC 0x1b0b0
+ MX6Q_PAD_RGMII_TXC__RGMII_TXC 0x1b0b0
+ MX6Q_PAD_RGMII_TD0__RGMII_TD0 0x1b0b0
+ MX6Q_PAD_RGMII_TD1__RGMII_TD1 0x1b0b0
+ MX6Q_PAD_RGMII_TD2__RGMII_TD2 0x1b0b0
+ MX6Q_PAD_RGMII_TD3__RGMII_TD3 0x1b0b0
+ MX6Q_PAD_RGMII_TX_CTL__RGMII_TX_CTL 0x1b0b0
+ MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK 0x1b0b0
+ MX6Q_PAD_RGMII_RXC__RGMII_RXC 0x1b0b0
+ MX6Q_PAD_RGMII_RD0__RGMII_RD0 0x1b0b0
+ MX6Q_PAD_RGMII_RD1__RGMII_RD1 0x1b0b0
+ MX6Q_PAD_RGMII_RD2__RGMII_RD2 0x1b0b0
+ MX6Q_PAD_RGMII_RD3__RGMII_RD3 0x1b0b0
+ MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL 0x1b0b0
+ >;
+ };
+ };
+
+ gpmi-nand {
+ pinctrl_gpmi_nand_1: gpmi-nand-1 {
+ fsl,pins = <
+ MX6Q_PAD_NANDF_CLE__NAND_CLE 0xb0b1
+ MX6Q_PAD_NANDF_ALE__NAND_ALE 0xb0b1
+ MX6Q_PAD_NANDF_WP_B__NAND_WP_B 0xb0b1
+ MX6Q_PAD_NANDF_RB0__NAND_READY_B 0xb000
+ MX6Q_PAD_NANDF_CS0__NAND_CE0_B 0xb0b1
+ MX6Q_PAD_NANDF_CS1__NAND_CE1_B 0xb0b1
+ MX6Q_PAD_NANDF_CS2__NAND_CE2_B 0xb0b1
+ MX6Q_PAD_NANDF_CS3__NAND_CE3_B 0xb0b1
+ MX6Q_PAD_SD4_CMD__NAND_RE_B 0xb0b1
+ MX6Q_PAD_SD4_CLK__NAND_WE_B 0xb0b1
+ MX6Q_PAD_NANDF_D0__NAND_DATA00 0xb0b1
+ MX6Q_PAD_NANDF_D1__NAND_DATA01 0xb0b1
+ MX6Q_PAD_NANDF_D2__NAND_DATA02 0xb0b1
+ MX6Q_PAD_NANDF_D3__NAND_DATA03 0xb0b1
+ MX6Q_PAD_NANDF_D4__NAND_DATA04 0xb0b1
+ MX6Q_PAD_NANDF_D5__NAND_DATA05 0xb0b1
+ MX6Q_PAD_NANDF_D6__NAND_DATA06 0xb0b1
+ MX6Q_PAD_NANDF_D7__NAND_DATA07 0xb0b1
+ MX6Q_PAD_SD4_DAT0__NAND_DQS 0x00b1
+ >;
+ };
+ };
+
+ i2c1 {
+ pinctrl_i2c1_1: i2c1grp-1 {
+ fsl,pins = <
+ MX6Q_PAD_EIM_D21__I2C1_SCL 0x4001b8b1
+ MX6Q_PAD_EIM_D28__I2C1_SDA 0x4001b8b1
+ >;
+ };
+ };
+
+ i2c2 {
+ pinctrl_i2c2_1: i2c2grp-1 {
+ fsl,pins = <
+ MX6Q_PAD_EIM_EB2__I2C2_SCL 0x4001b8b1
+ MX6Q_PAD_EIM_D16__I2C2_SDA 0x4001b8b1
+ >;
+ };
+ };
+
+ i2c3 {
+ pinctrl_i2c3_1: i2c3grp-1 {
+ fsl,pins = <
+ MX6Q_PAD_EIM_D17__I2C3_SCL 0x4001b8b1
+ MX6Q_PAD_EIM_D18__I2C3_SDA 0x4001b8b1
+ >;
+ };
+ };
+
+ uart1 {
+ pinctrl_uart1_1: uart1grp-1 {
+ fsl,pins = <
+ MX6Q_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
+ MX6Q_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
+ >;
+ };
+ };
+
+ uart2 {
+ pinctrl_uart2_1: uart2grp-1 {
+ fsl,pins = <
+ MX6Q_PAD_EIM_D26__UART2_TX_DATA 0x1b0b1
+ MX6Q_PAD_EIM_D27__UART2_RX_DATA 0x1b0b1
+ >;
+ };
+ };
+
+ uart4 {
+ pinctrl_uart4_1: uart4grp-1 {
+ fsl,pins = <
+ MX6Q_PAD_KEY_COL0__UART4_TX_DATA 0x1b0b1
+ MX6Q_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1
+ >;
+ };
+ };
+
+ usbotg {
+ pinctrl_usbotg_1: usbotggrp-1 {
+ fsl,pins = <
+ MX6Q_PAD_GPIO_1__USB_OTG_ID 0x17059
+ >;
+ };
+
+ pinctrl_usbotg_2: usbotggrp-2 {
+ fsl,pins = <
+ MX6Q_PAD_ENET_RX_ER__USB_OTG_ID 0x17059
+ >;
+ };
+ };
+
+ usdhc2 {
+ pinctrl_usdhc2_1: usdhc2grp-1 {
+ fsl,pins = <
+ MX6Q_PAD_SD2_CMD__SD2_CMD 0x17059
+ MX6Q_PAD_SD2_CLK__SD2_CLK 0x10059
+ MX6Q_PAD_SD2_DAT0__SD2_DATA0 0x17059
+ MX6Q_PAD_SD2_DAT1__SD2_DATA1 0x17059
+ MX6Q_PAD_SD2_DAT2__SD2_DATA2 0x17059
+ MX6Q_PAD_SD2_DAT3__SD2_DATA3 0x17059
+ MX6Q_PAD_NANDF_D4__SD2_DATA4 0x17059
+ MX6Q_PAD_NANDF_D5__SD2_DATA5 0x17059
+ MX6Q_PAD_NANDF_D6__SD2_DATA6 0x17059
+ MX6Q_PAD_NANDF_D7__SD2_DATA7 0x17059
+ >;
+ };
+ };
+
+ usdhc3 {
+ pinctrl_usdhc3_1: usdhc3grp-1 {
+ fsl,pins = <
+ MX6Q_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6Q_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6Q_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6Q_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6Q_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6Q_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ MX6Q_PAD_SD3_DAT4__SD3_DATA4 0x17059
+ MX6Q_PAD_SD3_DAT5__SD3_DATA5 0x17059
+ MX6Q_PAD_SD3_DAT6__SD3_DATA6 0x17059
+ MX6Q_PAD_SD3_DAT7__SD3_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc3_2: usdhc3grp-2 {
+ fsl,pins = <
+ MX6Q_PAD_SD3_CMD__SD3_CMD 0x17059
+ MX6Q_PAD_SD3_CLK__SD3_CLK 0x10059
+ MX6Q_PAD_SD3_DAT0__SD3_DATA0 0x17059
+ MX6Q_PAD_SD3_DAT1__SD3_DATA1 0x17059
+ MX6Q_PAD_SD3_DAT2__SD3_DATA2 0x17059
+ MX6Q_PAD_SD3_DAT3__SD3_DATA3 0x17059
+ >;
+ };
+ };
+
+ usdhc4 {
+ pinctrl_usdhc4_1: usdhc4grp-1 {
+ fsl,pins = <
+ MX6Q_PAD_SD4_CMD__SD4_CMD 0x17059
+ MX6Q_PAD_SD4_CLK__SD4_CLK 0x10059
+ MX6Q_PAD_SD4_DAT0__SD4_DATA0 0x17059
+ MX6Q_PAD_SD4_DAT1__SD4_DATA1 0x17059
+ MX6Q_PAD_SD4_DAT2__SD4_DATA2 0x17059
+ MX6Q_PAD_SD4_DAT3__SD4_DATA3 0x17059
+ MX6Q_PAD_SD4_DAT4__SD4_DATA4 0x17059
+ MX6Q_PAD_SD4_DAT5__SD4_DATA5 0x17059
+ MX6Q_PAD_SD4_DAT6__SD4_DATA6 0x17059
+ MX6Q_PAD_SD4_DAT7__SD4_DATA7 0x17059
+ >;
+ };
+
+ pinctrl_usdhc4_2: usdhc4grp-2 {
+ fsl,pins = <
+ MX6Q_PAD_SD4_CMD__SD4_CMD 0x17059
+ MX6Q_PAD_SD4_CLK__SD4_CLK 0x10059
+ MX6Q_PAD_SD4_DAT0__SD4_DATA0 0x17059
+ MX6Q_PAD_SD4_DAT1__SD4_DATA1 0x17059
+ MX6Q_PAD_SD4_DAT2__SD4_DATA2 0x17059
+ MX6Q_PAD_SD4_DAT3__SD4_DATA3 0x17059
+ >;
+ };
+ };
+ };
+ };
+
+ ipu2: ipu@02800000 {
+ #crtc-cells = <1>;
+ compatible = "fsl,imx6q-ipu";
+ reg = <0x02800000 0x400000>;
+ interrupts = <0 8 0x4 0 7 0x4>;
+ clocks = <&clks 133>, <&clks 134>, <&clks 137>;
+ clock-names = "bus", "di0", "di1";
+ resets = <&src 4>;
+ };
+ };
+};
+
+&ldb {
+ clocks = <&clks 33>, <&clks 34>,
+ <&clks 39>, <&clks 40>, <&clks 41>, <&clks 42>,
+ <&clks 135>, <&clks 136>;
+ clock-names = "di0_pll", "di1_pll",
+ "di0_sel", "di1_sel", "di2_sel", "di3_sel",
+ "di0", "di1";
+
+ lvds-channel@0 {
+ crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
+ };
+
+ lvds-channel@1 {
+ crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>;
+ };
+};
diff --git a/arch/arm/dts/imx6qdl-sabresd.dtsi b/arch/arm/dts/imx6qdl-sabresd.dtsi
new file mode 100644
index 0000000000..e21f6a89cf
--- /dev/null
+++ b/arch/arm/dts/imx6qdl-sabresd.dtsi
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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
+ */
+
+/ {
+ memory {
+ reg = <0x10000000 0x40000000>;
+ };
+
+ regulators {
+ compatible = "simple-bus";
+
+ 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;
+ };
+ };
+
+ gpio-keys {
+ compatible = "gpio-keys";
+
+ volume-up {
+ label = "Volume Up";
+ gpios = <&gpio1 4 0>;
+ linux,code = <115>; /* KEY_VOLUMEUP */
+ };
+
+ volume-down {
+ label = "Volume Down";
+ gpios = <&gpio1 5 0>;
+ linux,code = <114>; /* KEY_VOLUMEDOWN */
+ };
+ };
+};
+
+&fec {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_enet_1>;
+ phy-mode = "rgmii";
+ status = "okay";
+};
+
+&uart1 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_uart1_1>;
+ status = "okay";
+};
+
+&usbh1 {
+ status = "okay";
+};
+
+&usbotg {
+ vbus-supply = <&reg_usb_otg_vbus>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usbotg_2>;
+ disable-over-current;
+ status = "okay";
+};
+
+&usdhc2 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc2_1>;
+ cd-gpios = <&gpio2 2 0>;
+ wp-gpios = <&gpio2 3 0>;
+ status = "okay";
+};
+
+&usdhc3 {
+ pinctrl-names = "default";
+ pinctrl-0 = <&pinctrl_usdhc3_1>;
+ cd-gpios = <&gpio2 0 0>;
+ wp-gpios = <&gpio2 1 0>;
+ status = "okay";
+};
diff --git a/arch/arm/dts/imx6qdl.dtsi b/arch/arm/dts/imx6qdl.dtsi
new file mode 100644
index 0000000000..b6360027b3
--- /dev/null
+++ b/arch/arm/dts/imx6qdl.dtsi
@@ -0,0 +1,840 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * Copyright 2011 Linaro Ltd.
+ *
+ * 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 "skeleton.dtsi"
+
+/ {
+ aliases {
+ serial0 = &uart1;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ gpio0 = &gpio1;
+ gpio1 = &gpio2;
+ gpio2 = &gpio3;
+ gpio3 = &gpio4;
+ gpio4 = &gpio5;
+ gpio5 = &gpio6;
+ gpio6 = &gpio7;
+ mmc0 = &usdhc1;
+ mmc1 = &usdhc2;
+ mmc2 = &usdhc3;
+ mmc3 = &usdhc4;
+ };
+
+ intc: interrupt-controller@00a01000 {
+ compatible = "arm,cortex-a9-gic";
+ #interrupt-cells = <3>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ interrupt-controller;
+ reg = <0x00a01000 0x1000>,
+ <0x00a00100 0x100>;
+ };
+
+ clocks {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ckil {
+ compatible = "fsl,imx-ckil", "fixed-clock";
+ clock-frequency = <32768>;
+ };
+
+ ckih1 {
+ compatible = "fsl,imx-ckih1", "fixed-clock";
+ clock-frequency = <0>;
+ };
+
+ osc {
+ compatible = "fsl,imx-osc", "fixed-clock";
+ clock-frequency = <24000000>;
+ };
+ };
+
+ soc {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ interrupt-parent = <&intc>;
+ ranges;
+
+ dma_apbh: dma-apbh@00110000 {
+ compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
+ reg = <0x00110000 0x2000>;
+ interrupts = <0 13 0x04>, <0 13 0x04>, <0 13 0x04>, <0 13 0x04>;
+ interrupt-names = "gpmi0", "gpmi1", "gpmi2", "gpmi3";
+ #dma-cells = <1>;
+ dma-channels = <4>;
+ clocks = <&clks 106>;
+ };
+
+ gpmi: gpmi-nand@00112000 {
+ compatible = "fsl,imx6q-gpmi-nand";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x00112000 0x2000>, <0x00114000 0x2000>;
+ reg-names = "gpmi-nand", "bch";
+ interrupts = <0 13 0x04>, <0 15 0x04>;
+ interrupt-names = "gpmi-dma", "bch";
+ clocks = <&clks 152>, <&clks 153>, <&clks 151>,
+ <&clks 150>, <&clks 149>;
+ clock-names = "gpmi_io", "gpmi_apb", "gpmi_bch",
+ "gpmi_bch_apb", "per1_bch";
+ dmas = <&dma_apbh 0>;
+ dma-names = "rx-tx";
+ fsl,gpmi-dma-channel = <0>;
+ status = "disabled";
+ };
+
+ timer@00a00600 {
+ compatible = "arm,cortex-a9-twd-timer";
+ reg = <0x00a00600 0x20>;
+ interrupts = <1 13 0xf01>;
+ clocks = <&clks 15>;
+ };
+
+ L2: l2-cache@00a02000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x00a02000 0x1000>;
+ interrupts = <0 92 0x04>;
+ cache-unified;
+ cache-level = <2>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a9-pmu";
+ interrupts = <0 94 0x04>;
+ };
+
+ aips-bus@02000000 { /* AIPS1 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02000000 0x100000>;
+ ranges;
+
+ spba-bus@02000000 {
+ compatible = "fsl,spba-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02000000 0x40000>;
+ ranges;
+
+ spdif: spdif@02004000 {
+ reg = <0x02004000 0x4000>;
+ interrupts = <0 52 0x04>;
+ };
+
+ ecspi1: ecspi@02008000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02008000 0x4000>;
+ interrupts = <0 31 0x04>;
+ clocks = <&clks 112>, <&clks 112>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi2: ecspi@0200c000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+ reg = <0x0200c000 0x4000>;
+ interrupts = <0 32 0x04>;
+ clocks = <&clks 113>, <&clks 113>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi3: ecspi@02010000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02010000 0x4000>;
+ interrupts = <0 33 0x04>;
+ clocks = <&clks 114>, <&clks 114>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ ecspi4: ecspi@02014000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-ecspi", "fsl,imx51-ecspi";
+ reg = <0x02014000 0x4000>;
+ interrupts = <0 34 0x04>;
+ clocks = <&clks 115>, <&clks 115>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart1: serial@02020000 {
+ compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x02020000 0x4000>;
+ interrupts = <0 26 0x04>;
+ clocks = <&clks 160>, <&clks 161>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ esai: esai@02024000 {
+ reg = <0x02024000 0x4000>;
+ interrupts = <0 51 0x04>;
+ };
+
+ ssi1: ssi@02028000 {
+ compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
+ reg = <0x02028000 0x4000>;
+ interrupts = <0 46 0x04>;
+ clocks = <&clks 178>;
+ fsl,fifo-depth = <15>;
+ fsl,ssi-dma-events = <38 37>;
+ status = "disabled";
+ };
+
+ ssi2: ssi@0202c000 {
+ compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
+ reg = <0x0202c000 0x4000>;
+ interrupts = <0 47 0x04>;
+ clocks = <&clks 179>;
+ fsl,fifo-depth = <15>;
+ fsl,ssi-dma-events = <42 41>;
+ status = "disabled";
+ };
+
+ ssi3: ssi@02030000 {
+ compatible = "fsl,imx6q-ssi","fsl,imx21-ssi";
+ reg = <0x02030000 0x4000>;
+ interrupts = <0 48 0x04>;
+ clocks = <&clks 180>;
+ fsl,fifo-depth = <15>;
+ fsl,ssi-dma-events = <46 45>;
+ status = "disabled";
+ };
+
+ asrc: asrc@02034000 {
+ reg = <0x02034000 0x4000>;
+ interrupts = <0 50 0x04>;
+ };
+
+ spba@0203c000 {
+ reg = <0x0203c000 0x4000>;
+ };
+ };
+
+ vpu: vpu@02040000 {
+ reg = <0x02040000 0x3c000>;
+ interrupts = <0 3 0x04 0 12 0x04>;
+ };
+
+ aipstz@0207c000 { /* AIPSTZ1 */
+ reg = <0x0207c000 0x4000>;
+ };
+
+ pwm1: pwm@02080000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
+ reg = <0x02080000 0x4000>;
+ interrupts = <0 83 0x04>;
+ clocks = <&clks 62>, <&clks 145>;
+ clock-names = "ipg", "per";
+ };
+
+ pwm2: pwm@02084000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
+ reg = <0x02084000 0x4000>;
+ interrupts = <0 84 0x04>;
+ clocks = <&clks 62>, <&clks 146>;
+ clock-names = "ipg", "per";
+ };
+
+ pwm3: pwm@02088000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
+ reg = <0x02088000 0x4000>;
+ interrupts = <0 85 0x04>;
+ clocks = <&clks 62>, <&clks 147>;
+ clock-names = "ipg", "per";
+ };
+
+ pwm4: pwm@0208c000 {
+ #pwm-cells = <2>;
+ compatible = "fsl,imx6q-pwm", "fsl,imx27-pwm";
+ reg = <0x0208c000 0x4000>;
+ interrupts = <0 86 0x04>;
+ clocks = <&clks 62>, <&clks 148>;
+ clock-names = "ipg", "per";
+ };
+
+ can1: flexcan@02090000 {
+ reg = <0x02090000 0x4000>;
+ interrupts = <0 110 0x04>;
+ };
+
+ can2: flexcan@02094000 {
+ reg = <0x02094000 0x4000>;
+ interrupts = <0 111 0x04>;
+ };
+
+ gpt: gpt@02098000 {
+ compatible = "fsl,imx6q-gpt", "fsl,imx31-gpt";
+ reg = <0x02098000 0x4000>;
+ interrupts = <0 55 0x04>;
+ clocks = <&clks 119>, <&clks 120>;
+ clock-names = "ipg", "per";
+ };
+
+ gpio1: gpio@0209c000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x0209c000 0x4000>;
+ interrupts = <0 66 0x04 0 67 0x04>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio2: gpio@020a0000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020a0000 0x4000>;
+ interrupts = <0 68 0x04 0 69 0x04>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio3: gpio@020a4000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020a4000 0x4000>;
+ interrupts = <0 70 0x04 0 71 0x04>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio4: gpio@020a8000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020a8000 0x4000>;
+ interrupts = <0 72 0x04 0 73 0x04>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio5: gpio@020ac000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020ac000 0x4000>;
+ interrupts = <0 74 0x04 0 75 0x04>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio6: gpio@020b0000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020b0000 0x4000>;
+ interrupts = <0 76 0x04 0 77 0x04>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ gpio7: gpio@020b4000 {
+ compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
+ reg = <0x020b4000 0x4000>;
+ interrupts = <0 78 0x04 0 79 0x04>;
+ gpio-controller;
+ #gpio-cells = <2>;
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ };
+
+ kpp: kpp@020b8000 {
+ reg = <0x020b8000 0x4000>;
+ interrupts = <0 82 0x04>;
+ };
+
+ wdog1: wdog@020bc000 {
+ compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
+ reg = <0x020bc000 0x4000>;
+ interrupts = <0 80 0x04>;
+ clocks = <&clks 0>;
+ };
+
+ wdog2: wdog@020c0000 {
+ compatible = "fsl,imx6q-wdt", "fsl,imx21-wdt";
+ reg = <0x020c0000 0x4000>;
+ interrupts = <0 81 0x04>;
+ clocks = <&clks 0>;
+ status = "disabled";
+ };
+
+ clks: ccm@020c4000 {
+ compatible = "fsl,imx6q-ccm";
+ reg = <0x020c4000 0x4000>;
+ interrupts = <0 87 0x04 0 88 0x04>;
+ #clock-cells = <1>;
+ };
+
+ anatop: anatop@020c8000 {
+ compatible = "fsl,imx6q-anatop", "syscon", "simple-bus";
+ reg = <0x020c8000 0x1000>;
+ interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
+
+ regulator-1p1@110 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd1p1";
+ regulator-min-microvolt = <800000>;
+ regulator-max-microvolt = <1375000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x110>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <4>;
+ anatop-min-voltage = <800000>;
+ anatop-max-voltage = <1375000>;
+ };
+
+ regulator-3p0@120 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd3p0";
+ regulator-min-microvolt = <2800000>;
+ regulator-max-microvolt = <3150000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x120>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <0>;
+ anatop-min-voltage = <2625000>;
+ anatop-max-voltage = <3400000>;
+ };
+
+ regulator-2p5@130 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vdd2p5";
+ regulator-min-microvolt = <2000000>;
+ regulator-max-microvolt = <2750000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x130>;
+ anatop-vol-bit-shift = <8>;
+ anatop-vol-bit-width = <5>;
+ anatop-min-bit-val = <0>;
+ anatop-min-voltage = <2000000>;
+ anatop-max-voltage = <2750000>;
+ };
+
+ reg_arm: regulator-vddcore@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "cpu";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <0>;
+ anatop-vol-bit-width = <5>;
+ anatop-delay-reg-offset = <0x170>;
+ anatop-delay-bit-shift = <24>;
+ anatop-delay-bit-width = <2>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
+
+ reg_pu: regulator-vddpu@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vddpu";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <9>;
+ anatop-vol-bit-width = <5>;
+ anatop-delay-reg-offset = <0x170>;
+ anatop-delay-bit-shift = <26>;
+ anatop-delay-bit-width = <2>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
+
+ reg_soc: regulator-vddsoc@140 {
+ compatible = "fsl,anatop-regulator";
+ regulator-name = "vddsoc";
+ regulator-min-microvolt = <725000>;
+ regulator-max-microvolt = <1450000>;
+ regulator-always-on;
+ anatop-reg-offset = <0x140>;
+ anatop-vol-bit-shift = <18>;
+ anatop-vol-bit-width = <5>;
+ anatop-delay-reg-offset = <0x170>;
+ anatop-delay-bit-shift = <28>;
+ anatop-delay-bit-width = <2>;
+ anatop-min-bit-val = <1>;
+ anatop-min-voltage = <725000>;
+ anatop-max-voltage = <1450000>;
+ };
+ };
+
+ usbphy1: usbphy@020c9000 {
+ compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
+ reg = <0x020c9000 0x1000>;
+ interrupts = <0 44 0x04>;
+ clocks = <&clks 182>;
+ };
+
+ usbphy2: usbphy@020ca000 {
+ compatible = "fsl,imx6q-usbphy", "fsl,imx23-usbphy";
+ reg = <0x020ca000 0x1000>;
+ interrupts = <0 45 0x04>;
+ clocks = <&clks 183>;
+ };
+
+ snvs@020cc000 {
+ compatible = "fsl,sec-v4.0-mon", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0 0x020cc000 0x4000>;
+
+ snvs-rtc-lp@34 {
+ compatible = "fsl,sec-v4.0-mon-rtc-lp";
+ reg = <0x34 0x58>;
+ interrupts = <0 19 0x04 0 20 0x04>;
+ };
+ };
+
+ epit1: epit@020d0000 { /* EPIT1 */
+ reg = <0x020d0000 0x4000>;
+ interrupts = <0 56 0x04>;
+ };
+
+ epit2: epit@020d4000 { /* EPIT2 */
+ reg = <0x020d4000 0x4000>;
+ interrupts = <0 57 0x04>;
+ };
+
+ src: src@020d8000 {
+ compatible = "fsl,imx6q-src", "fsl,imx51-src";
+ reg = <0x020d8000 0x4000>;
+ interrupts = <0 91 0x04 0 96 0x04>;
+ #reset-cells = <1>;
+ };
+
+ gpc: gpc@020dc000 {
+ compatible = "fsl,imx6q-gpc";
+ reg = <0x020dc000 0x4000>;
+ interrupts = <0 89 0x04 0 90 0x04>;
+ };
+
+ gpr: iomuxc-gpr@020e0000 {
+ compatible = "fsl,imx6q-iomuxc-gpr", "syscon";
+ reg = <0x020e0000 0x38>;
+ };
+
+ ldb: ldb@020e0008 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-ldb", "fsl,imx53-ldb";
+ gpr = <&gpr>;
+ status = "disabled";
+
+ lvds-channel@0 {
+ reg = <0>;
+ crtcs = <&ipu1 0>;
+ status = "disabled";
+ };
+
+ lvds-channel@1 {
+ reg = <1>;
+ crtcs = <&ipu1 1>;
+ status = "disabled";
+ };
+ };
+
+ dcic1: dcic@020e4000 {
+ reg = <0x020e4000 0x4000>;
+ interrupts = <0 124 0x04>;
+ };
+
+ dcic2: dcic@020e8000 {
+ reg = <0x020e8000 0x4000>;
+ interrupts = <0 125 0x04>;
+ };
+
+ sdma: sdma@020ec000 {
+ compatible = "fsl,imx6q-sdma", "fsl,imx35-sdma";
+ reg = <0x020ec000 0x4000>;
+ interrupts = <0 2 0x04>;
+ clocks = <&clks 155>, <&clks 155>;
+ clock-names = "ipg", "ahb";
+ fsl,sdma-ram-script-name = "imx/sdma/sdma-imx6q.bin";
+ };
+ };
+
+ aips-bus@02100000 { /* AIPS2 */
+ compatible = "fsl,aips-bus", "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ reg = <0x02100000 0x100000>;
+ ranges;
+
+ caam@02100000 {
+ reg = <0x02100000 0x40000>;
+ interrupts = <0 105 0x04 0 106 0x04>;
+ };
+
+ aipstz@0217c000 { /* AIPSTZ2 */
+ reg = <0x0217c000 0x4000>;
+ };
+
+ usbotg: usb@02184000 {
+ compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+ reg = <0x02184000 0x200>;
+ interrupts = <0 43 0x04>;
+ clocks = <&clks 162>;
+ fsl,usbphy = <&usbphy1>;
+ fsl,usbmisc = <&usbmisc 0>;
+ status = "disabled";
+ };
+
+ usbh1: usb@02184200 {
+ compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+ reg = <0x02184200 0x200>;
+ interrupts = <0 40 0x04>;
+ clocks = <&clks 162>;
+ fsl,usbphy = <&usbphy2>;
+ fsl,usbmisc = <&usbmisc 1>;
+ status = "disabled";
+ };
+
+ usbh2: usb@02184400 {
+ compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+ reg = <0x02184400 0x200>;
+ interrupts = <0 41 0x04>;
+ clocks = <&clks 162>;
+ fsl,usbmisc = <&usbmisc 2>;
+ status = "disabled";
+ };
+
+ usbh3: usb@02184600 {
+ compatible = "fsl,imx6q-usb", "fsl,imx27-usb";
+ reg = <0x02184600 0x200>;
+ interrupts = <0 42 0x04>;
+ clocks = <&clks 162>;
+ fsl,usbmisc = <&usbmisc 3>;
+ status = "disabled";
+ };
+
+ usbmisc: usbmisc: usbmisc@02184800 {
+ #index-cells = <1>;
+ compatible = "fsl,imx6q-usbmisc";
+ reg = <0x02184800 0x200>;
+ clocks = <&clks 162>;
+ };
+
+ fec: ethernet@02188000 {
+ compatible = "fsl,imx6q-fec";
+ reg = <0x02188000 0x4000>;
+ interrupts = <0 118 0x04 0 119 0x04>;
+ clocks = <&clks 117>, <&clks 117>, <&clks 190>;
+ clock-names = "ipg", "ahb", "ptp";
+ status = "disabled";
+ };
+
+ mlb@0218c000 {
+ reg = <0x0218c000 0x4000>;
+ interrupts = <0 53 0x04 0 117 0x04 0 126 0x04>;
+ };
+
+ usdhc1: usdhc@02190000 {
+ compatible = "fsl,imx6q-usdhc";
+ reg = <0x02190000 0x4000>;
+ interrupts = <0 22 0x04>;
+ clocks = <&clks 163>, <&clks 163>, <&clks 163>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ usdhc2: usdhc@02194000 {
+ compatible = "fsl,imx6q-usdhc";
+ reg = <0x02194000 0x4000>;
+ interrupts = <0 23 0x04>;
+ clocks = <&clks 164>, <&clks 164>, <&clks 164>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ usdhc3: usdhc@02198000 {
+ compatible = "fsl,imx6q-usdhc";
+ reg = <0x02198000 0x4000>;
+ interrupts = <0 24 0x04>;
+ clocks = <&clks 165>, <&clks 165>, <&clks 165>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ usdhc4: usdhc@0219c000 {
+ compatible = "fsl,imx6q-usdhc";
+ reg = <0x0219c000 0x4000>;
+ interrupts = <0 25 0x04>;
+ clocks = <&clks 166>, <&clks 166>, <&clks 166>;
+ clock-names = "ipg", "ahb", "per";
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@021a0000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
+ reg = <0x021a0000 0x4000>;
+ interrupts = <0 36 0x04>;
+ clocks = <&clks 125>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@021a4000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
+ reg = <0x021a4000 0x4000>;
+ interrupts = <0 37 0x04>;
+ clocks = <&clks 126>;
+ status = "disabled";
+ };
+
+ i2c3: i2c@021a8000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "fsl,imx6q-i2c", "fsl,imx21-i2c";
+ reg = <0x021a8000 0x4000>;
+ interrupts = <0 38 0x04>;
+ clocks = <&clks 127>;
+ status = "disabled";
+ };
+
+ romcp@021ac000 {
+ reg = <0x021ac000 0x4000>;
+ };
+
+ mmdc0: mmdc@021b0000 { /* MMDC0 */
+ compatible = "fsl,imx6q-mmdc";
+ reg = <0x021b0000 0x4000>;
+ };
+
+ mmdc1: mmdc@021b4000 { /* MMDC1 */
+ reg = <0x021b4000 0x4000>;
+ };
+
+ weim@021b8000 {
+ reg = <0x021b8000 0x4000>;
+ interrupts = <0 14 0x04>;
+ };
+
+ ocotp@021bc000 {
+ compatible = "fsl,imx6q-ocotp";
+ reg = <0x021bc000 0x4000>;
+ };
+
+ ocotp@021c0000 {
+ reg = <0x021c0000 0x4000>;
+ interrupts = <0 21 0x04>;
+ };
+
+ tzasc@021d0000 { /* TZASC1 */
+ reg = <0x021d0000 0x4000>;
+ interrupts = <0 108 0x04>;
+ };
+
+ tzasc@021d4000 { /* TZASC2 */
+ reg = <0x021d4000 0x4000>;
+ interrupts = <0 109 0x04>;
+ };
+
+ audmux: audmux@021d8000 {
+ compatible = "fsl,imx6q-audmux", "fsl,imx31-audmux";
+ reg = <0x021d8000 0x4000>;
+ status = "disabled";
+ };
+
+ mipi@021dc000 { /* MIPI-CSI */
+ reg = <0x021dc000 0x4000>;
+ };
+
+ mipi@021e0000 { /* MIPI-DSI */
+ reg = <0x021e0000 0x4000>;
+ };
+
+ vdoa@021e4000 {
+ reg = <0x021e4000 0x4000>;
+ interrupts = <0 18 0x04>;
+ };
+
+ uart2: serial@021e8000 {
+ compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x021e8000 0x4000>;
+ interrupts = <0 27 0x04>;
+ clocks = <&clks 160>, <&clks 161>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart3: serial@021ec000 {
+ compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x021ec000 0x4000>;
+ interrupts = <0 28 0x04>;
+ clocks = <&clks 160>, <&clks 161>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart4: serial@021f0000 {
+ compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x021f0000 0x4000>;
+ interrupts = <0 29 0x04>;
+ clocks = <&clks 160>, <&clks 161>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+
+ uart5: serial@021f4000 {
+ compatible = "fsl,imx6q-uart", "fsl,imx21-uart";
+ reg = <0x021f4000 0x4000>;
+ interrupts = <0 30 0x04>;
+ clocks = <&clks 160>, <&clks 161>;
+ clock-names = "ipg", "per";
+ status = "disabled";
+ };
+ };
+
+ ipu1: ipu@02400000 {
+ #crtc-cells = <1>;
+ compatible = "fsl,imx6q-ipu";
+ reg = <0x02400000 0x400000>;
+ interrupts = <0 6 0x4 0 5 0x4>;
+ clocks = <&clks 130>, <&clks 131>, <&clks 132>;
+ clock-names = "bus", "di0", "di1";
+ resets = <&src 2>;
+ };
+ };
+};
diff --git a/arch/arm/dts/tegra20-colibri-iris.dts b/arch/arm/dts/tegra20-colibri-iris.dts
new file mode 100644
index 0000000000..804750e421
--- /dev/null
+++ b/arch/arm/dts/tegra20-colibri-iris.dts
@@ -0,0 +1,32 @@
+/dts-v1/;
+
+/include/ "tegra20-colibri.dtsi"
+
+/ {
+ model = "Toradex Colibri T20 on Iris";
+ compatible = "toradex,iris", "toradex,colibri-t20", "nvidia,tegra20";
+
+ pinmux {
+ state_default: pinmux {
+ hdint {
+ nvidia,tristate = <0>;
+ };
+
+ i2cddc {
+ nvidia,tristate = <0>;
+ };
+
+ sdio4 {
+ nvidia,tristate = <0>;
+ };
+
+ uarta {
+ nvidia,tristate = <0>;
+ };
+
+ uartd {
+ nvidia,tristate = <0>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/dts/tegra20-colibri.dtsi b/arch/arm/dts/tegra20-colibri.dtsi
new file mode 100644
index 0000000000..3644e7de4e
--- /dev/null
+++ b/arch/arm/dts/tegra20-colibri.dtsi
@@ -0,0 +1,190 @@
+/include/ "tegra20.dtsi"
+
+/ {
+ model = "Toradex Colibri T20";
+ compatible = "toradex,colibri_t20", "nvidia,tegra20";
+
+ memory {
+ reg = <0x00000000 0x20000000>;
+ };
+
+ pinmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ audio_refclk {
+ nvidia,pins = "cdev1";
+ nvidia,function = "plla_out";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ };
+ crt {
+ nvidia,pins = "crtp";
+ nvidia,function = "crt";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ };
+ dap3 {
+ nvidia,pins = "dap3";
+ nvidia,function = "dap3";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ };
+ displaya {
+ nvidia,pins = "ld0", "ld1", "ld2", "ld3",
+ "ld4", "ld5", "ld6", "ld7", "ld8",
+ "ld9", "ld10", "ld11", "ld12", "ld13",
+ "ld14", "ld15", "ld16", "ld17",
+ "lhs", "lpw0", "lpw2", "lsc0",
+ "lsc1", "lsck", "lsda", "lspi", "lvs";
+ nvidia,function = "displaya";
+ nvidia,tristate = <1>;
+ };
+ gpio_dte {
+ nvidia,pins = "dte";
+ nvidia,function = "rsvd1";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ };
+ gpio_gmi {
+ nvidia,pins = "ata", "atc", "atd", "ate",
+ "dap1", "dap2", "dap4", "gpu", "irrx",
+ "irtx", "spia", "spib", "spic";
+ nvidia,function = "gmi";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ };
+ gpio_pta {
+ nvidia,pins = "pta";
+ nvidia,function = "rsvd4";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ };
+ gpio_uac {
+ nvidia,pins = "uac";
+ nvidia,function = "rsvd2";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ };
+ hdint {
+ nvidia,pins = "hdint";
+ nvidia,function = "hdmi";
+ nvidia,tristate = <1>;
+ };
+ i2c1 {
+ nvidia,pins = "rm";
+ nvidia,function = "i2c1";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ };
+ i2c3 {
+ nvidia,pins = "dtf";
+ nvidia,function = "i2c3";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ };
+ i2cddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "i2c2";
+ nvidia,pull = <2>;
+ nvidia,tristate = <1>;
+ };
+ i2cp {
+ nvidia,pins = "i2cp";
+ nvidia,function = "i2cp";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ };
+ irda {
+ nvidia,pins = "uad";
+ nvidia,function = "irda";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ };
+ nand {
+ nvidia,pins = "kbca", "kbcc", "kbcd",
+ "kbce", "kbcf";
+ nvidia,function = "nand";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ };
+ owc {
+ nvidia,pins = "owc";
+ nvidia,function = "owr";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ };
+ pmc {
+ nvidia,pins = "pmc";
+ nvidia,function = "pwr_on";
+ nvidia,tristate = <0>;
+ };
+ pwm {
+ nvidia,pins = "sdb", "sdc", "sdd";
+ nvidia,function = "pwm";
+ nvidia,tristate = <1>;
+ };
+ sdio4 {
+ nvidia,pins = "atb", "gma", "gme";
+ nvidia,function = "sdio4";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ };
+ spi1 {
+ nvidia,pins = "spid", "spie", "spif";
+ nvidia,function = "spi1";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ };
+ spi4 {
+ nvidia,pins = "slxa", "slxc", "slxd", "slxk";
+ nvidia,function = "spi4";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ };
+ uarta {
+ nvidia,pins = "sdio1";
+ nvidia,function = "uarta";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ };
+ uartd {
+ nvidia,pins = "gmc";
+ nvidia,function = "uartd";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ };
+ ulpi {
+ nvidia,pins = "uaa", "uab", "uda";
+ nvidia,function = "ulpi";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ };
+ ulpi_refclk {
+ nvidia,pins = "cdev2";
+ nvidia,function = "pllp_out4";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ };
+ usb_gpio {
+ nvidia,pins = "spig", "spih";
+ nvidia,function = "spi2_alt";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ };
+ vi {
+ nvidia,pins = "dta", "dtb", "dtc", "dtd";
+ nvidia,function = "vi";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ };
+ vi_sc {
+ nvidia,pins = "csus";
+ nvidia,function = "vi_sensor_clk";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ };
+ };
+ };
+};
diff --git a/arch/arm/dts/tegra20-paz00.dts b/arch/arm/dts/tegra20-paz00.dts
index 09ccb8ba3a..e8486aae49 100644
--- a/arch/arm/dts/tegra20-paz00.dts
+++ b/arch/arm/dts/tegra20-paz00.dts
@@ -9,4 +9,220 @@
memory {
reg = <0x00000000 0x20000000>;
};
+
+ pinmux {
+ pinctrl-names = "default";
+ pinctrl-0 = <&state_default>;
+
+ state_default: pinmux {
+ ata {
+ nvidia,pins = "ata", "atc", "atd", "ate",
+ "dap2", "gmb", "gmc", "gmd", "spia",
+ "spib", "spic", "spid", "spie";
+ nvidia,function = "gmi";
+ };
+ atb {
+ nvidia,pins = "atb", "gma", "gme";
+ nvidia,function = "sdio4";
+ };
+ cdev1 {
+ nvidia,pins = "cdev1";
+ nvidia,function = "plla_out";
+ };
+ cdev2 {
+ nvidia,pins = "cdev2";
+ nvidia,function = "pllp_out4";
+ };
+ crtp {
+ nvidia,pins = "crtp";
+ nvidia,function = "crt";
+ };
+ csus {
+ nvidia,pins = "csus";
+ nvidia,function = "pllc_out1";
+ };
+ dap1 {
+ nvidia,pins = "dap1";
+ nvidia,function = "dap1";
+ };
+ dap3 {
+ nvidia,pins = "dap3";
+ nvidia,function = "dap3";
+ };
+ dap4 {
+ nvidia,pins = "dap4";
+ nvidia,function = "dap4";
+ };
+ ddc {
+ nvidia,pins = "ddc";
+ nvidia,function = "i2c2";
+ };
+ dta {
+ nvidia,pins = "dta", "dtb", "dtc", "dtd", "dte";
+ nvidia,function = "rsvd1";
+ };
+ dtf {
+ nvidia,pins = "dtf";
+ nvidia,function = "i2c3";
+ };
+ gpu {
+ nvidia,pins = "gpu", "sdb", "sdd";
+ nvidia,function = "pwm";
+ };
+ gpu7 {
+ nvidia,pins = "gpu7";
+ nvidia,function = "rtck";
+ };
+ gpv {
+ nvidia,pins = "gpv", "slxa", "slxk";
+ nvidia,function = "pcie";
+ };
+ hdint {
+ nvidia,pins = "hdint", "pta";
+ nvidia,function = "hdmi";
+ };
+ i2cp {
+ nvidia,pins = "i2cp";
+ nvidia,function = "i2cp";
+ };
+ irrx {
+ nvidia,pins = "irrx", "irtx";
+ nvidia,function = "uarta";
+ };
+ kbca {
+ nvidia,pins = "kbca", "kbcc", "kbce", "kbcf";
+ nvidia,function = "kbc";
+ };
+ kbcb {
+ nvidia,pins = "kbcb", "kbcd";
+ nvidia,function = "sdio2";
+ };
+ lcsn {
+ nvidia,pins = "lcsn", "ld0", "ld1", "ld2",
+ "ld3", "ld4", "ld5", "ld6", "ld7",
+ "ld8", "ld9", "ld10", "ld11", "ld12",
+ "ld13", "ld14", "ld15", "ld16", "ld17",
+ "ldc", "ldi", "lhp0", "lhp1", "lhp2",
+ "lhs", "lm0", "lm1", "lpp", "lpw0",
+ "lpw1", "lpw2", "lsc0", "lsc1", "lsck",
+ "lsda", "lsdi", "lspi", "lvp0", "lvp1",
+ "lvs";
+ nvidia,function = "displaya";
+ };
+ owc {
+ nvidia,pins = "owc";
+ nvidia,function = "owr";
+ };
+ pmc {
+ nvidia,pins = "pmc";
+ nvidia,function = "pwr_on";
+ };
+ rm {
+ nvidia,pins = "rm";
+ nvidia,function = "i2c1";
+ };
+ sdc {
+ nvidia,pins = "sdc";
+ nvidia,function = "twc";
+ };
+ sdio1 {
+ nvidia,pins = "sdio1";
+ nvidia,function = "sdio1";
+ };
+ slxc {
+ nvidia,pins = "slxc", "slxd";
+ nvidia,function = "spi4";
+ };
+ spdi {
+ nvidia,pins = "spdi", "spdo";
+ nvidia,function = "rsvd2";
+ };
+ spif {
+ nvidia,pins = "spif", "uac";
+ nvidia,function = "rsvd4";
+ };
+ spig {
+ nvidia,pins = "spig", "spih";
+ nvidia,function = "spi2_alt";
+ };
+ uaa {
+ nvidia,pins = "uaa", "uab", "uda";
+ nvidia,function = "ulpi";
+ };
+ uad {
+ nvidia,pins = "uad";
+ nvidia,function = "spdif";
+ };
+ uca {
+ nvidia,pins = "uca", "ucb";
+ nvidia,function = "uartc";
+ };
+ conf_ata {
+ nvidia,pins = "ata", "atb", "atc", "atd", "ate",
+ "cdev1", "cdev2", "dap1", "dap2", "dtf",
+ "gma", "gmb", "gmc", "gmd", "gme",
+ "gpu", "gpu7", "gpv", "i2cp", "pta",
+ "rm", "sdio1", "slxk", "spdo", "uac",
+ "uda";
+ nvidia,pull = <0>;
+ nvidia,tristate = <0>;
+ };
+ conf_ck32 {
+ nvidia,pins = "ck32", "ddrc", "pmca", "pmcb",
+ "pmcc", "pmcd", "pmce", "xm2c", "xm2d";
+ nvidia,pull = <0>;
+ };
+ conf_crtp {
+ nvidia,pins = "crtp", "dap3", "dap4", "dtb",
+ "dtc", "dte", "slxa", "slxc", "slxd",
+ "spdi";
+ nvidia,pull = <0>;
+ nvidia,tristate = <1>;
+ };
+ conf_csus {
+ nvidia,pins = "csus", "spia", "spib", "spid",
+ "spif";
+ nvidia,pull = <1>;
+ nvidia,tristate = <1>;
+ };
+ conf_ddc {
+ nvidia,pins = "ddc", "irrx", "irtx", "kbca",
+ "kbcb", "kbcc", "kbcd", "kbce", "kbcf",
+ "spic", "spig", "uaa", "uab";
+ nvidia,pull = <2>;
+ nvidia,tristate = <0>;
+ };
+ conf_dta {
+ nvidia,pins = "dta", "dtd", "owc", "sdc", "sdd",
+ "spie", "spih", "uad", "uca", "ucb";
+ nvidia,pull = <2>;
+ nvidia,tristate = <1>;
+ };
+ conf_hdint {
+ nvidia,pins = "hdint", "ld0", "ld1", "ld2",
+ "ld3", "ld4", "ld5", "ld6", "ld7",
+ "ld8", "ld9", "ld10", "ld11", "ld12",
+ "ld13", "ld14", "ld15", "ld16", "ld17",
+ "ldc", "ldi", "lhs", "lsc0", "lspi",
+ "lvs", "pmc";
+ nvidia,tristate = <0>;
+ };
+ conf_lc {
+ nvidia,pins = "lc", "ls";
+ nvidia,pull = <2>;
+ };
+ conf_lcsn {
+ nvidia,pins = "lcsn", "lhp0", "lhp1", "lhp2",
+ "lm0", "lm1", "lpp", "lpw0", "lpw1",
+ "lpw2", "lsc1", "lsck", "lsda", "lsdi",
+ "lvp0", "lvp1", "sdb";
+ nvidia,tristate = <1>;
+ };
+ conf_ld17_0 {
+ nvidia,pins = "ld17_0", "ld19_18", "ld21_20",
+ "ld23_22";
+ nvidia,pull = <1>;
+ };
+ };
+ };
};
diff --git a/arch/arm/dts/tegra20.dtsi b/arch/arm/dts/tegra20.dtsi
index b7d1e27de2..f63ead89db 100644
--- a/arch/arm/dts/tegra20.dtsi
+++ b/arch/arm/dts/tegra20.dtsi
@@ -34,6 +34,14 @@
interrupt-controller;
};
+ pinmux: pinmux {
+ compatible = "nvidia,tegra20-pinmux";
+ reg = <0x70000014 0x10 /* Tri-state registers */
+ 0x70000080 0x20 /* Mux registers */
+ 0x700000a0 0x14 /* Pull-up/down registers */
+ 0x70000868 0xa8>; /* Pad control registers */
+ };
+
pmc {
compatible = "nvidia,tegra20-pmc";
reg = <0x7000e400 0x400>;
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index e7a0625d3b..0786e22d3d 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -91,6 +91,10 @@ static int __do_bootm_linux(struct image_data *data, int swap)
of_add_reserve_entry(initrd_start, initrd_end);
data->oftree = of_get_fixed_tree(data->of_root_node);
fdt_add_reserve_map(data->oftree);
+ if (bootm_verbose(data))
+ of_print_cmdline(data->of_root_node);
+ if (bootm_verbose(data) > 1)
+ of_print_nodes(data->of_root_node, 0);
}
if (bootm_verbose(data)) {
@@ -326,7 +330,7 @@ static int aimage_load_resource(int fd, struct resource *r, void* buf, int ps)
ret = read_full(fd, buf, to_read);
if (ret < 0)
- printf("could not read dummy %d\n", to_read);
+ printf("could not read dummy %u\n", to_read);
return ret;
}
diff --git a/arch/arm/lib/module.c b/arch/arm/lib/module.c
index 643a8bed0e..be7965d59c 100644
--- a/arch/arm/lib/module.c
+++ b/arch/arm/lib/module.c
@@ -34,7 +34,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
offset = ELF32_R_SYM(rel->r_info);
if (offset < 0 || offset > (symsec->sh_size / sizeof(Elf32_Sym))) {
- printf("%s: bad relocation, section %d reloc %d\n",
+ printf("%s: bad relocation, section %u reloc %u\n",
module->name, relindex, i);
return -ENOEXEC;
}
@@ -43,7 +43,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
if (rel->r_offset < 0 || rel->r_offset > dstsec->sh_size - sizeof(u32)) {
printf("%s: out of bounds relocation, "
- "section %d reloc %d offset %d size %d\n",
+ "section %u reloc %u offset %d size %d\n",
module->name, relindex, i, rel->r_offset,
dstsec->sh_size);
return -ENOEXEC;
@@ -68,7 +68,7 @@ apply_relocate(Elf32_Shdr *sechdrs, const char *strtab, unsigned int symindex,
offset <= (s32)0xfe000000 ||
offset >= (s32)0x02000000) {
printf("%s: relocation out of range, section "
- "%d reloc %d sym '%s'\n", module->name,
+ "%u reloc %u sym '%s'\n", module->name,
relindex, i, strtab + sym->st_name);
return -ENOEXEC;
}
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index b8528d0616..8116b62f24 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -59,6 +59,7 @@ config BOARDINFO
default "Calao TNY-A9263" if MACH_TNY_A9263
default "Calao TNY-A9G20" if MACH_TNY_A9G20
default "Calao QIL-A9260" if MACH_QIL_A9260
+ default "Calao QIL-A9G20" if MACH_QIL_A9G20
default "Somfy Animeo IP" if MACH_ANIMEO_IP
default "Telit EVK-PRO3" if MACH_GE863
@@ -363,6 +364,13 @@ config MACH_DSS11
Select this if you are using aizo dSS11
that embeds only one SD/MMC slot.
+config MACH_QIL_A9G20
+ bool "CALAO QIL-A9G20 board"
+ help
+ Select this if you are using a Calao Systems QIL-A9G20 Board.
+ <http://www.calao-systems.com>
+
+
endchoice
endif
@@ -513,7 +521,7 @@ config AT91_HAVE_2MMC
config AT91_HAVE_SRAM_128M
bool "Have 128 of ram"
- depends on MACH_USB_A9G20 || MACH_USB_A9263 || MACH_QIL_A9260
+ depends on MACH_USB_A9G20 || MACH_USB_A9263 || MACH_QIL_A9260 || MACH_QIL_A9G20
help
Select this if you board have 128 MiB of Ram (as USB_A9G20 C11)
@@ -543,7 +551,7 @@ config CALAO_MOB_TNY_MD2
config CALAO_MB_QIL_A9260
bool "MB-QIL A9260 Motherboard Board support"
- depends on MACH_QIL_A9260
+ depends on MACH_QIL_A9260 || MACH_QIL_A9G20
if COMMAND_SUPPORT
diff --git a/arch/arm/mach-bcm2835/core.c b/arch/arm/mach-bcm2835/core.c
index f44ecd5bf3..906e4344dd 100644
--- a/arch/arm/mach-bcm2835/core.c
+++ b/arch/arm/mach-bcm2835/core.c
@@ -70,6 +70,7 @@ static int bcm2835_dev_init(void)
{
add_generic_device("bcm2835-gpio", 0, NULL, BCM2835_GPIO_BASE, 0xB0, IORESOURCE_MEM, NULL);
add_generic_device("bcm2835-cs", DEVICE_ID_SINGLE, NULL, BCM2835_ST_BASE, 0x1C, IORESOURCE_MEM, NULL);
+ add_generic_device("bcm2835_mci", 0, NULL, BCM2835_EMMC_BASE, 0xFC, IORESOURCE_MEM, NULL);
return 0;
}
coredevice_initcall(bcm2835_dev_init);
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 359b5cd091..a66395cb06 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -66,6 +66,7 @@ config BOARDINFO
choice
prompt "Select boot mode"
+ depends on !ARCH_IMX_INTERNAL_BOOT_USE_IMXIMAGE
help
i.MX processors support two different boot modes. With the internal
boot mode the boot medium contains a header describing the image to
@@ -93,6 +94,21 @@ config ARCH_IMX_EXTERNAL_BOOT
endchoice
+config ARCH_IMX_IMXIMAGE
+ bool
+ help
+ if enabled the imx-image tool is compiled
+
+config ARCH_IMX_INTERNAL_BOOT_USE_IMXIMAGE
+ select ARCH_IMX_IMXIMAGE
+ bool
+ help
+ Traditionally the i.MX specific format for internal bootmode
+ was generated using C structs inside the binary. Now there is
+ a tool available to generate the imx-image format. Boards using
+ this tool must select this option. This is recommended for new
+ boards.
+
choice
depends on ARCH_IMX_INTERNAL_BOOT
prompt "Internal boot source"
@@ -407,6 +423,7 @@ choice
config MACH_FREESCALE_MX51_PDK
select HAVE_DEFAULT_ENVIRONMENT_NEW
+ select ARCH_IMX_INTERNAL_BOOT_USE_IMXIMAGE
bool "Freescale i.MX51 PDK"
config MACH_EUKREA_CPUIMX51SD
@@ -508,6 +525,7 @@ config MACH_MX6Q_ARM2
bool "Freescale i.MX6q Armadillo2"
config MACH_SABRELITE
+ select HAVE_DEFAULT_ENVIRONMENT_NEW
bool "Freescale i.MX6 Sabre Lite"
config MACH_SABRESD
@@ -596,6 +614,13 @@ endmenu
menu "i.MX specific settings"
+config ARCH_IMX_USBLOADER
+ bool "compile imx-usb-loader"
+ help
+ imx-usb-loader is a tool to upload and start imximages to an i.MX SoC
+ in ROM boot mode. It requires libusb, so make sure you have the libusb
+ devel package installed on your machine.
+
config IMX_IIM
tristate "IIM fusebox device"
depends on !ARCH_IMX21 && !ARCH_IMX21
diff --git a/arch/arm/mach-imx/clk-imx6.c b/arch/arm/mach-imx/clk-imx6.c
index f1b167aac5..5c84df264a 100644
--- a/arch/arm/mach-imx/clk-imx6.c
+++ b/arch/arm/mach-imx/clk-imx6.c
@@ -321,7 +321,7 @@ static int imx6_ccm_probe(struct device_d *dev)
static __maybe_unused struct of_device_id imx6_ccm_dt_ids[] = {
{
- .compatible = "fsl,imx6-ccm",
+ .compatible = "fsl,imx6q-ccm",
}, {
/* sentinel */
}
diff --git a/arch/arm/mach-imx/iim.c b/arch/arm/mach-imx/iim.c
index ce2bbafc90..956811cc6d 100644
--- a/arch/arm/mach-imx/iim.c
+++ b/arch/arm/mach-imx/iim.c
@@ -31,8 +31,6 @@
#define DRIVERNAME "imx_iim"
-static unsigned long mac_addr_base;
-
static int iim_write_enable;
static int iim_sense_enable;
@@ -225,21 +223,66 @@ static int imx_iim_add_bank(struct device_d *dev, void __iomem *base, int num)
return devfs_create(cdev);
}
+#if IS_ENABLED(CONFIG_OFDEVICE)
+
+/*
+ * a single MAC address reference has the form
+ * <&phandle iim-bank-no offset>, so three cells
+ */
+#define MAC_ADDRESS_PROPLEN (3 * sizeof(__be32))
+
+static void imx_iim_init_dt(struct device_d *dev)
+{
+ char mac[6];
+ const __be32 *prop;
+ struct device_node *node = dev->device_node;
+ int len, ret;
+
+ if (!node)
+ return;
+
+ prop = of_get_property(node, "barebox,provide-mac-address", &len);
+ if (!prop)
+ return;
+
+ while (len >= MAC_ADDRESS_PROPLEN) {
+ struct device_node *rnode;
+ uint32_t phandle, bank, offset;
+
+ phandle = be32_to_cpup(prop++);
+
+ rnode = of_find_node_by_phandle(phandle);
+ bank = be32_to_cpup(prop++);
+ offset = be32_to_cpup(prop++);
+
+ ret = imx_iim_read(bank, offset, mac, 6);
+ if (ret == 6) {
+ of_eth_register_ethaddr(rnode, mac);
+ } else {
+ dev_err(dev, "cannot read: %s\n", strerror(-ret));
+ }
+
+ len -= MAC_ADDRESS_PROPLEN;
+ }
+}
+#else
+static inline void imx_iim_init_dt(struct device_d *dev)
+{
+}
+#endif
+
static int imx_iim_probe(struct device_d *dev)
{
- struct imx_iim_platform_data *pdata = dev->platform_data;
int i;
void __iomem *base;
base = dev_request_mem_region(dev, 0);
- if (pdata)
- mac_addr_base = pdata->mac_addr_base;
-
for (i = 0; i < 8; i++) {
imx_iim_add_bank(dev, base, i);
}
+ imx_iim_init_dt(dev);
if (IS_ENABLED(CONFIG_IMX_IIM_FUSE_BLOW))
dev_add_param_bool(dev, "permanent_write_enable",
@@ -251,9 +294,18 @@ static int imx_iim_probe(struct device_d *dev)
return 0;
}
+static __maybe_unused struct of_device_id imx_iim_dt_ids[] = {
+ {
+ .compatible = "fsl,imx-iim",
+ }, {
+ /* sentinel */
+ }
+};
+
static struct driver_d imx_iim_driver = {
.name = DRIVERNAME,
.probe = imx_iim_probe,
+ .of_compatible = DRV_OF_COMPAT(imx_iim_dt_ids),
};
static int imx_iim_init(void)
diff --git a/arch/arm/mach-imx/imx25.c b/arch/arm/mach-imx/imx25.c
index 501191874f..63e91a51f0 100644
--- a/arch/arm/mach-imx/imx25.c
+++ b/arch/arm/mach-imx/imx25.c
@@ -53,16 +53,12 @@ u64 imx_uid(void)
return uid;
}
-static struct imx_iim_platform_data imx25_iim_pdata = {
- .mac_addr_base = IIM_MAC_ADDR,
-};
-
static int imx25_init(void)
{
imx25_boot_save_loc((void *)MX25_CCM_BASE_ADDR);
add_generic_device("imx_iim", 0, NULL, MX25_IIM_BASE_ADDR, SZ_4K,
- IORESOURCE_MEM, &imx25_iim_pdata);
+ IORESOURCE_MEM, NULL);
add_generic_device("imx-iomuxv3", 0, NULL, MX25_IOMUXC_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx25-ccm", 0, NULL, MX25_CCM_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/imx51.c b/arch/arm/mach-imx/imx51.c
index 54d99a4c19..fdf2374402 100644
--- a/arch/arm/mach-imx/imx51.c
+++ b/arch/arm/mach-imx/imx51.c
@@ -58,6 +58,9 @@ static int imx51_init(void)
imx51_silicon_revision();
imx51_boot_save_loc((void *)MX51_SRC_BASE_ADDR);
+ if (of_get_root_node())
+ return 0;
+
add_generic_device("imx_iim", 0, NULL, MX51_IIM_BASE_ADDR, SZ_4K,
IORESOURCE_MEM, NULL);
@@ -95,15 +98,63 @@ postcore_initcall(imx51_init);
* power up.
*/
+#define DP_MFN_800_DIT 60 /* PL Dither mode */
+
+/*
+ * Workaround for i.MX51 PLL errata. This is needed by all boards using the
+ * i.MX51 silicon version up until (including) 3.0 running at 800MHz.
+ * The PLL's in the i.MX51 processor can go out of lock due to a metastable
+ * condition in an analog flip-flop when used at high frequencies.
+ * This workaround implements an undocumented feature in the PLL (dither
+ * mode), which causes the effect of this failure to be much lower (in terms
+ * of frequency deviation), avoiding system failure, or at least decreasing
+ * the likelihood of system failure.
+ */
+static void imx51_setup_pll800_bug(void)
+{
+ void __iomem *base = (void *)MX51_PLL1_BASE_ADDR;
+ u32 dp_config;
+ volatile int i;
+
+ imx5_setup_pll_864(base);
+
+ dp_config = readl(base + MX5_PLL_DP_CONFIG);
+ dp_config &= ~MX5_PLL_DP_CONFIG_AREN;
+ writel(dp_config, base + MX5_PLL_DP_CONFIG);
+
+ /* Restart PLL with PLM = 1 */
+ writel(0x00001236, base + MX5_PLL_DP_CTL);
+
+ /* Wait for lock */
+ while (!(readl(base + MX5_PLL_DP_CTL) & 1));
+
+ /* Modify MFN value */
+ writel(DP_MFN_800_DIT, base + MX5_PLL_DP_MFN);
+ writel(DP_MFN_800_DIT, base + MX5_PLL_DP_HFS_MFN);
+
+ /* Reload MFN value */
+ writel(0x1, base + MX5_PLL_DP_CONFIG);
+
+ while (readl(base + MX5_PLL_DP_CONFIG) & 1);
+
+ /* Wait at least 4 us */
+ for (i = 0; i < 100; i++);
+
+ /* Enable auto-restart AREN bit */
+ dp_config |= MX5_PLL_DP_CONFIG_AREN;
+ writel(dp_config, base + MX5_PLL_DP_CONFIG);
+}
+
void imx51_init_lowlevel(unsigned int cpufreq_mhz)
{
void __iomem *ccm = (void __iomem *)MX51_CCM_BASE_ADDR;
u32 r;
+ int rev = imx_silicon_revision();
imx5_init_lowlevel();
/* disable write combine for TO 2 and lower revs */
- if (imx_silicon_revision() < IMX_CHIP_REV_3_0) {
+ if (rev < IMX_CHIP_REV_3_0) {
__asm__ __volatile__("mrc 15, 1, %0, c9, c0, 1":"=r"(r));
r |= (1 << 25);
__asm__ __volatile__("mcr 15, 1, %0, c9, c0, 1" : : "r"(r));
@@ -135,7 +186,10 @@ void imx51_init_lowlevel(unsigned int cpufreq_mhz)
break;
default:
/* Default maximum 800MHz */
- imx5_setup_pll_800((void __iomem *)MX51_PLL1_BASE_ADDR);
+ if (rev <= IMX_CHIP_REV_3_0)
+ imx51_setup_pll800_bug();
+ else
+ imx5_setup_pll_800((void __iomem *)MX51_PLL1_BASE_ADDR);
break;
}
diff --git a/arch/arm/mach-imx/imx6.c b/arch/arm/mach-imx/imx6.c
index 7a7ce15c46..5c20aa1841 100644
--- a/arch/arm/mach-imx/imx6.c
+++ b/arch/arm/mach-imx/imx6.c
@@ -57,6 +57,9 @@ static int imx6_init(void)
{
imx6_boot_save_loc((void *)MX6_SRC_BASE_ADDR);
+ if (of_get_root_node())
+ return 0;
+
add_generic_device("imx-iomuxv3", 0, NULL, MX6_IOMUXC_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
add_generic_device("imx6-ccm", 0, NULL, MX6_CCM_BASE_ADDR, 0x4000, IORESOURCE_MEM, NULL);
add_generic_device("imx31-gpt", 0, NULL, MX6_GPT_BASE_ADDR, 0x1000, IORESOURCE_MEM, NULL);
diff --git a/arch/arm/mach-imx/include/mach/devices-imx1.h b/arch/arm/mach-imx/include/mach/devices-imx1.h
index 391c1a9c8e..e4185bc281 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx1.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx1.h
@@ -1,4 +1,5 @@
#include <mach/devices.h>
+#include <mach/imx1-regs.h>
static inline struct device_d *imx1_add_uart0(void)
{
diff --git a/arch/arm/mach-imx/include/mach/devices-imx21.h b/arch/arm/mach-imx/include/mach/devices-imx21.h
index ad7ee5ed02..5b2dfd7505 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx21.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx21.h
@@ -1,5 +1,6 @@
#include <mach/devices.h>
+#include <mach/imx21-regs.h>
static inline struct device_d *imx21_add_uart0(void)
{
diff --git a/arch/arm/mach-imx/include/mach/devices-imx25.h b/arch/arm/mach-imx/include/mach/devices-imx25.h
index a655be9564..5b582b88cd 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx25.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx25.h
@@ -1,5 +1,6 @@
#include <mach/devices.h>
+#include <mach/imx25-regs.h>
static inline struct device_d *imx25_add_i2c0(struct i2c_platform_data *pdata)
{
diff --git a/arch/arm/mach-imx/include/mach/devices-imx27.h b/arch/arm/mach-imx/include/mach/devices-imx27.h
index d6c884a30a..87a3a7cc1c 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx27.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx27.h
@@ -1,5 +1,6 @@
#include <mach/devices.h>
+#include <mach/imx27-regs.h>
static inline struct device_d *imx27_add_spi0(struct spi_imx_master *pdata)
{
diff --git a/arch/arm/mach-imx/include/mach/devices-imx35.h b/arch/arm/mach-imx/include/mach/devices-imx35.h
index 912c41872e..766610de9d 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx35.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx35.h
@@ -1,5 +1,6 @@
#include <mach/devices.h>
+#include <mach/imx35-regs.h>
static inline struct device_d *imx35_add_i2c0(struct i2c_platform_data *pdata)
{
diff --git a/arch/arm/mach-imx/include/mach/devices-imx51.h b/arch/arm/mach-imx/include/mach/devices-imx51.h
index ec8467ae9c..00644788a7 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx51.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx51.h
@@ -1,6 +1,7 @@
-#include <mach/devices.h>
#include <sizes.h>
+#include <mach/devices.h>
+#include <mach/imx51-regs.h>
static inline struct device_d *imx51_add_spi0(struct spi_imx_master *pdata)
{
diff --git a/arch/arm/mach-imx/include/mach/devices-imx53.h b/arch/arm/mach-imx/include/mach/devices-imx53.h
index 5bdcf32291..df14654865 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx53.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx53.h
@@ -1,5 +1,6 @@
#include <mach/devices.h>
+#include <mach/imx53-regs.h>
static inline struct device_d *imx53_add_spi0(struct spi_imx_master *pdata)
{
diff --git a/arch/arm/mach-imx/include/mach/devices-imx6.h b/arch/arm/mach-imx/include/mach/devices-imx6.h
index b6b538a95b..7d41d7f02b 100644
--- a/arch/arm/mach-imx/include/mach/devices-imx6.h
+++ b/arch/arm/mach-imx/include/mach/devices-imx6.h
@@ -1,4 +1,5 @@
#include <mach/devices.h>
+#include <mach/imx6-regs.h>
static inline struct device_d *imx6_add_uart0(void)
{
diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h
index 189b32f2c3..9958cb2f3f 100644
--- a/arch/arm/mach-imx/include/mach/generic.h
+++ b/arch/arm/mach-imx/include/mach/generic.h
@@ -1,6 +1,9 @@
#ifndef __MACH_GENERIC_H
#define __MACH_GENERIC_H
+#include <linux/compiler.h>
+#include <linux/types.h>
+
u64 imx_uid(void);
void imx25_boot_save_loc(void __iomem *ccm_base);
diff --git a/arch/arm/mach-imx/include/mach/iim.h b/arch/arm/mach-imx/include/mach/iim.h
index 713f0de057..1d2814919b 100644
--- a/arch/arm/mach-imx/include/mach/iim.h
+++ b/arch/arm/mach-imx/include/mach/iim.h
@@ -38,10 +38,6 @@
#define IIM_SCS2 0x0034
#define IIM_SCS3 0x0038
-struct imx_iim_platform_data {
- unsigned long mac_addr_base;
-};
-
#ifdef CONFIG_IMX_IIM
int imx_iim_read(unsigned int bank, int offset, void *buf, int count);
#else
diff --git a/arch/arm/mach-imx/include/mach/imx5.h b/arch/arm/mach-imx/include/mach/imx5.h
index 7f5c2eff50..5d1a7d7d40 100644
--- a/arch/arm/mach-imx/include/mach/imx5.h
+++ b/arch/arm/mach-imx/include/mach/imx5.h
@@ -9,6 +9,7 @@ void imx5_init_lowlevel(void);
void imx5_setup_pll(void __iomem *base, int freq, u32 op, u32 mfd, u32 mfn);
#define imx5_setup_pll_1000(base) imx5_setup_pll((base), 1000, ((10 << 4) + ((1 - 1) << 0)), (12 - 1), 5)
+#define imx5_setup_pll_864(base) imx5_setup_pll((base), 864, (( 8 << 4) + ((1 - 1) << 0)), (180 - 1), 180)
#define imx5_setup_pll_800(base) imx5_setup_pll((base), 800, (( 8 << 4) + ((1 - 1) << 0)), (3 - 1), 1)
#define imx5_setup_pll_665(base) imx5_setup_pll((base), 665, (( 6 << 4) + ((1 - 1) << 0)), (96 - 1), 89)
#define imx5_setup_pll_600(base) imx5_setup_pll((base), 600, (( 6 << 4) + ((1 - 1) << 0)), ( 4 - 1), 1)
diff --git a/arch/arm/mach-imx/include/mach/iomux-v1.h b/arch/arm/mach-imx/include/mach/iomux-v1.h
index 55fbcdb94e..49dcecd1de 100644
--- a/arch/arm/mach-imx/include/mach/iomux-v1.h
+++ b/arch/arm/mach-imx/include/mach/iomux-v1.h
@@ -1,6 +1,8 @@
#ifndef __MACH_IOMUX_V1_H__
#define __MACH_IOMUX_V1_H__
+#include <linux/compiler.h>
+
#define GPIO_PIN_MASK 0x1f
#define GPIO_PORT_SHIFT 5
diff --git a/arch/arm/mach-imx/include/mach/weim.h b/arch/arm/mach-imx/include/mach/weim.h
index 8d572dc0bf..3fbbb6ba8e 100644
--- a/arch/arm/mach-imx/include/mach/weim.h
+++ b/arch/arm/mach-imx/include/mach/weim.h
@@ -1,6 +1,8 @@
#ifndef __MACH_WEIM_H
#define __MACH_WEIM_H
+#include <linux/types.h>
+
void imx27_setup_weimcs(size_t cs, unsigned upper, unsigned lower,
unsigned additional);
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig
new file mode 100644
index 0000000000..11e4550ec5
--- /dev/null
+++ b/arch/arm/mach-mvebu/Kconfig
@@ -0,0 +1,124 @@
+if ARCH_MVEBU
+
+config ARCH_TEXT_BASE
+ hex
+ default 0x2000000 if MACH_PLATHOME_OPENBLOCKS_AX3
+ default 0x2000000 if MACH_GLOBALSCALE_MIRABOX
+ default 0x2000000 if MACH_GLOBALSCALE_GURUPLUG
+ default 0x2000000 if MACH_MARVELL_ARMADA_XP_GP
+ default 0x2000000 if MACH_SOLIDRUN_CUBOX
+
+config BOARDINFO
+ default "PlatHome OpenBlocks AX3" if MACH_PLATHOME_OPENBLOCKS_AX3
+ default "Globalscale Mirabox" if MACH_GLOBALSCALE_MIRABOX
+ default "Globalscale Guruplug" if MACH_GLOBALSCALE_GURUPLUG
+ default "Marvell Armada XP GP" if MACH_MARVELL_ARMADA_XP_GP
+ default "SolidRun CuBox" if MACH_SOLIDRUN_CUBOX
+
+choice
+ prompt "Marvell EBU Processor"
+
+config ARCH_ARMADA_370
+ bool "Armada 370"
+ select CPU_V7
+ select CLOCKSOURCE_MVEBU
+
+config ARCH_ARMADA_XP
+ bool "Armada XP"
+ select CPU_V7
+ select CLOCKSOURCE_MVEBU
+
+config ARCH_DOVE
+ bool "Dove 88AP510"
+ select CPU_V7
+ select CLOCKSOURCE_ORION
+
+config ARCH_KIRKWOOD
+ bool "Kirkwood"
+ select CPU_FEROCEON
+ select CLOCKSOURCE_ORION
+
+endchoice
+
+#
+# Armada 370 SoC boards
+#
+
+if ARCH_ARMADA_370
+
+choice
+ prompt "Armada 370 Board Type"
+
+config MACH_GLOBALSCALE_MIRABOX
+ bool "Globalscale Mirabox"
+
+endchoice
+
+endif # ARCH_ARMADA_370
+
+#
+# Armada XP SoC boards
+#
+
+if ARCH_ARMADA_XP
+
+choice
+ prompt "Armada XP Board Type"
+
+config MACH_PLATHOME_OPENBLOCKS_AX3
+ bool "PlatHome OpenBlocks AX3"
+
+config MACH_MARVELL_ARMADA_XP_GP
+ bool "Marvell Armada XP GP"
+
+endchoice
+
+endif # ARCH_ARMADA_XP
+
+#
+# Dove 88AP510 SoC boards
+#
+
+if ARCH_DOVE
+
+choice
+ prompt "Dove 88AP510 Board Type"
+
+config MACH_SOLIDRUN_CUBOX
+ bool "SolidRun CuBox"
+
+endchoice
+
+endif # ARCH_DOVE
+
+#
+# Kirkwood SoC boards
+#
+
+if ARCH_KIRKWOOD
+
+choice
+ prompt "Kirkwood Board Type"
+
+config MACH_GLOBALSCALE_GURUPLUG
+ bool "Guruplug"
+
+endchoice
+
+endif # ARCH_KIRKWOOD
+
+#
+# Common options
+#
+
+config MVEBU_CONSOLE_UART
+ int "UART number for console"
+ default 0
+ range 0 1 if ARCH_ARMADA_370
+ range 0 1 if ARCH_ARMADA_XP
+ range 0 3 if ARCH_DOVE
+ range 0 1 if ARCH_KIRKWOOD
+ help
+ Select the UART number the barebox console will sit on.
+
+endif # ARCH_MVEBU
diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile
new file mode 100644
index 0000000000..80b3947cc8
--- /dev/null
+++ b/arch/arm/mach-mvebu/Makefile
@@ -0,0 +1,6 @@
+lwl-y += lowlevel.o
+obj-y += common.o
+obj-$(CONFIG_ARCH_ARMADA_370) += armada-370-xp.o
+obj-$(CONFIG_ARCH_ARMADA_XP) += armada-370-xp.o
+obj-$(CONFIG_ARCH_DOVE) += dove.o
+obj-$(CONFIG_ARCH_KIRKWOOD) += kirkwood.o
diff --git a/arch/arm/mach-mvebu/armada-370-xp.c b/arch/arm/mach-mvebu/armada-370-xp.c
new file mode 100644
index 0000000000..2cdc3b0cbc
--- /dev/null
+++ b/arch/arm/mach-mvebu/armada-370-xp.c
@@ -0,0 +1,121 @@
+/*
+ * Copyright
+ * (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * 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.
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <ns16550.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <asm/memory.h>
+#include <mach/armada-370-xp-regs.h>
+
+#define CONSOLE_UART_BASE \
+ ARMADA_370_XP_UARTn_BASE(CONFIG_MVEBU_CONSOLE_UART)
+
+static struct clk *tclk;
+
+static inline void armada_370_xp_memory_find(unsigned long *phys_base,
+ unsigned long *phys_size)
+{
+ int cs;
+
+ *phys_base = ~0;
+ *phys_size = 0;
+
+ for (cs = 0; cs < 4; cs++) {
+ u32 base = readl(ARMADA_370_XP_SDRAM_BASE + DDR_BASE_CSn(cs));
+ u32 ctrl = readl(ARMADA_370_XP_SDRAM_BASE + DDR_SIZE_CSn(cs));
+
+ /* Skip non-enabled CS */
+ if ((ctrl & DDR_SIZE_ENABLED) != DDR_SIZE_ENABLED)
+ continue;
+
+ base &= DDR_BASE_CS_LOW_MASK;
+ if (base < *phys_base)
+ *phys_base = base;
+ *phys_size += (ctrl | ~DDR_SIZE_MASK) + 1;
+ }
+}
+
+static struct NS16550_plat uart_plat = {
+ .shift = 2,
+};
+
+static int armada_370_xp_add_uart(void)
+{
+ uart_plat.clock = clk_get_rate(tclk);
+ if (!add_ns16550_device(DEVICE_ID_DYNAMIC,
+ (unsigned int)CONSOLE_UART_BASE, 32,
+ IORESOURCE_MEM_32BIT, &uart_plat))
+ return -ENODEV;
+ return 0;
+}
+
+#if defined(CONFIG_ARCH_ARMADA_370)
+static int armada_370_init_clocks(void)
+{
+ u32 val = readl(ARMADA_370_XP_SAR_BASE + SAR_LOW);
+ unsigned int rate;
+
+ /*
+ * On Armada 370, the TCLK frequency can be either
+ * 166 Mhz or 200 Mhz
+ */
+ if ((val & SAR_TCLK_FREQ) == SAR_TCLK_FREQ)
+ rate = 200000000;
+ else
+ rate = 166000000;
+
+ tclk = clk_fixed("tclk", rate);
+ return clk_register_clkdev(tclk, NULL, "mvebu-timer");
+}
+#define armada_370_xp_init_clocks() armada_370_init_clocks()
+#endif
+
+#if defined(CONFIG_ARCH_ARMADA_XP)
+static int armada_xp_init_clocks(void)
+{
+ /* On Armada XP, the TCLK frequency is always 250 Mhz */
+ tclk = clk_fixed("tclk", 250000000);
+ return clk_register_clkdev(tclk, NULL, "mvebu-timer");
+}
+#define armada_370_xp_init_clocks() armada_xp_init_clocks()
+#endif
+
+static int armada_370_xp_init_soc(void)
+{
+ unsigned long phys_base, phys_size;
+
+ armada_370_xp_init_clocks();
+ add_generic_device("mvebu-timer", DEVICE_ID_SINGLE, NULL,
+ (unsigned int)ARMADA_370_XP_TIMER_BASE, 0x30,
+ IORESOURCE_MEM, NULL);
+ armada_370_xp_memory_find(&phys_base, &phys_size);
+ arm_add_mem_device("ram0", phys_base, phys_size);
+ armada_370_xp_add_uart();
+ return 0;
+}
+postcore_initcall(armada_370_xp_init_soc);
+
+void __noreturn reset_cpu(unsigned long addr)
+{
+ writel(0x1, ARMADA_370_XP_SYSCTL_BASE + 0x60);
+ writel(0x1, ARMADA_370_XP_SYSCTL_BASE + 0x64);
+ while (1)
+ ;
+}
+EXPORT_SYMBOL(reset_cpu);
diff --git a/arch/arm/mach-mvebu/common.c b/arch/arm/mach-mvebu/common.c
new file mode 100644
index 0000000000..e2092c8705
--- /dev/null
+++ b/arch/arm/mach-mvebu/common.c
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2013
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#include <common.h>
+#include <io.h>
+#include <sizes.h>
+#include <asm/barebox-arm.h>
+#include <mach/common.h>
+
+/*
+ * All MVEBU SoCs start with internal registers at 0xd0000000.
+ * To get more contiguous address space and as Linux expects them
+ * there, we remap them early to 0xf1000000.
+ *
+ * There is no way to determine internal registers base address
+ * safely later on, as the remap register itself is within the
+ * internal registers.
+ */
+#define MVEBU_BOOTUP_INT_REG_BASE 0xd0000000
+#define MVEBU_BRIDGE_REG_BASE 0x20000
+#define DEVICE_INTERNAL_BASE_ADDR (MVEBU_BRIDGE_REG_BASE + 0x80)
+
+static void mvebu_remap_registers(void)
+{
+ writel(MVEBU_REMAP_INT_REG_BASE,
+ IOMEM(MVEBU_BOOTUP_INT_REG_BASE) + DEVICE_INTERNAL_BASE_ADDR);
+}
+
+/*
+ * Determining the actual memory size is highly SoC dependent,
+ * but for all SoCs RAM starts at 0x00000000. Therefore, we start
+ * with a minimal memory setup of 64M and probe correct memory size
+ * later.
+ */
+#define MVEBU_BOOTUP_MEMORY_BASE 0x00000000
+#define MVEBU_BOOTUP_MEMORY_SIZE SZ_64M
+
+void __naked __noreturn mvebu_barebox_entry(void)
+{
+ mvebu_remap_registers();
+ barebox_arm_entry(MVEBU_BOOTUP_MEMORY_BASE,
+ MVEBU_BOOTUP_MEMORY_SIZE, 0);
+}
diff --git a/arch/arm/mach-mvebu/dove.c b/arch/arm/mach-mvebu/dove.c
new file mode 100644
index 0000000000..6e8e1130ec
--- /dev/null
+++ b/arch/arm/mach-mvebu/dove.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright
+ * (C) 2013 Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <ns16550.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <asm/memory.h>
+#include <mach/dove-regs.h>
+
+#define CONSOLE_UART_BASE DOVE_UARTn_BASE(CONFIG_MVEBU_CONSOLE_UART)
+
+static struct clk *tclk;
+
+static inline void dove_remap_mc_regs(void)
+{
+ void __iomem *mcboot = IOMEM(DOVE_BOOTUP_MC_REGS);
+ uint32_t val;
+
+ /* remap ahb slave base */
+ val = readl(DOVE_CPU_CTRL) & 0xffff0000;
+ val |= (DOVE_REMAP_MC_REGS & 0xffff0000) >> 16;
+ writel(val, DOVE_CPU_CTRL);
+
+ /* remap axi bridge address */
+ val = readl(DOVE_AXI_CTRL) & 0x007fffff;
+ val |= DOVE_REMAP_MC_REGS & 0xff800000;
+ writel(val, DOVE_AXI_CTRL);
+
+ /* remap memory controller base address */
+ val = readl(mcboot + SDRAM_REGS_BASE_DECODE) & 0x0000ffff;
+ val |= DOVE_REMAP_MC_REGS & 0xffff0000;
+ writel(val, mcboot + SDRAM_REGS_BASE_DECODE);
+}
+
+static inline void dove_memory_find(unsigned long *phys_base,
+ unsigned long *phys_size)
+{
+ int n;
+
+ *phys_base = ~0;
+ *phys_size = 0;
+
+ for (n = 0; n < 2; n++) {
+ uint32_t map = readl(DOVE_SDRAM_BASE + SDRAM_MAPn(n));
+ uint32_t base, size;
+
+ /* skip disabled areas */
+ if ((map & SDRAM_MAP_VALID) != SDRAM_MAP_VALID)
+ continue;
+
+ base = map & SDRAM_START_MASK;
+ if (base < *phys_base)
+ *phys_base = base;
+
+ /* real size is encoded as ld(2^(16+length)) */
+ size = (map & SDRAM_LENGTH_MASK) >> SDRAM_LENGTH_SHIFT;
+ *phys_size += 1 << (16 + size);
+ }
+}
+
+static struct NS16550_plat uart_plat = {
+ .shift = 2,
+};
+
+static int dove_add_uart(void)
+{
+ uart_plat.clock = clk_get_rate(tclk);
+ if (!add_ns16550_device(DEVICE_ID_DYNAMIC,
+ (unsigned int)CONSOLE_UART_BASE, 32,
+ IORESOURCE_MEM_32BIT, &uart_plat))
+ return -ENODEV;
+ return 0;
+}
+
+/*
+ * Dove TCLK sample-at-reset configuation
+ *
+ * SAR0[24:23] : TCLK frequency
+ * 0 = 166 MHz
+ * 1 = 125 MHz
+ * others reserved.
+ */
+static int dove_init_clocks(void)
+{
+ uint32_t strap, sar = readl(DOVE_SAR_BASE + SAR0);
+ unsigned int rate;
+
+ strap = (sar & TCLK_FREQ_MASK) >> TCLK_FREQ_SHIFT;
+ switch (strap) {
+ case 0:
+ rate = 166666667;
+ break;
+ case 1:
+ rate = 125000000;
+ break;
+ default:
+ panic("Unknown TCLK strapping %d\n", strap);
+ }
+
+ tclk = clk_fixed("tclk", rate);
+ return clk_register_clkdev(tclk, NULL, "orion-timer");
+}
+
+static int dove_init_soc(void)
+{
+ unsigned long phys_base, phys_size;
+
+ dove_remap_mc_regs();
+ dove_init_clocks();
+ add_generic_device("orion-timer", DEVICE_ID_SINGLE, NULL,
+ (unsigned int)DOVE_TIMER_BASE, 0x30,
+ IORESOURCE_MEM, NULL);
+ dove_memory_find(&phys_base, &phys_size);
+ arm_add_mem_device("ram0", phys_base, phys_size);
+ dove_add_uart();
+
+ return 0;
+}
+postcore_initcall(dove_init_soc);
+
+void __noreturn reset_cpu(unsigned long addr)
+{
+ /* enable and assert RSTOUTn */
+ writel(SOFT_RESET_OUT_EN, DOVE_BRIDGE_BASE + BRIDGE_RSTOUT_MASK);
+ writel(SOFT_RESET_EN, DOVE_BRIDGE_BASE + BRIDGE_SYS_SOFT_RESET);
+ while (1)
+ ;
+}
+EXPORT_SYMBOL(reset_cpu);
diff --git a/arch/arm/mach-mvebu/include/mach/armada-370-xp-regs.h b/arch/arm/mach-mvebu/include/mach/armada-370-xp-regs.h
new file mode 100644
index 0000000000..5fd16e5733
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/armada-370-xp-regs.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright
+ * (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_MVEBU_ARMADA_370_XP_REGS_H
+#define __MACH_MVEBU_ARMADA_370_XP_REGS_H
+
+#include <mach/common.h>
+
+#define ARMADA_370_XP_INT_REGS_BASE IOMEM(MVEBU_REMAP_INT_REG_BASE)
+#define ARMADA_370_XP_UART_BASE (ARMADA_370_XP_INT_REGS_BASE + 0x12000)
+#define ARMADA_370_XP_UARTn_BASE(n) \
+ (ARMADA_370_XP_UART_BASE + ((n) * 0x100))
+
+#define ARMADA_370_XP_SYSCTL_BASE (ARMADA_370_XP_INT_REGS_BASE + 0x18200)
+#define ARMADA_370_XP_SAR_BASE (ARMADA_370_XP_INT_REGS_BASE + 0x18230)
+#define SAR_LOW 0x00
+#define SAR_TCLK_FREQ BIT(20)
+#define SAR_HIGH 0x04
+
+#define ARMADA_370_XP_SDRAM_BASE (ARMADA_370_XP_INT_REGS_BASE + 0x20000)
+#define DDR_BASE_CS 0x180
+#define DDR_BASE_CSn(n) (DDR_BASE_CS + ((n) * 0x8))
+#define DDR_BASE_CS_HIGH_MASK 0x0000000f
+#define DDR_BASE_CS_LOW_MASK 0xff000000
+#define DDR_SIZE_CS 0x184
+#define DDR_SIZE_CSn(n) (DDR_SIZE_CS + ((n) * 0x8))
+#define DDR_SIZE_ENABLED BIT(0)
+#define DDR_SIZE_CS_MASK 0x0000001c
+#define DDR_SIZE_CS_SHIFT 2
+#define DDR_SIZE_MASK 0xff000000
+
+#define ARMADA_370_XP_TIMER_BASE (ARMADA_370_XP_INT_REGS_BASE + 0x20300)
+
+#endif /* __MACH_MVEBU_DOVE_REGS_H */
diff --git a/arch/arm/mach-mvebu/include/mach/common.h b/arch/arm/mach-mvebu/include/mach/common.h
new file mode 100644
index 0000000000..3cc1bf71c0
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/common.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2013
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_COMMON_H__
+#define __MACH_COMMON_H__
+
+#define MVEBU_REMAP_INT_REG_BASE 0xf1000000
+
+#endif
diff --git a/arch/arm/mach-mvebu/include/mach/debug_ll.h b/arch/arm/mach-mvebu/include/mach/debug_ll.h
new file mode 100644
index 0000000000..1cf821ee2a
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/debug_ll.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2013
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_DEBUG_LL_H__
+#define __MACH_DEBUG_LL_H__
+
+#include <io.h>
+
+#define UART_BASE 0xf1012000
+#define UARTn_BASE(n) (UART_BASE + ((n) * 0x100))
+#define UART_THR 0x00
+#define UART_LSR 0x14
+#define LSR_THRE BIT(5)
+
+#define EARLY_UART UARTn_BASE(CONFIG_MVEBU_CONSOLE_UART)
+
+static inline void PUTC_LL(char c)
+{
+ /* Wait until there is space in the FIFO */
+ while (!(readl(EARLY_UART + UART_LSR) & LSR_THRE))
+ ;
+
+ /* Send the character */
+ writel(c, EARLY_UART + UART_THR);
+
+ /* Wait to make sure it hits the line */
+ while (!(readl(EARLY_UART + UART_LSR) & LSR_THRE))
+ ;
+}
+#endif
diff --git a/arch/arm/mach-mvebu/include/mach/dove-regs.h b/arch/arm/mach-mvebu/include/mach/dove-regs.h
new file mode 100644
index 0000000000..519457e3d4
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/dove-regs.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright
+ * (C) 2013 Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_MVEBU_DOVE_REGS_H
+#define __MACH_MVEBU_DOVE_REGS_H
+
+#include <mach/common.h>
+
+/*
+ * Even after MVEBU SoC internal register base remap. Dove MC
+ * registers are still at 0xd0800000. We remap it right after
+ * internal registers to 0xf1800000.
+*/
+#define DOVE_BOOTUP_MC_REGS 0xd0800000
+#define DOVE_REMAP_MC_REGS 0xf1800000
+
+#define DOVE_INT_REGS_BASE IOMEM(MVEBU_REMAP_INT_REG_BASE)
+#define DOVE_MC_REGS_BASE IOMEM(DOVE_REMAP_MC_REGS)
+
+#define DOVE_UART_BASE (DOVE_INT_REGS_BASE + 0x12000)
+#define DOVE_UARTn_BASE(n) (DOVE_UART_BASE + ((n) * 0x100))
+
+#define DOVE_BRIDGE_BASE (DOVE_INT_REGS_BASE + 0x20000)
+#define INT_REGS_BASE_MAP 0x080
+#define BRIDGE_RSTOUT_MASK 0x108
+#define SOFT_RESET_OUT_EN BIT(2)
+#define BRIDGE_SYS_SOFT_RESET 0x10c
+#define SOFT_RESET_EN BIT(0)
+#define DOVE_TIMER_BASE (DOVE_INT_REGS_BASE + 0x20300)
+
+#define DOVE_SAR_BASE (DOVE_INT_REGS_BASE + 0xd0214)
+#define SAR0 0x000
+#define TCLK_FREQ_SHIFT 23
+#define TCLK_FREQ_MASK (0x3 << TCLK_FREQ_SHIFT)
+#define SAR1 0x004
+
+#define DOVE_AXI_CTRL (DOVE_INT_REGS_BASE + 0xd0224)
+#define DOVE_CPU_CTRL (DOVE_INT_REGS_BASE + 0xd025c)
+
+#define DOVE_SDRAM_BASE (DOVE_MC_REGS_BASE)
+#define SDRAM_REGS_BASE_DECODE 0x010
+#define SDRAM_MAPn(n) (0x100 + ((n) * 0x10))
+#define SDRAM_START_MASK (0x1ff << 23)
+#define SDRAM_LENGTH_SHIFT 16
+#define SDRAM_LENGTH_MASK (0x00f << SDRAM_LENGTH_SHIFT)
+#define SDRAM_ADDRESS_MASK (0x1ff << 7)
+#define SDRAM_MAP_VALID BIT(0)
+
+#endif /* __MACH_MVEBU_DOVE_REGS_H */
diff --git a/arch/arm/mach-mvebu/include/mach/dove.h b/arch/arm/mach-mvebu/include/mach/dove.h
new file mode 100644
index 0000000000..1712fa7a1d
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/dove.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright
+ * (C) 2013 Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_MVEBU_DOVE_H
+#define __MACH_MVEBU_DOVE_H
+
+int dove_add_uart(int num);
+void __naked __noreturn dove_barebox_entry(void);
+
+#endif /* __MACH_MVEBU_DOVE_H */
diff --git a/arch/arm/mach-mvebu/include/mach/kirkwood-regs.h b/arch/arm/mach-mvebu/include/mach/kirkwood-regs.h
new file mode 100644
index 0000000000..39fa37900b
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/kirkwood-regs.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright
+ * (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_MVEBU_KIRKWOOD_REGS_H
+#define __MACH_MVEBU_KIRKWOOD_REGS_H
+
+#include <mach/common.h>
+
+#define KIRKWOOD_INT_REGS_BASE IOMEM(MVEBU_REMAP_INT_REG_BASE)
+
+#define KIRKWOOD_SDRAM_BASE (KIRKWOOD_INT_REGS_BASE + 0x00000)
+#define DDR_BASE_CS 0x1500
+#define DDR_BASE_CSn(n) (DDR_BASE_CS + ((n) * 0x8))
+#define DDR_BASE_CS_HIGH_MASK 0x0000000f
+#define DDR_BASE_CS_LOW_MASK 0xff000000
+#define DDR_SIZE_CS 0x1504
+#define DDR_SIZE_CSn(n) (DDR_SIZE_CS + ((n) * 0x8))
+#define DDR_SIZE_ENABLED BIT(0)
+#define DDR_SIZE_CS_MASK 0x1c
+#define DDR_SIZE_CS_SHIFT 2
+#define DDR_SIZE_MASK 0xff000000
+
+#define KIRKWOOD_SAR_BASE (KIRKWOOD_INT_REGS_BASE + 0x10030)
+#define SAR_TCLK_FREQ BIT(21)
+
+#define KIRKWOOD_UART_BASE (KIRKWOOD_INT_REGS_BASE + 0x12000)
+#define KIRKWOOD_UARTn_BASE(n) (KIRKWOOD_UART_BASE + ((n) * 0x100))
+
+#define KIRKWOOD_BRIDGE_BASE (KIRKWOOD_INT_REGS_BASE + 0x20000)
+#define BRIDGE_RSTOUT_MASK 0x108
+#define SOFT_RESET_OUT_EN BIT(2)
+#define BRIDGE_SYS_SOFT_RESET 0x10c
+#define SOFT_RESET_EN BIT(0)
+
+#define KIRKWOOD_TIMER_BASE (KIRKWOOD_INT_REGS_BASE + 0x20300)
+
+#endif /* __MACH_MVEBU_KIRKWOOD_REGS_H */
diff --git a/arch/arm/mach-mvebu/include/mach/kirkwood.h b/arch/arm/mach-mvebu/include/mach/kirkwood.h
new file mode 100644
index 0000000000..7fe002d44d
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/kirkwood.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_KIRKWOOD_H
+#define __MACH_KIRKWOOD_H
+
+int kirkwood_add_uart0(void);
+void __naked __noreturn kirkwood_barebox_entry(void);
+
+#endif /* __MACH_KIRKWOOD_H */
diff --git a/arch/arm/mach-mvebu/include/mach/lowlevel.h b/arch/arm/mach-mvebu/include/mach/lowlevel.h
new file mode 100644
index 0000000000..e86d928f63
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/lowlevel.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2013
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_LOWLEVEL_H__
+#define __MACH_LOWLEVEL_H__
+
+void mvebu_barebox_entry(void);
+
+#endif
diff --git a/arch/arm/mach-mvebu/include/mach/mvebu.h b/arch/arm/mach-mvebu/include/mach/mvebu.h
new file mode 100644
index 0000000000..e13a446fca
--- /dev/null
+++ b/arch/arm/mach-mvebu/include/mach/mvebu.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * 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.
+ *
+ */
+
+#ifndef __MACH_MVEBU_H
+#define __MACH_MVEBU_H
+
+int mvebu_add_uart0(void);
+void __naked __noreturn mvebu_barebox_entry(void);
+
+#endif /* __MACH_MVEBU_H */
diff --git a/arch/arm/mach-mvebu/kirkwood.c b/arch/arm/mach-mvebu/kirkwood.c
new file mode 100644
index 0000000000..3e16f410be
--- /dev/null
+++ b/arch/arm/mach-mvebu/kirkwood.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * 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.
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <ns16550.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <asm/memory.h>
+#include <mach/kirkwood-regs.h>
+
+#define CONSOLE_UART_BASE KIRKWOOD_UARTn_BASE(CONFIG_MVEBU_CONSOLE_UART)
+
+static struct clk *tclk;
+
+static inline void kirkwood_memory_find(unsigned long *phys_base,
+ unsigned long *phys_size)
+{
+ int cs;
+
+ *phys_base = ~0;
+ *phys_size = 0;
+
+ for (cs = 0; cs < 4; cs++) {
+ u32 base = readl(KIRKWOOD_SDRAM_BASE + DDR_BASE_CSn(cs));
+ u32 ctrl = readl(KIRKWOOD_SDRAM_BASE + DDR_SIZE_CSn(cs));
+
+ /* Skip non-enabled CS */
+ if ((ctrl & DDR_SIZE_ENABLED) != DDR_SIZE_ENABLED)
+ continue;
+
+ base &= DDR_BASE_CS_LOW_MASK;
+ if (base < *phys_base)
+ *phys_base = base;
+ *phys_size += (ctrl | ~DDR_SIZE_MASK) + 1;
+ }
+}
+
+static struct NS16550_plat uart_plat = {
+ .shift = 2,
+};
+
+static int kirkwood_add_uart(void)
+{
+ uart_plat.clock = clk_get_rate(tclk);
+ if (!add_ns16550_device(DEVICE_ID_DYNAMIC,
+ (unsigned int)CONSOLE_UART_BASE, 32,
+ IORESOURCE_MEM_32BIT, &uart_plat))
+ return -ENODEV;
+ return 0;
+}
+
+static int kirkwood_init_clocks(void)
+{
+ u32 val = readl(KIRKWOOD_SAR_BASE);
+ unsigned int rate;
+
+ /*
+ * On Kirkwood, the TCLK frequency can be either
+ * 166 Mhz or 200 Mhz
+ */
+ if ((val & SAR_TCLK_FREQ) == SAR_TCLK_FREQ)
+ rate = 166666667;
+ else
+ rate = 200000000;
+
+ tclk = clk_fixed("tclk", rate);
+ return clk_register_clkdev(tclk, NULL, "orion-timer");
+}
+
+static int kirkwood_init_soc(void)
+{
+ unsigned long phys_base, phys_size;
+
+ kirkwood_init_clocks();
+ add_generic_device("orion-timer", DEVICE_ID_SINGLE, NULL,
+ (unsigned int)KIRKWOOD_TIMER_BASE, 0x30,
+ IORESOURCE_MEM, NULL);
+ kirkwood_memory_find(&phys_base, &phys_size);
+ arm_add_mem_device("ram0", phys_base, phys_size);
+ kirkwood_add_uart();
+
+ return 0;
+}
+postcore_initcall(kirkwood_init_soc);
+
+void __noreturn reset_cpu(unsigned long addr)
+{
+ writel(SOFT_RESET_OUT_EN, KIRKWOOD_BRIDGE_BASE + BRIDGE_RSTOUT_MASK);
+ writel(SOFT_RESET_EN, KIRKWOOD_BRIDGE_BASE + BRIDGE_SYS_SOFT_RESET);
+ for(;;)
+ ;
+}
+EXPORT_SYMBOL(reset_cpu);
diff --git a/arch/arm/mach-mvebu/lowlevel.c b/arch/arm/mach-mvebu/lowlevel.c
new file mode 100644
index 0000000000..3f64c4a5b4
--- /dev/null
+++ b/arch/arm/mach-mvebu/lowlevel.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2013
+ * Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#include <common.h>
+#include <sizes.h>
+#include <asm/barebox-arm.h>
+#include <asm/barebox-arm-head.h>
+#include <mach/lowlevel.h>
+
+void __naked barebox_arm_reset_vector(void)
+{
+ arm_cpu_lowlevel_init();
+ mvebu_barebox_entry();
+}
diff --git a/arch/arm/mach-mxs/imx.c b/arch/arm/mach-mxs/imx.c
index fcb26f73b3..5acce9376a 100644
--- a/arch/arm/mach-mxs/imx.c
+++ b/arch/arm/mach-mxs/imx.c
@@ -112,6 +112,48 @@ static void mxs_silicon_revision(void)
silicon_revision_set(product, revision);
}
+#define HW_PINCTRL_MUXSEL2 0x120
+#define HW_PINCTRL_MUXSEL3 0x130
+#define HW_PINCTRL_DOE1 0x710
+#define HW_PINCTRL_DIN1 0x610
+
+/*
+ * we are interested in the setting of:
+ * - GPIO BANK1/19: 1 = the ROM has used the following pins for boot source selection
+ * - GPIO BANK1/5: ETM enable
+ * - GPIO BANK1/3: BM3
+ * - GPIO BANK1/2: BM2
+ * - GPIO BANK1/1: BM1
+ * - GPIO BANK1/0: BM0
+ */
+static uint32_t mx23_detect_bootsource(void)
+{
+ uint32_t mux2, mux3, dir, mode;
+
+ mux3 = readl(IMX_IOMUXC_BASE + HW_PINCTRL_MUXSEL3);
+ mux2 = readl(IMX_IOMUXC_BASE + HW_PINCTRL_MUXSEL2);
+ dir = readl(IMX_IOMUXC_BASE + HW_PINCTRL_DOE1);
+
+ /* force the GPIO lines of interest to input */
+ writel(0x0008002f, IMX_IOMUXC_BASE + HW_PINCTRL_DOE1 + 8);
+ /* force the GPIO lines of interest to act as GPIO */
+ writel(0x00000cff, IMX_IOMUXC_BASE + HW_PINCTRL_MUXSEL2 + 4);
+ writel(0x000000c0, IMX_IOMUXC_BASE + HW_PINCTRL_MUXSEL3 + 4);
+
+ /* read the bootstrapping */
+ mode = readl(IMX_IOMUXC_BASE + HW_PINCTRL_DIN1) & 0x8002f;
+
+ /* restore previous settings */
+ writel(mux3, IMX_IOMUXC_BASE + HW_PINCTRL_MUXSEL3);
+ writel(mux2, IMX_IOMUXC_BASE + HW_PINCTRL_MUXSEL2);
+ writel(dir, IMX_IOMUXC_BASE + HW_PINCTRL_DOE1);
+
+ if (!(mode & (1 << 19)))
+ return 0xff; /* invalid marker */
+
+ return (mode & 0xf) | ((mode & 0x20) >> 1);
+}
+
#define MX28_REV_1_0_MODE (0x0001a7f0)
#define MX28_REV_1_2_MODE (0x00019bf0)
@@ -122,7 +164,7 @@ static void mxs_boot_save_loc(void)
uint32_t mode = 0xff;
if (cpu_is_mx23()) {
- /* not implemented yet */
+ mode = mx23_detect_bootsource();
} else if (cpu_is_mx28()) {
enum silicon_revision rev = silicon_revision_get();
diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig
index f7aa8c5a28..3ec18f0c4d 100644
--- a/arch/arm/mach-omap/Kconfig
+++ b/arch/arm/mach-omap/Kconfig
@@ -214,6 +214,18 @@ endchoice
endif
+if MACH_PCM049
+ choice
+ prompt "Select DDR2-RAM Size"
+
+ config 512MB_DDR2RAM
+ bool "512MB"
+ config 1024MB_DDR2RAM
+ bool "1024MB"
+
+ endchoice
+endif
+
config MACH_OMAP_ADVANCED_MUX
bool "Enable advanced pin muxing"
depends on MACH_OMAP343xSDP
diff --git a/arch/arm/mach-omap/am33xx_clock.c b/arch/arm/mach-omap/am33xx_clock.c
index a28540c919..4451d62268 100644
--- a/arch/arm/mach-omap/am33xx_clock.c
+++ b/arch/arm/mach-omap/am33xx_clock.c
@@ -89,6 +89,14 @@ static void per_clocks_enable(void)
__raw_writel(PRCM_MOD_EN, CM_WKUP_UART0_CLKCTRL);
while (__raw_readl(CM_WKUP_UART0_CLKCTRL) != PRCM_MOD_EN);
+ /* UART1 */
+ __raw_writel(PRCM_MOD_EN, CM_PER_UART1_CLKCTRL);
+ while (__raw_readl(CM_PER_UART1_CLKCTRL) != PRCM_MOD_EN);
+
+ /* UART2 */
+ __raw_writel(PRCM_MOD_EN, CM_PER_UART2_CLKCTRL);
+ while (__raw_readl(CM_PER_UART2_CLKCTRL) != PRCM_MOD_EN);
+
/* UART3 */
__raw_writel(PRCM_MOD_EN, CM_PER_UART3_CLKCTRL);
while (__raw_readl(CM_PER_UART3_CLKCTRL) != PRCM_MOD_EN);
diff --git a/arch/arm/mach-omap/am33xx_mux.c b/arch/arm/mach-omap/am33xx_mux.c
index 36fe3792d1..424d120125 100644
--- a/arch/arm/mach-omap/am33xx_mux.c
+++ b/arch/arm/mach-omap/am33xx_mux.c
@@ -27,6 +27,12 @@ static const __maybe_unused struct module_pin_mux uart0_pin_mux[] = {
{-1},
};
+static const __maybe_unused struct module_pin_mux uart2_pin_mux[] = {
+ {OFFSET(mii1_txclk), (MODE(1) | PULLUDEN | RXACTIVE)}, /* UART2_RXD */
+ {OFFSET(mii1_rxclk), (MODE(1) | PULLUDEN)}, /* UART2_TXD */
+ {-1},
+};
+
static const __maybe_unused struct module_pin_mux uart3_pin_mux[] = {
{OFFSET(spi0_cs1), (MODE(1) | PULLUDEN | RXACTIVE)}, /* UART3_RXD */
{OFFSET(ecap0_in_pwm0_out), (MODE(1) | PULLUDEN)}, /* UART3_TXD */
@@ -142,6 +148,20 @@ static const __maybe_unused struct module_pin_mux rmii1_pin_mux[] = {
{-1},
};
+static const __maybe_unused struct module_pin_mux rmii2_pin_mux[] = {
+ {OFFSET(gpmc_a0), MODE(3)}, /* RMII2_TXEN */
+ {OFFSET(gpmc_a4), MODE(3)}, /* RMII2_TXD1 */
+ {OFFSET(gpmc_a5), MODE(3)}, /* RMII2_TXD0 */
+ {OFFSET(gpmc_a10), MODE(3) | RXACTIVE}, /* RMII2_RXD1 */
+ {OFFSET(gpmc_a11), MODE(3) | RXACTIVE}, /* RMII2_RXD0 */
+ {OFFSET(gpmc_wait0), MODE(3) | RXACTIVE}, /* RMII2_CRS */
+ {OFFSET(gpmc_wpn), MODE(3) | RXACTIVE}, /* RMII2_RXERR */
+ {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */
+ {OFFSET(mdio_clk), MODE(0) | PULLUP_EN}, /* MDIO_CLK */
+ {OFFSET(mii1_col), MODE(1) | RXACTIVE}, /* RMII2_REFCLK */
+ {-1},
+};
+
#ifdef CONFIG_NOR
static const __maybe_unused struct module_pin_mux nor_pin_mux[] = {
{OFFSET(lcd_data0), MODE(1) | PULLUDEN}, /* NOR_A0 */
@@ -255,6 +275,16 @@ void am33xx_enable_mii1_pin_mux(void)
configure_module_pin_mux(mii1_pin_mux);
}
+void am33xx_enable_rmii1_pin_mux(void)
+{
+ configure_module_pin_mux(rmii1_pin_mux);
+}
+
+void am33xx_enable_rmii2_pin_mux(void)
+{
+ configure_module_pin_mux(rmii2_pin_mux);
+}
+
void am33xx_enable_i2c0_pin_mux(void)
{
configure_module_pin_mux(i2c0_pin_mux);
@@ -275,6 +305,11 @@ void am33xx_enable_uart0_pin_mux(void)
configure_module_pin_mux(uart0_pin_mux);
}
+void am33xx_enable_uart2_pin_mux(void)
+{
+ configure_module_pin_mux(uart2_pin_mux);
+}
+
void am33xx_enable_mmc0_pin_mux(void)
{
configure_module_pin_mux(mmc0_pin_mux);
diff --git a/arch/arm/mach-omap/include/mach/am33xx-clock.h b/arch/arm/mach-omap/include/mach/am33xx-clock.h
index 2ecfc5fc8d..3d1f074da9 100644
--- a/arch/arm/mach-omap/include/mach/am33xx-clock.h
+++ b/arch/arm/mach-omap/include/mach/am33xx-clock.h
@@ -136,7 +136,10 @@
#define CM_PER_GPIO1_CLKCTRL (CM_PER + 0xAC) /* GPIO1 */
#define CM_PER_GPIO2_CLKCTRL (CM_PER + 0xB0) /* GPIO2 */
#define CM_PER_GPIO3_CLKCTRL (CM_PER + 0xB4) /* GPIO3 */
+#define CM_PER_UART1_CLKCTRL (CM_PER + 0x6C) /* UART1 */
+#define CM_PER_UART2_CLKCTRL (CM_PER + 0x70) /* UART2 */
#define CM_PER_UART3_CLKCTRL (CM_PER + 0x74) /* UART3 */
+#define CM_PER_UART4_CLKCTRL (CM_PER + 0x78) /* UART4 */
#define CM_PER_I2C1_CLKCTRL (CM_PER + 0x48) /* I2C1 */
#define CM_PER_I2C2_CLKCTRL (CM_PER + 0x44) /* I2C2 */
#define CM_WKUP_GPIO0_CLKCTRL (CM_WKUP + 0x8) /* GPIO0 */
diff --git a/arch/arm/mach-omap/include/mach/am33xx-mux.h b/arch/arm/mach-omap/include/mach/am33xx-mux.h
index 896e9588eb..44b93bd25c 100644
--- a/arch/arm/mach-omap/include/mach/am33xx-mux.h
+++ b/arch/arm/mach-omap/include/mach/am33xx-mux.h
@@ -248,10 +248,13 @@ extern void configure_module_pin_mux(const struct module_pin_mux *mod_pin_mux);
/* Standard mux settings */
extern void am33xx_enable_mii1_pin_mux(void);
+extern void am33xx_enable_rmii1_pin_mux(void);
+extern void am33xx_enable_rmii2_pin_mux(void);
extern void am33xx_enable_i2c0_pin_mux(void);
extern void am33xx_enable_i2c1_pin_mux(void);
extern void am33xx_enable_i2c2_pin_mux(void);
extern void am33xx_enable_uart0_pin_mux(void);
+extern void am33xx_enable_uart2_pin_mux(void);
extern void am33xx_enable_mmc0_pin_mux(void);
#endif /*__AM33XX_MUX_H__ */
diff --git a/arch/arm/mach-omap/omap4_twl6030_mmc.c b/arch/arm/mach-omap/omap4_twl6030_mmc.c
index 7d71eb868a..155add6ea1 100644
--- a/arch/arm/mach-omap/omap4_twl6030_mmc.c
+++ b/arch/arm/mach-omap/omap4_twl6030_mmc.c
@@ -16,7 +16,7 @@
#include <common.h>
#include <io.h>
-#include <mci/twl6030.h>
+#include <mfd/twl6030.h>
/* MMC voltage */
#define OMAP4_CONTROL_PBIASLITE 0x4A100600
@@ -24,6 +24,16 @@
#define OMAP4_MMC1_PBIASLITE_PWRDNZ (1<<22)
#define OMAP4_MMC1_PWRDNZ (1<<26)
+static void twl6030_mci_write(u8 address, u8 data)
+{
+ int ret;
+ struct twl6030 *twl6030 = twl6030_get();
+
+ ret = twl6030_reg_write(twl6030, address, data);
+ if (ret != 0)
+ printf("TWL6030 Write[0x%x] Error %d\n", address, ret);
+}
+
void set_up_mmc_voltage_omap4(void)
{
u32 value;
@@ -32,7 +42,12 @@ void set_up_mmc_voltage_omap4(void)
value &= ~(OMAP4_MMC1_PBIASLITE_PWRDNZ | OMAP4_MMC1_PWRDNZ);
writel(value, OMAP4_CONTROL_PBIASLITE);
- twl6030_mci_power_init();
+ twl6030_mci_write(TWL6030_PMCS_VMMC_CFG_VOLTAGE,
+ TWL6030_VMMC_WR_S |
+ TWL6030_VMMC_VSEL_0 | TWL6030_VMMC_VSEL_2 |
+ TWL6030_VMMC_VSEL_4);
+ twl6030_mci_write(TWL6030_PMCS_VMMC_CFG_STATE,
+ TWL6030_VMMC_STATE0 | TWL6030_VMMC_GRP_APP);
value = readl(OMAP4_CONTROL_PBIASLITE);
value |= (OMAP4_MMC1_PBIASLITE_VMODE | OMAP4_MMC1_PBIASLITE_PWRDNZ |
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index 965e7ab6ba..9224e628cb 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -5,6 +5,7 @@ choice
config ARCH_TEGRA_2x_SOC
bool "Tegra 20"
+ select PINCTRL_TEGRA20
endchoice
@@ -52,6 +53,11 @@ config ARCH_TEXT_BASE
choice
prompt "Tegra 20 Board Type"
+config MACH_TEGRA20_GENERIC
+ bool "Generic DT based board"
+ help
+ Say Y here if you are building for a generic DT based board.
+
config MACH_TOSHIBA_AC100
bool "Toshiba AC100"
help
@@ -59,6 +65,13 @@ config MACH_TOSHIBA_AC100
endchoice
+if MACH_TEGRA20_GENERIC
+
+config BOARDINFO
+ default "Generic Tegra20 board"
+
+endif #MACH_TEGRA20_GENERIC
+
source arch/arm/boards/toshiba-ac100/Kconfig
endif #ARCH_TEGRA_2x_SOC
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 947edcf6f8..2e44619a0e 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -23,6 +23,14 @@ config GENERIC_LINKER_SCRIPT
menu "Machine selection"
+config BUILTIN_DTB
+ bool "link a DTB into the barebox image"
+ depends on OFTREE
+
+config BUILTIN_DTB_NAME
+ string "DTB to build into the barebox image"
+ depends on BUILTIN_DTB
+
choice
prompt "System type"
default MACH_MIPS_MALTA
@@ -37,6 +45,14 @@ config MACH_MIPS_MALTA
select SYS_SUPPORTS_BIG_ENDIAN
select HAS_DEBUG_LL
+config MACH_MIPS_AR231X
+ bool "Atheros ar231x-based boards"
+ select SYS_HAS_CPU_MIPS32_R1
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select CSRC_R4K_LIB
+ select DRIVER_SERIAL_NS16550
+
config MACH_MIPS_BCM47XX
bool "Broadcom BCM47xx-based boards"
select CSRC_R4K_LIB
@@ -53,9 +69,12 @@ config MACH_MIPS_XBURST
select SYS_SUPPORTS_32BIT_KERNEL
select DRIVER_SERIAL_NS16550
select HAS_DEBUG_LL
+ select HAVE_PBL_IMAGE
+ select HAVE_IMAGE_COMPRESSION
endchoice
source arch/mips/mach-malta/Kconfig
+source arch/mips/mach-ar231x/Kconfig
source arch/mips/mach-bcm47xx/Kconfig
source arch/mips/mach-xburst/Kconfig
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 3c565a48af..dc0fe56d68 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -72,6 +72,9 @@ LDFLAGS_barebox += -nostdlib
machine-$(CONFIG_MACH_MIPS_MALTA) := malta
board-$(CONFIG_BOARD_QEMU_MALTA) := qemu-malta
+machine-$(CONFIG_MACH_MIPS_AR231X) := ar231x
+board-$(CONFIG_BOARD_NETGEAR_WG102) := netgear-wg102
+
machine-$(CONFIG_MACH_MIPS_BCM47XX) := bcm47xx
board-$(CONFIG_BOARD_DLINK_DIR320) := dlink-dir-320
@@ -113,6 +116,8 @@ common-y += $(BOARD) $(MACH)
common-y += arch/mips/lib/
common-y += arch/mips/boot/
+common-$(CONFIG_BUILTIN_DTB) += arch/mips/dts/
+
CPPFLAGS += $(cflags-y)
CFLAGS += $(cflags-y)
@@ -127,4 +132,14 @@ zbarebox.S zbarebox.bin zbarebox: barebox.bin
archclean:
$(MAKE) $(clean)=$(pbl)
+dts := arch/mips/dts
+
+%.dtb: scripts
+ $(Q)$(MAKE) $(build)=$(dts) $(dts)/$@
+
+dtbs: scripts
+ $(Q)$(MAKE) $(build)=$(dts) dtbs
+
+KBUILD_DTBS := dtbs
+
KBUILD_IMAGE ?= $(KBUILD_BINARY)
diff --git a/arch/mips/boards/netgear-wg102/Kconfig b/arch/mips/boards/netgear-wg102/Kconfig
new file mode 100644
index 0000000000..ceca6de820
--- /dev/null
+++ b/arch/mips/boards/netgear-wg102/Kconfig
@@ -0,0 +1,6 @@
+if BOARD_NETGEAR_WG102
+
+config BOARDINFO
+ default "Netgear WG102"
+
+endif
diff --git a/arch/mips/boards/netgear-wg102/Makefile b/arch/mips/boards/netgear-wg102/Makefile
new file mode 100644
index 0000000000..0899b66c5f
--- /dev/null
+++ b/arch/mips/boards/netgear-wg102/Makefile
@@ -0,0 +1 @@
+obj-y += ram.o
diff --git a/arch/mips/boards/netgear-wg102/ram.c b/arch/mips/boards/netgear-wg102/ram.c
new file mode 100644
index 0000000000..00a008a1ee
--- /dev/null
+++ b/arch/mips/boards/netgear-wg102/ram.c
@@ -0,0 +1,11 @@
+#include <common.h>
+#include <init.h>
+#include <sizes.h>
+#include <asm/memory.h>
+
+static int mem_init(void)
+{
+ mips_add_ram0(SZ_16M);
+ return 0;
+}
+mem_initcall(mem_init);
diff --git a/arch/mips/boards/qemu-malta/init.c b/arch/mips/boards/qemu-malta/init.c
index fb4472fe86..db26b3b5c9 100644
--- a/arch/mips/boards/qemu-malta/init.c
+++ b/arch/mips/boards/qemu-malta/init.c
@@ -20,21 +20,10 @@
#include <types.h>
#include <driver.h>
#include <init.h>
-#include <asm/memory.h>
#include <ns16550.h>
#include <mach/hardware.h>
-#include <io.h>
#include <partition.h>
#include <sizes.h>
-#include <asm/common.h>
-
-static int malta_mem_init(void)
-{
- mips_add_ram0(SZ_256M);
-
- return 0;
-}
-mem_initcall(malta_mem_init);
static int malta_devices_init(void)
{
diff --git a/arch/mips/boards/rzx50/include/board/board_pbl_start.h b/arch/mips/boards/rzx50/include/board/board_pbl_start.h
new file mode 100644
index 0000000000..cba3e7f470
--- /dev/null
+++ b/arch/mips/boards/rzx50/include/board/board_pbl_start.h
@@ -0,0 +1,34 @@
+/*
+ * Startup Code for Ritmix RZX-50 board
+ *
+ * Copyright (C) 2013 Antony Pavlov <antonynpavlov@gmail.com>
+ *
+ * This file is part of barebox.
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+
+#include <asm/pbl_macros.h>
+
+ .macro board_pbl_start
+ .set push
+ .set noreorder
+
+ mips_disable_interrupts
+
+ /* CPU/SoC specific setup ... */
+ /* ... absent */
+
+ copy_to_link_location pbl_start
+
+ .set pop
+ .endm
diff --git a/arch/mips/boards/rzx50/include/board/debug_ll.h b/arch/mips/boards/rzx50/include/board/debug_ll.h
index 3d183b0a1c..7ae0e2a4fd 100644
--- a/arch/mips/boards/rzx50/include/board/debug_ll.h
+++ b/arch/mips/boards/rzx50/include/board/debug_ll.h
@@ -18,9 +18,6 @@
#ifndef __INCLUDE_RZX50_BOARD_DEBUG_LL_H__
#define __INCLUDE_RZX50_BOARD_DEBUG_LL_H__
-#include <mach/jz4750d_regs.h>
-
-#define DEBUG_LL_UART_ADDR UART1_BASE
-#define DEBUG_LL_UART_SHIFT 2
+#include <mach/debug_ll_jz4750d.h>
#endif /* __INCLUDE_RZX50_BOARD_DEBUG_LL_H__ */
diff --git a/arch/mips/boards/rzx50/serial.c b/arch/mips/boards/rzx50/serial.c
index 5230aaa8c8..129806d5a1 100644
--- a/arch/mips/boards/rzx50/serial.c
+++ b/arch/mips/boards/rzx50/serial.c
@@ -16,47 +16,14 @@
*/
#include <common.h>
-#include <types.h>
-#include <driver.h>
#include <init.h>
-#include <ns16550.h>
+#include <mach/devices.h>
#include <mach/jz4750d_regs.h>
-#include <io.h>
-#include <asm/common.h>
-
-#define JZ4750D_UART_SHIFT 2
-
-#define ier (1 << JZ4750D_UART_SHIFT)
-#define fcr (2 << JZ4750D_UART_SHIFT)
-
-static void jz4750d_serial_reg_write(unsigned int val, unsigned long base,
- unsigned char reg_offset)
-{
- switch (reg_offset) {
- case fcr:
- val |= 0x10; /* Enable uart module */
- break;
- case ier:
- val |= (val & 0x4) << 2;
- break;
- default:
- break;
- }
-
- writeb(val & 0xff, (void *)(base + reg_offset));
-}
-
-static struct NS16550_plat serial_plat = {
- .clock = 12000000,
- .shift = JZ4750D_UART_SHIFT,
- .reg_write = &jz4750d_serial_reg_write,
-};
static int rzx50_console_init(void)
{
/* Register the serial port */
- add_ns16550_device(DEVICE_ID_DYNAMIC, UART1_BASE, 8 << JZ4750D_UART_SHIFT,
- IORESOURCE_MEM_8BIT, &serial_plat);
+ jz_add_uart(DEVICE_ID_DYNAMIC, UART1_BASE, 12000000);
return 0;
}
diff --git a/arch/mips/boot/Makefile b/arch/mips/boot/Makefile
index 6b093f1e0e..b865b10f8b 100644
--- a/arch/mips/boot/Makefile
+++ b/arch/mips/boot/Makefile
@@ -1,4 +1,6 @@
obj-y += start.o
obj-y += main_entry.o
+obj-$(CONFIG_BUILTIN_DTB) += dtb.o
+
pbl-y += start-pbl.o main_entry-pbl.o
diff --git a/arch/mips/boot/dtb.c b/arch/mips/boot/dtb.c
new file mode 100644
index 0000000000..c1962bfd0c
--- /dev/null
+++ b/arch/mips/boot/dtb.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2013 Antony Pavlov <antonynpavlov@gmail.com>
+ *
+ * Based on arch/arm/cpu/dtb.c:
+ * Copyright (C) 2013 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+#include <common.h>
+#include <init.h>
+#include <of.h>
+#include <memory.h>
+#include <asm/addrspace.h>
+
+void of_add_memory_bank(struct device_node *node, bool dump, int r,
+ u64 base, u64 size)
+{
+ static char str[12];
+
+ sprintf(str, "kseg0_ram%d", r);
+ barebox_add_memory_bank(str, KSEG0 | base, size);
+
+ sprintf(str, "kseg1_ram%d", r);
+ barebox_add_memory_bank(str, KSEG1 | base, size);
+
+ if (dump)
+ pr_info("%s: %s: 0x%llx@0x%llx\n", node->name, str, size, base);
+}
+
+extern char __dtb_start[];
+
+static int of_mips_init(void)
+{
+ struct device_node *root;
+
+ root = of_get_root_node();
+ if (root)
+ return 0;
+
+ root = of_unflatten_dtb(NULL, __dtb_start);
+ if (root) {
+ pr_debug("using internal DTB\n");
+ of_set_root_node(root);
+ if (IS_ENABLED(CONFIG_OFDEVICE))
+ of_probe();
+ }
+
+ return 0;
+}
+core_initcall(of_mips_init);
diff --git a/arch/mips/configs/qemu-malta_defconfig b/arch/mips/configs/qemu-malta_defconfig
index 7dab969931..18c840d7c3 100644
--- a/arch/mips/configs/qemu-malta_defconfig
+++ b/arch/mips/configs/qemu-malta_defconfig
@@ -1,3 +1,5 @@
+CONFIG_BUILTIN_DTB=y
+CONFIG_BUILTIN_DTB_NAME="qemu-malta"
CONFIG_PBL_IMAGE=y
CONFIG_STACK_SIZE=0x7000
CONFIG_BROKEN=y
@@ -23,22 +25,25 @@ CONFIG_CMD_MENU=y
CONFIG_CMD_MENU_MANAGEMENT=y
CONFIG_CMD_PASSWD=y
CONFIG_CMD_TIME=y
+CONFIG_CMD_TFTP=y
CONFIG_CMD_ECHO_E=y
CONFIG_CMD_LOADB=y
CONFIG_CMD_LOADY=y
CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_IOMEM=y
CONFIG_CMD_CRC=y
CONFIG_CMD_CRC_CMP=y
CONFIG_CMD_MD5SUM=y
CONFIG_CMD_SHA1SUM=y
CONFIG_CMD_SHA256SUM=y
-CONFIG_CMD_MTEST=y
CONFIG_CMD_FLASH=y
-CONFIG_CMD_BOOTM_ZLIB=y
-CONFIG_CMD_BOOTM_BZLIB=y
CONFIG_CMD_BOOTM_SHOW_TYPE=y
CONFIG_CMD_RESET=y
CONFIG_CMD_GO=y
+CONFIG_CMD_OFTREE=y
+CONFIG_CMD_OF_PROPERTY=y
+CONFIG_CMD_OF_NODE=y
+CONFIG_CMD_MTEST=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_UNCOMPRESS=y
@@ -46,18 +51,18 @@ CONFIG_NET=y
CONFIG_NET_DHCP=y
CONFIG_NET_NFS=y
CONFIG_NET_PING=y
-CONFIG_CMD_TFTP=y
-CONFIG_FS_TFTP=y
CONFIG_NET_NETCONSOLE=y
CONFIG_NET_RESOLV=y
+CONFIG_OFDEVICE=y
# CONFIG_SPI is not set
+CONFIG_MTD=y
CONFIG_DRIVER_CFI=y
# CONFIG_DRIVER_CFI_AMD is not set
# CONFIG_DRIVER_CFI_BANK_WIDTH_1 is not set
# CONFIG_DRIVER_CFI_BANK_WIDTH_2 is not set
CONFIG_CFI_BUFFER_WRITE=y
-CONFIG_MTD=y
CONFIG_FS_CRAMFS=y
+CONFIG_FS_TFTP=y
CONFIG_FS_FAT=y
CONFIG_FS_FAT_WRITE=y
CONFIG_FS_FAT_LFN=y
diff --git a/arch/mips/configs/rzx50_defconfig b/arch/mips/configs/rzx50_defconfig
index 722d977f50..5d994c76e1 100644
--- a/arch/mips/configs/rzx50_defconfig
+++ b/arch/mips/configs/rzx50_defconfig
@@ -1,4 +1,5 @@
CONFIG_MACH_MIPS_XBURST=y
+CONFIG_PBL_IMAGE=y
CONFIG_BAUDRATE=57600
CONFIG_GLOB=y
CONFIG_HUSH_FANCY_PROMPT=y
@@ -14,6 +15,7 @@ CONFIG_CMD_LOADY=y
CONFIG_CMD_LOADS=y
CONFIG_CMD_SAVES=y
CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_IOMEM=y
CONFIG_CMD_MD5SUM=y
CONFIG_CMD_BOOTM_SHOW_TYPE=y
CONFIG_CMD_BOOTM_VERBOSE=y
@@ -22,6 +24,7 @@ CONFIG_CMD_BOOTM_OFTREE=y
CONFIG_CMD_BOOTM_OFTREE_UIMAGE=y
CONFIG_CMD_UIMAGE=y
CONFIG_CMD_RESET=y
+CONFIG_CMD_POWEROFF=y
CONFIG_CMD_GO=y
# CONFIG_SPI is not set
CONFIG_SHA1=y
diff --git a/arch/mips/dts/Makefile b/arch/mips/dts/Makefile
new file mode 100644
index 0000000000..3ee89247e0
--- /dev/null
+++ b/arch/mips/dts/Makefile
@@ -0,0 +1,10 @@
+
+BUILTIN_DTB := $(patsubst "%",%,$(CONFIG_BUILTIN_DTB_NAME)).dtb.o
+obj-$(CONFIG_BUILTIN_DTB) += $(BUILTIN_DTB)
+
+targets += dtbs
+targets += $(dtb-y)
+
+dtbs: $(addprefix $(obj)/, $(dtb-y))
+
+clean-files := *.dtb *.dtb.S
diff --git a/arch/mips/dts/qemu-malta.dts b/arch/mips/dts/qemu-malta.dts
new file mode 100644
index 0000000000..c4dcf056c1
--- /dev/null
+++ b/arch/mips/dts/qemu-malta.dts
@@ -0,0 +1,12 @@
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+
+/ {
+ model = "qemu malta";
+ compatible = "qemu,malta";
+
+ memory {
+ reg = <0x00000000 0x10000000>;
+ };
+};
diff --git a/arch/mips/dts/skeleton.dtsi b/arch/mips/dts/skeleton.dtsi
new file mode 100644
index 0000000000..b41d241de2
--- /dev/null
+++ b/arch/mips/dts/skeleton.dtsi
@@ -0,0 +1,13 @@
+/*
+ * Skeleton device tree; the bare minimum needed to boot; just include and
+ * add a compatible value. The bootloader will typically populate the memory
+ * node.
+ */
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ chosen { };
+ aliases { };
+ memory { device_type = "memory"; reg = <0 0>; };
+};
diff --git a/arch/mips/include/asm/debug_ll_ns16550.h b/arch/mips/include/asm/debug_ll_ns16550.h
new file mode 100644
index 0000000000..5dd1b39041
--- /dev/null
+++ b/arch/mips/include/asm/debug_ll_ns16550.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2012, 2013 Antony Pavlov <antonynpavlov@gmail.com>
+ *
+ * This file is part of barebox.
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+
+/** @file
+ * This file contains declaration for early output support
+ */
+#ifndef __INCLUDE_MIPS_ASM_DEBUG_LL_NS16550_H__
+#define __INCLUDE_MIPS_ASM_DEBUG_LL_NS16550_H__
+
+#ifdef CONFIG_DEBUG_LL
+
+#ifndef DEBUG_LL_UART_ADDR
+#error DEBUG_LL_UART_ADDR is undefined!
+#endif
+
+#ifndef DEBUG_LL_UART_SHIFT
+#error DEBUG_LL_UART_SHIFT is undefined!
+#endif
+
+#ifndef DEBUG_LL_UART_DIVISOR
+#error DEBUG_LL_UART_DIVISOR is undefined!
+#endif
+
+#endif /* CONFIG_DEBUG_LL */
+
+#define UART_THR (0x0 << DEBUG_LL_UART_SHIFT)
+#define UART_DLL (0x0 << DEBUG_LL_UART_SHIFT)
+#define UART_DLM (0x1 << DEBUG_LL_UART_SHIFT)
+#define UART_LCR (0x3 << DEBUG_LL_UART_SHIFT)
+#define UART_LSR (0x5 << DEBUG_LL_UART_SHIFT)
+
+#define UART_LCR_W 0x07 /* Set UART to 8,N,2 & DLAB = 0 */
+#define UART_LCR_DLAB 0x87 /* Set UART to 8,N,2 & DLAB = 1 */
+
+#define UART_LSR_THRE 0x20 /* Xmit holding register empty */
+
+/*
+ * Macros for use in assembly language code
+ */
+
+.macro debug_ll_ns16550_init
+#ifdef CONFIG_DEBUG_LL
+ la t0, DEBUG_LL_UART_ADDR
+
+ li t1, UART_LCR_DLAB /* DLAB on */
+ sb t1, UART_LCR(t0) /* Write it out */
+
+ li t1, DEBUG_LL_UART_DIVISOR
+ sb t1, UART_DLL(t0) /* write low order byte */
+ srl t1, t1, 8
+ sb t1, UART_DLM(t0) /* write high order byte */
+
+ li t1, UART_LCR_W /* DLAB off */
+ sb t1, UART_LCR(t0) /* Write it out */
+#endif /* CONFIG_DEBUG_LL */
+.endm
+
+/*
+ * output a character in a0
+ */
+.macro debug_ll_ns16550_outc chr
+#ifdef CONFIG_DEBUG_LL
+ li a0, \chr
+ la t0, DEBUG_LL_UART_ADDR
+
+1: lbu t1, UART_LSR(t0) /* get line status */
+ nop
+ andi t1, t1, UART_LSR_THRE /* check for transmitter empty */
+ beqz t1, 1b /* try again */
+ nop
+
+ sb a0, UART_THR(t0) /* write the character */
+#endif /* CONFIG_DEBUG_LL */
+.endm
+
+/*
+ * output CR + NL
+ */
+.macro debug_ll_ns16550_outnl
+#ifdef CONFIG_DEBUG_LL
+ debug_ll_ns16550_outc '\r'
+ debug_ll_ns16550_outc '\n'
+#endif /* CONFIG_DEBUG_LL */
+.endm
+
+#endif /* __INCLUDE_MIPS_ASM_DEBUG_LL_NS16550_H__ */
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 608f19bda1..f9238607ab 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -673,19 +673,11 @@ do { \
#define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val)
#define read_c0_status() __read_32bit_c0_register($12, 0)
-#ifdef CONFIG_MIPS_MT_SMTC
-#define write_c0_status(val) \
-do { \
- __write_32bit_c0_register($12, 0, val); \
- __ehb(); \
-} while (0)
-#else
/*
* Legacy non-SMTC code, which may be hazardous
* but which might not support EHB
*/
#define write_c0_status(val) __write_32bit_c0_register($12, 0, val)
-#endif /* CONFIG_MIPS_MT_SMTC */
#define read_c0_cause() __read_32bit_c0_register($13, 0)
#define write_c0_cause(val) __write_32bit_c0_register($13, 0, val)
diff --git a/arch/mips/lib/barebox.lds.S b/arch/mips/lib/barebox.lds.S
index 5b3d45dc3c..bc78d2be8c 100644
--- a/arch/mips/lib/barebox.lds.S
+++ b/arch/mips/lib/barebox.lds.S
@@ -69,6 +69,8 @@ SECTIONS
__usymtab : { BAREBOX_SYMS }
__usymtab_end = .;
+ .dtb : { BAREBOX_DTB() }
+
_edata = .;
. = ALIGN(4);
__bss_start = .;
diff --git a/arch/mips/mach-ar231x/Kconfig b/arch/mips/mach-ar231x/Kconfig
new file mode 100644
index 0000000000..1c6a12f885
--- /dev/null
+++ b/arch/mips/mach-ar231x/Kconfig
@@ -0,0 +1,17 @@
+if MACH_MIPS_AR231X
+
+config ARCH_TEXT_BASE
+ hex
+ default 0xa0800000
+
+choice
+ prompt "Board type"
+
+config BOARD_NETGEAR_WG102
+ bool "Netgear WG102"
+
+endchoice
+
+source arch/mips/boards/netgear-wg102/Kconfig
+
+endif
diff --git a/arch/mips/mach-ar231x/Makefile b/arch/mips/mach-ar231x/Makefile
new file mode 100644
index 0000000000..eba8e818b5
--- /dev/null
+++ b/arch/mips/mach-ar231x/Makefile
@@ -0,0 +1,3 @@
+obj-y += ar231x.o
+obj-y += board.o
+obj-y += ar231x_reset.o
diff --git a/arch/mips/mach-ar231x/ar231x.c b/arch/mips/mach-ar231x/ar231x.c
new file mode 100644
index 0000000000..ca912bf0ef
--- /dev/null
+++ b/arch/mips/mach-ar231x/ar231x.c
@@ -0,0 +1,195 @@
+/*
+ * Based on Linux driver:
+ * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
+ * Copyright (C) 2006 FON Technology, SL.
+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
+ * Ported to Barebox:
+ * Copyright (C) 2013 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <ns16550.h>
+#include <mach/ar231x_platform.h>
+#include <mach/ar2312_regs.h>
+
+struct ar231x_board_data ar231x_board;
+
+/*
+ * This table is indexed by bits 5..4 of the CLOCKCTL1 register
+ * to determine the predevisor value.
+ */
+static int CLOCKCTL1_PREDIVIDE_TABLE[4] = { 1, 2, 4, 5 };
+
+static unsigned int
+ar2312_cpu_frequency(void)
+{
+ unsigned int predivide_mask, predivide_shift;
+ unsigned int multiplier_mask, multiplier_shift;
+ unsigned int clock_ctl1, pre_divide_select, pre_divisor, multiplier;
+ unsigned int doubler_mask;
+ u32 devid;
+
+ devid = __raw_readl((char *)KSEG1ADDR(AR2312_REV));
+ devid &= AR2312_REV_MAJ;
+ devid >>= AR2312_REV_MAJ_S;
+ if (devid == AR2312_REV_MAJ_AR2313) {
+ predivide_mask = AR2313_CLOCKCTL1_PREDIVIDE_MASK;
+ predivide_shift = AR2313_CLOCKCTL1_PREDIVIDE_SHIFT;
+ multiplier_mask = AR2313_CLOCKCTL1_MULTIPLIER_MASK;
+ multiplier_shift = AR2313_CLOCKCTL1_MULTIPLIER_SHIFT;
+ doubler_mask = AR2313_CLOCKCTL1_DOUBLER_MASK;
+ } else { /* AR5312 and AR2312 */
+ predivide_mask = AR2312_CLOCKCTL1_PREDIVIDE_MASK;
+ predivide_shift = AR2312_CLOCKCTL1_PREDIVIDE_SHIFT;
+ multiplier_mask = AR2312_CLOCKCTL1_MULTIPLIER_MASK;
+ multiplier_shift = AR2312_CLOCKCTL1_MULTIPLIER_SHIFT;
+ doubler_mask = AR2312_CLOCKCTL1_DOUBLER_MASK;
+ }
+
+ /*
+ * Clocking is derived from a fixed 40MHz input clock.
+ *
+ * cpuFreq = InputClock * MULT (where MULT is PLL multiplier)
+ * sysFreq = cpuFreq / 4 (used for APB clock, serial,
+ * flash, Timer, Watchdog Timer)
+ *
+ * cntFreq = cpuFreq / 2 (use for CPU count/compare)
+ *
+ * So, for example, with a PLL multiplier of 5, we have
+ *
+ * cpuFreq = 200MHz
+ * sysFreq = 50MHz
+ * cntFreq = 100MHz
+ *
+ * We compute the CPU frequency, based on PLL settings.
+ */
+
+ clock_ctl1 = __raw_readl((char *)KSEG1ADDR(AR2312_CLOCKCTL1));
+ pre_divide_select = (clock_ctl1 & predivide_mask) >> predivide_shift;
+ pre_divisor = CLOCKCTL1_PREDIVIDE_TABLE[pre_divide_select];
+ multiplier = (clock_ctl1 & multiplier_mask) >> multiplier_shift;
+
+ if (clock_ctl1 & doubler_mask)
+ multiplier = multiplier << 1;
+
+ return (40000000 / pre_divisor) * multiplier;
+}
+
+static unsigned int
+ar2312_sys_frequency(void)
+{
+ return ar2312_cpu_frequency() / 4;
+}
+
+/*
+ * shutdown watchdog
+ */
+static int watchdog_init(void)
+{
+ pr_debug("Disable watchdog.\n");
+ __raw_writeb(AR2312_WD_CTRL_IGNORE_EXPIRATION,
+ (char *)KSEG1ADDR(AR2312_WD_CTRL));
+ return 0;
+}
+
+static void flash_init(void)
+{
+ u32 ctl, old_ctl;
+
+ /* Configure flash bank 0.
+ * Assume 8M maximum window size on this SoC.
+ * Flash will be aliased if it's smaller
+ */
+ old_ctl = __raw_readl((char *)KSEG1ADDR(AR2312_FLASHCTL0));
+ ctl = FLASHCTL_E | FLASHCTL_AC_8M | FLASHCTL_RBLE |
+ (0x01 << FLASHCTL_IDCY_S) |
+ (0x07 << FLASHCTL_WST1_S) |
+ (0x07 << FLASHCTL_WST2_S) | (old_ctl & FLASHCTL_MW);
+
+ __raw_writel(ctl, (char *)KSEG1ADDR(AR2312_FLASHCTL0));
+ /* Disable other flash banks */
+ old_ctl = __raw_readl((char *)KSEG1ADDR(AR2312_FLASHCTL1));
+ __raw_writel(old_ctl & ~(FLASHCTL_E | FLASHCTL_AC),
+ (char *)KSEG1ADDR(AR2312_FLASHCTL1));
+
+ old_ctl = __raw_readl((char *)KSEG1ADDR(AR2312_FLASHCTL2));
+ __raw_writel(old_ctl & ~(FLASHCTL_E | FLASHCTL_AC),
+ (char *)KSEG1ADDR(AR2312_FLASHCTL2));
+
+ /* We need to find atheros config. MAC address is there. */
+ ar231x_find_config((char *)KSEG1ADDR(AR2312_FLASH +
+ AR2312_MAX_FLASH_SIZE));
+}
+
+static int ether_init(void)
+{
+ static struct resource res[2];
+ struct ar231x_eth_platform_data *eth = &ar231x_board.eth_pdata;
+
+ /* Base ETH registers */
+ res[0].start = KSEG1ADDR(AR2312_ENET1);
+ res[0].end = res[0].start + 0x100000 - 1;
+ res[0].flags = IORESOURCE_MEM;
+ /* Base PHY registers */
+ res[1].start = KSEG1ADDR(AR2312_ENET0);
+ res[1].end = res[1].start + 0x100000 - 1;
+ res[1].flags = IORESOURCE_MEM;
+
+ /* MAC address located in atheros config on flash. */
+ eth->mac = ar231x_board.config->enet0_mac;
+
+ eth->reset_mac = AR2312_RESET_ENET0 | AR2312_RESET_ENET1;
+ eth->reset_phy = AR2312_RESET_EPHY0 | AR2312_RESET_EPHY1;
+
+ eth->reset_bit = ar231x_reset_bit;
+
+ /* FIXME: base_reset should be replaced with reset driver */
+ eth->base_reset = KSEG1ADDR(AR2312_RESET);
+
+ add_generic_device_res("ar231x_eth", DEVICE_ID_DYNAMIC, res, 2, eth);
+ return 0;
+}
+
+static int platform_init(void)
+{
+ add_generic_device("ar231x_reset", DEVICE_ID_SINGLE, NULL,
+ KSEG1ADDR(AR2312_RESET), 0x4,
+ IORESOURCE_MEM, NULL);
+ watchdog_init();
+ flash_init();
+ ether_init();
+ return 0;
+}
+late_initcall(platform_init);
+
+static struct NS16550_plat serial_plat = {
+ .shift = AR2312_UART_SHIFT,
+};
+
+static int ar2312_console_init(void)
+{
+ u32 reset;
+
+ /* reset UART0 */
+ reset = __raw_readl((char *)KSEG1ADDR(AR2312_RESET));
+ reset = ((reset & ~AR2312_RESET_APB) | AR2312_RESET_UART0);
+ __raw_writel(reset, (char *)KSEG1ADDR(AR2312_RESET));
+
+ reset &= ~AR2312_RESET_UART0;
+ __raw_writel(reset, (char *)KSEG1ADDR(AR2312_RESET));
+
+ /* Register the serial port */
+ serial_plat.clock = ar2312_sys_frequency();
+ add_ns16550_device(DEVICE_ID_DYNAMIC, KSEG1ADDR(AR2312_UART0),
+ 8 << AR2312_UART_SHIFT, IORESOURCE_MEM_8BIT, &serial_plat);
+ return 0;
+}
+console_initcall(ar2312_console_init);
diff --git a/arch/mips/mach-ar231x/ar231x_reset.c b/arch/mips/mach-ar231x/ar231x_reset.c
new file mode 100644
index 0000000000..5ececb5c01
--- /dev/null
+++ b/arch/mips/mach-ar231x/ar231x_reset.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2013 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+
+#include <mach/ar2312_regs.h>
+#include <mach/ar231x_platform.h>
+
+static void __iomem *reset_base;
+
+void __noreturn reset_cpu(ulong addr)
+{
+ printf("reseting cpu\n");
+ __raw_writel(0x10000,
+ (char *)KSEG1ADDR(AR2312_WD_TIMER));
+ __raw_writel(AR2312_WD_CTRL_RESET,
+ (char *)KSEG1ADDR(AR2312_WD_CTRL));
+ unreachable();
+}
+EXPORT_SYMBOL(reset_cpu);
+
+static u32 ar231x_reset_readl(void)
+{
+ return __raw_readl(reset_base);
+}
+
+static void ar231x_reset_writel(u32 val)
+{
+ __raw_writel(val, reset_base);
+}
+
+void ar231x_reset_bit(u32 val, enum reset_state state)
+{
+ u32 tmp;
+
+ tmp = ar231x_reset_readl();
+
+ if (state == REMOVE)
+ ar231x_reset_writel(tmp & ~val);
+ else
+ ar231x_reset_writel(tmp | val);
+}
+EXPORT_SYMBOL(ar231x_reset_bit);
+
+static int ar231x_reset_probe(struct device_d *dev)
+{
+ reset_base = dev_request_mem_region(dev, 0);
+ if (!reset_base) {
+ dev_err(dev, "could not get memory region\n");
+ return -ENODEV;
+ }
+
+ return 0;
+}
+
+static struct driver_d ar231x_reset_driver = {
+ .probe = ar231x_reset_probe,
+ .name = "ar231x_reset",
+};
+
+static int ar231x_reset_init(void)
+{
+ return platform_driver_register(&ar231x_reset_driver);
+}
+coredevice_initcall(ar231x_reset_init);
diff --git a/arch/mips/mach-ar231x/board.c b/arch/mips/mach-ar231x/board.c
new file mode 100644
index 0000000000..f1b876f762
--- /dev/null
+++ b/arch/mips/mach-ar231x/board.c
@@ -0,0 +1,188 @@
+/*
+ * Based on Linux driver:
+ * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
+ * Copyright (C) 2006 FON Technology, SL.
+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
+ * Ported to Barebox:
+ * Copyright (C) 2013 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * 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.
+ */
+
+
+#include <common.h>
+#include <io.h>
+#include <mach/ar2312_regs.h>
+#include <mach/ar231x_platform.h>
+#include <linux/stddef.h>
+#include <net.h>
+
+#define HDR_SIZE 6
+
+#define TAB_1 "\t"
+#define TAB_2 "\t\t"
+
+extern struct ar231x_board_data ar231x_board;
+
+static void
+ar231x_print_mac(unsigned char *mac)
+{
+ int i;
+ for (i = 0; i < 5; i++)
+ printf("%02x:", mac[i]);
+ printf("%02x\n", mac[5]);
+}
+
+#ifdef DEBUG_BOARD
+static void
+ar231x_print_board_config(struct ar231x_board_config *config)
+{
+ printf("board config:\n");
+ printf(TAB_1 "chsum:" TAB_2 "%04x\n", config->cksum);
+ printf(TAB_1 "rev:" TAB_2 "%04x\n", config->rev);
+ printf(TAB_1 "name:" TAB_2 "%s\n", config->board_name);
+ printf(TAB_1 "maj:" TAB_2 "%04x\n", config->major);
+ printf(TAB_1 "min:" TAB_2 "%04x\n", config->minor);
+ printf(TAB_1 "board flags:" TAB_1 "%08x\n", config->flags);
+
+ if (config->flags & BD_ENET0)
+ printf(TAB_2 "ENET0 is stuffed\n");
+ if (config->flags & BD_ENET1)
+ printf(TAB_2 "ENET1 is stuffed\n");
+ if (config->flags & BD_UART1)
+ printf(TAB_2 "UART1 is stuffed\n");
+ if (config->flags & BD_UART0)
+ printf(TAB_2 "UART0 is stuffed (dma)\n");
+ if (config->flags & BD_RSTFACTORY)
+ printf(TAB_2 "Reset factory defaults stuffed\n");
+ if (config->flags & BD_SYSLED)
+ printf(TAB_2 "System LED stuffed\n");
+ if (config->flags & BD_EXTUARTCLK)
+ printf(TAB_2 "External UART clock\n");
+ if (config->flags & BD_CPUFREQ)
+ printf(TAB_2 "cpu freq is valid in nvram\n");
+ if (config->flags & BD_SYSFREQ)
+ printf(TAB_2 "sys freq is set in nvram\n");
+ if (config->flags & BD_WLAN0)
+ printf(TAB_2 "Enable WLAN0\n");
+ if (config->flags & BD_MEMCAP)
+ printf(TAB_2 "CAP SDRAM @ memCap for testing\n");
+ if (config->flags & BD_DISWATCHDOG)
+ printf(TAB_2 "disable system watchdog\n");
+ if (config->flags & BD_WLAN1)
+ printf(TAB_2 "Enable WLAN1 (ar5212)\n");
+ if (config->flags & BD_ISCASPER)
+ printf(TAB_2 "FLAG for AR2312\n");
+ if (config->flags & BD_WLAN0_2G_EN)
+ printf(TAB_2 "FLAG for radio0_2G\n");
+ if (config->flags & BD_WLAN0_5G_EN)
+ printf(TAB_2 "FLAG for radio0_5G\n");
+ if (config->flags & BD_WLAN1_2G_EN)
+ printf(TAB_2 "FLAG for radio1_2G\n");
+ if (config->flags & BD_WLAN1_5G_EN)
+ printf(TAB_2 "FLAG for radio1_5G\n");
+
+ printf(TAB_1 "ResetConf GPIO pin:" TAB_1 "%04x\n",
+ config->reset_config_gpio);
+ printf(TAB_1 "Sys LED GPIO pin:" TAB_1 "%04x\n", config->sys_led_gpio);
+ printf(TAB_1 "CPU Freq:" TAB_2 "%u\n", config->cpu_freq);
+ printf(TAB_1 "Sys Freq:" TAB_2 "%u\n", config->sys_freq);
+ printf(TAB_1 "Calculated Freq:" TAB_1 "%u\n", config->cnt_freq);
+
+ printf(TAB_1 "wlan0 mac:" TAB_2);
+ ar231x_print_mac(config->wlan0_mac);
+ printf(TAB_1 "wlan1 mac:" TAB_2);
+ ar231x_print_mac(config->wlan1_mac);
+ printf(TAB_1 "eth0 mac:" TAB_2);
+ ar231x_print_mac(config->enet0_mac);
+ printf(TAB_1 "eth1 mac:" TAB_2);
+ ar231x_print_mac(config->enet1_mac);
+
+ printf(TAB_1 "Pseudo PCIID:" TAB_2 "%04x\n", config->pci_id);
+ printf(TAB_1 "Mem capacity:" TAB_2 "%u\n", config->mem_cap);
+}
+#endif
+
+static u16
+ar231x_cksum16(u8 *data, int size)
+{
+ int i;
+ u16 sum;
+
+ for (i = 0; i < size; i++)
+ sum += data[i];
+
+ return sum;
+}
+
+static void
+ar231x_check_mac(u8 *addr)
+{
+ if (!is_valid_ether_addr(addr)) {
+ pr_warn("config: no valid mac was found. "
+ "Generating random mac: ");
+ random_ether_addr(addr);
+ ar231x_print_mac(addr);
+ }
+}
+
+static u8 *
+ar231x_find_board_config(u8 *flash_limit)
+{
+ u8 *addr;
+ int found = 0;
+
+ for (addr = flash_limit - 0x1000;
+ addr >= flash_limit - 0x30000;
+ addr -= 0x1000) {
+
+ if (*((u32 *)addr) == AR231X_BD_MAGIC) {
+ found = 1;
+ pr_debug("config at %x\n", addr);
+ break;
+ }
+ }
+
+ if (!found)
+ addr = NULL;
+
+ return addr;
+}
+
+void
+ar231x_find_config(u8 *flash_limit)
+{
+ struct ar231x_board_config *config;
+ u8 *bcfg, bsize;
+ u8 brocken;
+
+ bcfg = ar231x_find_board_config(flash_limit);
+
+ bsize = sizeof(struct ar231x_board_config);
+ config = xzalloc(bsize);
+ ar231x_board.config = config;
+
+ if (bcfg) {
+ u16 cksum;
+ /* Copy the board and radio data to RAM.
+ * If flash will go to CFI mode, we won't
+ * be able to read to from mapped memory area */
+ memcpy(config, bcfg, bsize);
+ cksum = 0xca + ar231x_cksum16((unsigned char *)config + HDR_SIZE,
+ sizeof(struct ar231x_board_config) - HDR_SIZE);
+ if (cksum != config->cksum) {
+ pr_err("config: checksum is invalid: %04x != %04x\n",
+ cksum, config->cksum);
+ brocken = 1;
+ }
+ /* ar231x_print_board_config(config); */
+ }
+
+ /* We do not care about wlans here */
+ ar231x_check_mac(config->enet0_mac);
+ ar231x_check_mac(config->enet1_mac);
+}
diff --git a/arch/mips/mach-ar231x/include/mach/ar2312_regs.h b/arch/mips/mach-ar231x/include/mach/ar2312_regs.h
new file mode 100644
index 0000000000..7ac1b09b9a
--- /dev/null
+++ b/arch/mips/mach-ar231x/include/mach/ar2312_regs.h
@@ -0,0 +1,302 @@
+/*
+ * Based on Linux driver:
+ * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
+ * Ported to Barebox:
+ * Copyright (C) 2013 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * 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.
+ */
+
+#ifndef AR2312_H
+#define AR2312_H
+
+#include <asm/addrspace.h>
+
+/* Address Map */
+#define AR2312_SDRAM0 0x00000000
+#define AR2312_SDRAM1 0x08000000
+#define AR2312_WLAN0 0x18000000
+#define AR2312_WLAN1 0x18500000
+#define AR2312_ENET0 0x18100000
+#define AR2312_ENET1 0x18200000
+#define AR2312_SDRAMCTL 0x18300000
+#define AR2312_FLASHCTL 0x18400000
+#define AR2312_APBBASE 0x1c000000
+#define AR2312_FLASH 0x1e000000
+
+#define AR2312_CPU_CLOCK_RATE 180000000
+/* Used by romSizeMemory to set SDRAM Memory Refresh */
+#define AR2312_SDRAM_CLOCK_RATE (AR2312_CPU_CLOCK_RATE / 2)
+/*
+ * SDRAM Memory Refresh (MEM_REF) value is computed as:
+ * 15.625us * SDRAM_CLOCK_RATE (in MHZ)
+ */
+#define DESIRED_MEMORY_REFRESH_NSECS 15625
+#define AR2312_SDRAM_MEMORY_REFRESH_VALUE \
+ ((DESIRED_MEMORY_REFRESH_NSECS * AR2312_SDRAM_CLOCK_RATE/1000000) / 1000)
+
+/*
+ * APB Address Map
+ */
+#define AR2312_UART0 (AR2312_APBBASE + 0x0003) /* high speed uart */
+#define AR2312_UART_SHIFT 2
+#define AR2312_UART1 (AR2312_APBBASE + 0x1000) /* ar2312 only */
+#define AR2312_GPIO (AR2312_APBBASE + 0x2000)
+#define AR2312_RESETTMR (AR2312_APBBASE + 0x3000)
+#define AR2312_APB2AHB (AR2312_APBBASE + 0x4000)
+
+/*
+ * AR2312_NUM_ENET_MAC defines the number of ethernet MACs that
+ * should be considered available. The AR2312 supports 2 enet MACS,
+ * even though many reference boards only actually use 1 of them
+ * (i.e. Only MAC 0 is actually connected to an enet PHY or PHY switch.
+ * The AR2312 supports 1 enet MAC.
+ */
+#define AR2312_NUM_ENET_MAC 2
+
+/*
+ * Need these defines to determine true number of ethernet MACs
+ */
+#define AR5212_AR2312_REV2 0x52 /* AR2312 WMAC (AP31) */
+#define AR5212_AR2312_REV7 0x57 /* AR2312 WMAC (AP30-040) */
+#define AR5212_AR2313_REV8 0x58 /* AR2313 WMAC (AP43-030) */
+
+/* Reset/Timer Block Address Map */
+#define AR2312_RESETTMR (AR2312_APBBASE + 0x3000)
+#define AR2312_TIMER (AR2312_RESETTMR + 0x0000) /* countdown timer */
+#define AR2312_WD_CTRL (AR2312_RESETTMR + 0x0008) /* watchdog cntrl */
+#define AR2312_WD_TIMER (AR2312_RESETTMR + 0x000c) /* watchdog timer */
+#define AR2312_ISR (AR2312_RESETTMR + 0x0010) /* Intr Status Reg */
+#define AR2312_IMR (AR2312_RESETTMR + 0x0014) /* Intr Mask Reg */
+#define AR2312_RESET (AR2312_RESETTMR + 0x0020)
+#define AR2312_CLOCKCTL0 (AR2312_RESETTMR + 0x0060)
+#define AR2312_CLOCKCTL1 (AR2312_RESETTMR + 0x0064)
+#define AR2312_CLOCKCTL2 (AR2312_RESETTMR + 0x0068)
+#define AR2312_SCRATCH (AR2312_RESETTMR + 0x006c)
+#define AR2312_PROCADDR (AR2312_RESETTMR + 0x0070)
+#define AR2312_PROC1 (AR2312_RESETTMR + 0x0074)
+#define AR2312_DMAADDR (AR2312_RESETTMR + 0x0078)
+#define AR2312_DMA1 (AR2312_RESETTMR + 0x007c)
+#define AR2312_ENABLE (AR2312_RESETTMR + 0x0080) /* interface enb */
+#define AR2312_REV (AR2312_RESETTMR + 0x0090) /* revision */
+
+/* AR2312_WD_CTRL register bit field definitions */
+#define AR2312_WD_CTRL_IGNORE_EXPIRATION 0x0000
+#define AR2312_WD_CTRL_NMI 0x0001
+#define AR2312_WD_CTRL_RESET 0x0002
+
+/* AR2312_ISR register bit field definitions */
+#define AR2312_ISR_NONE 0x0000
+#define AR2312_ISR_TIMER 0x0001
+#define AR2312_ISR_AHBPROC 0x0002
+#define AR2312_ISR_AHBDMA 0x0004
+#define AR2312_ISR_GPIO 0x0008
+#define AR2312_ISR_UART0 0x0010
+#define AR2312_ISR_UART0DMA 0x0020
+#define AR2312_ISR_WD 0x0040
+#define AR2312_ISR_LOCAL 0x0080
+
+/* AR2312_RESET register bit field definitions */
+#define AR2312_RESET_SYSTEM 0x00000001 /* cold reset full system */
+#define AR2312_RESET_PROC 0x00000002 /* cold reset MIPS core */
+#define AR2312_RESET_WLAN0 0x00000004 /* cold reset WLAN MAC and BB */
+#define AR2312_RESET_EPHY0 0x00000008 /* cold reset ENET0 phy */
+#define AR2312_RESET_EPHY1 0x00000010 /* cold reset ENET1 phy */
+#define AR2312_RESET_ENET0 0x00000020 /* cold reset ENET0 mac */
+#define AR2312_RESET_ENET1 0x00000040 /* cold reset ENET1 mac */
+#define AR2312_RESET_UART0 0x00000100 /* cold reset UART0 (high speed) */
+#define AR2312_RESET_WLAN1 0x00000200 /* cold reset WLAN MAC/BB */
+#define AR2312_RESET_APB 0x00000400 /* cold reset APB (ar2312) */
+#define AR2312_RESET_WARM_PROC 0x00001000 /* warm reset MIPS core */
+#define AR2312_RESET_WARM_WLAN0_MAC 0x00002000 /* warm reset WLAN0 MAC */
+#define AR2312_RESET_WARM_WLAN0_BB 0x00004000 /* warm reset WLAN0 BaseBand */
+#define AR2312_RESET_NMI 0x00010000 /* send an NMI to the processor */
+#define AR2312_RESET_WARM_WLAN1_MAC 0x00020000 /* warm reset WLAN1 mac */
+#define AR2312_RESET_WARM_WLAN1_BB 0x00040000 /* warm reset WLAN1 baseband */
+#define AR2312_RESET_LOCAL_BUS 0x00080000 /* reset local bus */
+#define AR2312_RESET_WDOG 0x00100000 /* last reset was a watchdog */
+
+/* Values for AR2312_CLOCKCTL1
+ *
+ * The AR2312_CLOCKCTL1 register is loaded based on the speed of
+ * our incoming clock. Currently, all valid configurations
+ * for an AR2312 use an ar5112 radio clocked at 40MHz. Until
+ * there are other configurations available, we'll hardcode
+ * this 40MHz assumption.
+ */
+#define AR2312_INPUT_CLOCK 40000000
+#define AR2312_CLOCKCTL1_IN40_OUT160MHZ 0x0405 /* 40MHz in, 160Mhz out */
+#define AR2312_CLOCKCTL1_IN40_OUT180MHZ 0x0915 /* 40MHz in, 180Mhz out */
+#define AR2312_CLOCKCTL1_IN40_OUT200MHZ 0x1935 /* 40MHz in, 200Mhz out */
+#define AR2312_CLOCKCTL1_IN40_OUT220MHZ 0x0b15 /* 40MHz in, 220Mhz out */
+#define AR2312_CLOCKCTL1_IN40_OUT240MHZ 0x0605 /* 40MHz in, 240Mhz out */
+
+#define AR2312_CLOCKCTL1_SELECTION AR2312_CLOCKCTL1_IN40_OUT180MHZ
+#define AR2312_CPU_CLOCK_RATE 180000000
+
+/*
+ * Special values for AR2313 'VIPER' PLL.
+ *
+ * These values do not match the latest datasheet for the AR2313,
+ * which appears to be an exact copy of the AR2312 in this area.
+ * The values were derived from the ECOS code provided in the Atheros
+ * LSDK-1.0 (and confirmed by checking values on an AR2313 reference
+ * design).
+ */
+#define AR2313_CLOCKCTL1_SELECTION 0x91245
+
+/* Bit fields for AR2312_CLOCKCTL2 */
+#define AR2312_CLOCKCTL2_WANT_RESET 0x00000001 /* reset with new vals */
+#define AR2312_CLOCKCTL2_WANT_DIV2 0x00000010 /* request /2 clock */
+#define AR2312_CLOCKCTL2_WANT_DIV4 0x00000020 /* request /4 clock */
+#define AR2312_CLOCKCTL2_WANT_PLL_BYPASS 0x00000080 /* request PLL bypass */
+#define AR2312_CLOCKCTL2_STATUS_DIV2 0x10000000 /* have /2 clock */
+#define AR2312_CLOCKCTL2_STATUS_DIV4 0x20000000 /* have /4 clock */
+#define AR2312_CLOCKCTL2_STATUS_PLL_BYPASS 0x80000000 /* PLL is bypassed */
+
+/* AR2312_CLOCKCTL1 register bit field definitions */
+#define AR2312_CLOCKCTL1_PREDIVIDE_MASK 0x00000030
+#define AR2312_CLOCKCTL1_PREDIVIDE_SHIFT 4
+#define AR2312_CLOCKCTL1_MULTIPLIER_MASK 0x00001f00
+#define AR2312_CLOCKCTL1_MULTIPLIER_SHIFT 8
+#define AR2312_CLOCKCTL1_DOUBLER_MASK 0x00010000
+
+/* Valid for AR2313 */
+#define AR2313_CLOCKCTL1_PREDIVIDE_MASK 0x00003000
+#define AR2313_CLOCKCTL1_PREDIVIDE_SHIFT 12
+#define AR2313_CLOCKCTL1_MULTIPLIER_MASK 0x001f0000
+#define AR2313_CLOCKCTL1_MULTIPLIER_SHIFT 16
+#define AR2313_CLOCKCTL1_DOUBLER_MASK 0x00000000
+
+/* Values for AR2312_CLOCKCTL */
+#define AR2312_CLOCKCTL_ETH0 0x0004 /* enable eth0 clock */
+#define AR2312_CLOCKCTL_ETH1 0x0008 /* enable eth1 clock */
+#define AR2312_CLOCKCTL_UART0 0x0010 /* enable UART0 external clock */
+
+
+/* AR2312_ENABLE register bit field definitions */
+#define AR2312_ENABLE_ENET0 0x0002
+#define AR2312_ENABLE_ENET1 0x0004
+
+/* AR2312_REV register bit field definitions */
+#define AR2312_REV_WMAC_MAJ 0xf000
+#define AR2312_REV_WMAC_MAJ_S 12
+#define AR2312_REV_WMAC_MIN 0x0f00
+#define AR2312_REV_WMAC_MIN_S 8
+#define AR2312_REV_MAJ 0x00f0
+#define AR2312_REV_MAJ_S 4
+#define AR2312_REV_MIN 0x000f
+#define AR2312_REV_MIN_S 0
+#define AR2312_REV_CHIP (AR2312_REV_MAJ|AR2312_REV_MIN)
+
+/* Major revision numbers, bits 7..4 of Revision ID register */
+#define AR2312_REV_MAJ_AR2312 0x4
+#define AR2312_REV_MAJ_AR2313 0x5
+
+/* Minor revision numbers, bits 3..0 of Revision ID register */
+#define AR2312_REV_MIN_DUAL 0x0 /* Dual WLAN version */
+#define AR2312_REV_MIN_SINGLE 0x1 /* Single WLAN version */
+
+/* AR2312_FLASHCTL register bit field definitions */
+#define FLASHCTL_IDCY 0x0000000f /* Idle cycle turn around time */
+#define FLASHCTL_IDCY_S 0
+#define FLASHCTL_WST1 0x000003e0 /* Wait state 1 */
+#define FLASHCTL_WST1_S 5
+#define FLASHCTL_RBLE 0x00000400 /* Read byte lane enable */
+#define FLASHCTL_WST2 0x0000f800 /* Wait state 2 */
+#define FLASHCTL_WST2_S 11
+#define FLASHCTL_AC 0x00070000 /* Flash address check (added) */
+#define FLASHCTL_AC_S 16
+#define FLASHCTL_AC_128K 0x00000000
+#define FLASHCTL_AC_256K 0x00010000
+#define FLASHCTL_AC_512K 0x00020000
+#define FLASHCTL_AC_1M 0x00030000
+#define FLASHCTL_AC_2M 0x00040000
+#define FLASHCTL_AC_4M 0x00050000
+#define FLASHCTL_AC_8M 0x00060000
+#define FLASHCTL_AC_RES 0x00070000 /* 16MB is not supported */
+#define FLASHCTL_E 0x00080000 /* Flash bank enable (added) */
+#define FLASHCTL_BUSERR 0x01000000 /* Bus transfer error status flag */
+#define FLASHCTL_WPERR 0x02000000 /* Write protect error status flag */
+#define FLASHCTL_WP 0x04000000 /* Write protect */
+#define FLASHCTL_BM 0x08000000 /* Burst mode */
+#define FLASHCTL_MW 0x30000000 /* Memory width */
+#define FLASHCTL_MWx8 0x00000000 /* Memory width x8 */
+#define FLASHCTL_MWx16 0x10000000 /* Memory width x16 */
+#define FLASHCTL_MWx32 0x20000000 /* Memory width x32 (not supported) */
+#define FLASHCTL_ATNR 0x00000000 /* Access type == no retry */
+#define FLASHCTL_ATR 0x80000000 /* Access type == retry every */
+#define FLASHCTL_ATR4 0xc0000000 /* Access type == retry every 4 */
+
+#define AR2312_MAX_FLASH_SIZE 0x800000
+
+/* ARM Flash Controller -- 3 flash banks with either x8 or x16 devices. */
+#define AR2312_FLASHCTL0 (AR2312_FLASHCTL + 0x00)
+#define AR2312_FLASHCTL1 (AR2312_FLASHCTL + 0x04)
+#define AR2312_FLASHCTL2 (AR2312_FLASHCTL + 0x08)
+
+/* ARM SDRAM Controller -- just enough to determine memory size */
+#define AR2312_MEM_CFG0 (AR2312_SDRAMCTL + 0x00)
+#define AR2312_MEM_CFG1 (AR2312_SDRAMCTL + 0x04)
+#define AR2312_MEM_REF (AR2312_SDRAMCTL + 0x08) /* 16 bit value */
+
+#define MEM_CFG0_F0 0x00000002 /* bank 0: 256Mb support */
+#define MEM_CFG0_T0 0x00000004 /* bank 0: chip width */
+#define MEM_CFG0_B0 0x00000008 /* bank 0: 2 vs 4 bank */
+#define MEM_CFG0_F1 0x00000020 /* bank 1: 256Mb support */
+#define MEM_CFG0_T1 0x00000040 /* bank 1: chip width */
+#define MEM_CFG0_B1 0x00000080 /* bank 1: 2 vs 4 bank */
+ /* bank 2 and 3 are not supported */
+#define MEM_CFG0_E 0x00020000 /* SDRAM clock control */
+#define MEM_CFG0_C 0x00040000 /* SDRAM clock enable */
+#define MEM_CFG0_X 0x00080000 /* bus width (0 == 32b) */
+#define MEM_CFG0_CAS 0x00300000 /* CAS latency (1-3) */
+#define MEM_CFG0_C1 0x00100000
+#define MEM_CFG0_C2 0x00200000
+#define MEM_CFG0_C3 0x00300000
+#define MEM_CFG0_R 0x00c00000 /* RAS to CAS latency (1-3) */
+#define MEM_CFG0_R1 0x00400000
+#define MEM_CFG0_R2 0x00800000
+#define MEM_CFG0_R3 0x00c00000
+#define MEM_CFG0_A 0x01000000 /* AHB auto pre-charge */
+
+#define MEM_CFG1_I 0x0001 /* memory init control */
+#define MEM_CFG1_M 0x0002 /* memory init control */
+#define MEM_CFG1_R 0x0004 /* read buffer enable (unused) */
+#define MEM_CFG1_W 0x0008 /* write buffer enable (unused) */
+#define MEM_CFG1_B 0x0010 /* SDRAM engine busy */
+#define MEM_CFG1_AC_2 0 /* AC of 2MB */
+#define MEM_CFG1_AC_4 1 /* AC of 4MB */
+#define MEM_CFG1_AC_8 2 /* AC of 8MB */
+#define MEM_CFG1_AC_16 3 /* AC of 16MB */
+#define MEM_CFG1_AC_32 4 /* AC of 32MB */
+#define MEM_CFG1_AC_64 5 /* AC of 64MB */
+#define MEM_CFG1_AC_128 6 /* AC of 128MB */
+
+#define MEM_CFG1_AC0_S 8
+#define MEM_CFG1_AC0 0x0700 /* bank 0: SDRAM addr check (added) */
+#define MEM_CFG1_E0 0x0800 /* bank 0: enable */
+#define MEM_CFG1_AC1_S 12
+#define MEM_CFG1_AC1 0x7000 /* bank 1: SDRAM addr check (added) */
+#define MEM_CFG1_E1 0x8000 /* bank 1: enable */
+
+/* GPIO Address Map */
+#define AR2312_GPIO (AR2312_APBBASE + 0x2000)
+#define AR2312_GPIO_DO (AR2312_GPIO + 0x00) /* output register */
+#define AR2312_GPIO_DI (AR2312_GPIO + 0x04) /* intput register */
+#define AR2312_GPIO_CR (AR2312_GPIO + 0x08) /* control register */
+
+/* GPIO Control Register bit field definitions */
+#define AR2312_GPIO_CR_M(x) (1 << (x)) /* mask for i/o */
+#define AR2312_GPIO_CR_O(x) (0 << (x)) /* mask for output */
+#define AR2312_GPIO_CR_I(x) (1 << (x)) /* mask for input */
+#define AR2312_GPIO_CR_INT(x) (1 << ((x)+8)) /* mask for interrupt */
+#define AR2312_GPIO_CR_UART(x) (1 << ((x)+16)) /* uart multiplex */
+#define AR2312_NUM_GPIO 8
+
+#endif
diff --git a/arch/mips/mach-ar231x/include/mach/ar231x_platform.h b/arch/mips/mach-ar231x/include/mach/ar231x_platform.h
new file mode 100644
index 0000000000..18f55b69c7
--- /dev/null
+++ b/arch/mips/mach-ar231x/include/mach/ar231x_platform.h
@@ -0,0 +1,104 @@
+/*
+ * Based on Linux driver:
+ * Copyright (C) 2003 Atheros Communications, Inc., All Rights Reserved.
+ * Copyright (C) 2006 FON Technology, SL.
+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
+ * Ported to Barebox:
+ * Copyright (C) 2013 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * 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.
+ */
+
+#ifndef __AR231X_PLATFORM_H
+#define __AR231X_PLATFORM_H
+
+/*
+ * This is board-specific data that is stored in a "fixed" location in flash.
+ * It is shared across operating systems, so it should not be changed lightly.
+ * The main reason we need it is in order to extract the ethernet MAC
+ * address(es).
+ */
+struct ar231x_board_config {
+ u32 magic; /* board data is valid */
+#define AR231X_BD_MAGIC 0x35333131 /* "5311", for all 531x platforms */
+ u16 cksum; /* checksum (starting with BD_REV 2) */
+ u16 rev; /* revision of this struct */
+#define BD_REV 4
+ char boardName[64]; /* Name of board */
+ u16 major; /* Board major number */
+ u16 minor; /* Board minor number */
+ u32 flags; /* Board configuration */
+#define BD_ENET0 0x00000001 /* ENET0 is stuffed */
+#define BD_ENET1 0x00000002 /* ENET1 is stuffed */
+#define BD_UART1 0x00000004 /* UART1 is stuffed */
+#define BD_UART0 0x00000008 /* UART0 is stuffed (dma) */
+#define BD_RSTFACTORY 0x00000010 /* Reset factory defaults stuffed */
+#define BD_SYSLED 0x00000020 /* System LED stuffed */
+#define BD_EXTUARTCLK 0x00000040 /* External UART clock */
+#define BD_CPUFREQ 0x00000080 /* cpu freq is valid in nvram */
+#define BD_SYSFREQ 0x00000100 /* sys freq is set in nvram */
+#define BD_WLAN0 0x00000200 /* Enable WLAN0 */
+#define BD_MEMCAP 0x00000400 /* CAP SDRAM @ memCap for testing */
+#define BD_DISWATCHDOG 0x00000800 /* disable system watchdog */
+#define BD_WLAN1 0x00001000 /* Enable WLAN1 (ar5212) */
+#define BD_ISCASPER 0x00002000 /* FLAG for AR2312 */
+#define BD_WLAN0_2G_EN 0x00004000 /* FLAG for radio0_2G */
+#define BD_WLAN0_5G_EN 0x00008000 /* FLAG for radio0_2G */
+#define BD_WLAN1_2G_EN 0x00020000 /* FLAG for radio0_2G */
+#define BD_WLAN1_5G_EN 0x00040000 /* FLAG for radio0_2G */
+ u16 resetConfigGpio; /* Reset factory GPIO pin */
+ u16 sysLedGpio; /* System LED GPIO pin */
+
+ u32 cpuFreq; /* CPU core frequency in Hz */
+ u32 sysFreq; /* System frequency in Hz */
+ u32 cntFreq; /* Calculated C0_COUNT frequency */
+
+ u8 wlan0_mac[6];
+ u8 enet0_mac[6];
+ u8 enet1_mac[6];
+
+ u16 pciId; /* Pseudo PCIID for common code */
+ u16 memCap; /* cap bank1 in MB */
+
+ /* version 3 */
+ u8 wlan1_mac[6]; /* (ar5212) */
+};
+
+#define BOARD_CONFIG_BUFSZ 0x1000
+
+/*
+ * Platform device information for the Ethernet MAC
+ */
+enum reset_state {
+ SET,
+ REMOVE,
+};
+
+struct ar231x_eth_platform_data {
+ u32 base_reset;
+ u32 reset_mac;
+ u32 reset_phy;
+
+ u8 *mac;
+
+ void (*reset_bit)(u32 val, enum reset_state state);
+};
+
+struct ar231x_board_data {
+ u16 devid;
+
+ /* board config data */
+ struct ar231x_board_config *config;
+
+ struct ar231x_eth_platform_data eth_pdata;
+};
+
+void ar231x_find_config(u8 *flash_limit);
+
+void ar231x_reset_bit(u32 val, enum reset_state state);
+
+#endif /* __AR231X_PLATFORM_H */
diff --git a/arch/mips/mach-xburst/Kconfig b/arch/mips/mach-xburst/Kconfig
index c72b7414d5..e6413d5637 100644
--- a/arch/mips/mach-xburst/Kconfig
+++ b/arch/mips/mach-xburst/Kconfig
@@ -17,6 +17,24 @@ config BOARD_RZX50
endchoice
+if DEBUG_LL
+if CPU_JZ4755
+choice
+ prompt "DEBUG_LL port"
+
+config JZ4750D_DEBUG_LL_UART0
+ bool "UART0"
+
+config JZ4750D_DEBUG_LL_UART1
+ bool "UART1"
+
+config JZ4750D_DEBUG_LL_UART2
+ bool "UART2"
+
+endchoice
+endif # CPU_JZ4755
+endif # DEBUG_LL
+
source arch/mips/boards/rzx50/Kconfig
endif
diff --git a/arch/mips/mach-xburst/Makefile b/arch/mips/mach-xburst/Makefile
index e5634ba9cc..3e0cd7324e 100644
--- a/arch/mips/mach-xburst/Makefile
+++ b/arch/mips/mach-xburst/Makefile
@@ -1 +1,2 @@
+obj-y += serial.o
obj-$(CONFIG_CPU_JZ4755) += csrc-jz4750.o reset-jz4750.o
diff --git a/arch/mips/mach-xburst/include/mach/debug_ll_jz4750d.h b/arch/mips/mach-xburst/include/mach/debug_ll_jz4750d.h
new file mode 100644
index 0000000000..7bf66b12ae
--- /dev/null
+++ b/arch/mips/mach-xburst/include/mach/debug_ll_jz4750d.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2013 Antony Pavlov <antonynpavlov@gmail.com>
+ *
+ * This file is part of barebox.
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+
+#ifndef __INCLUDE_DEBUG_LL_JZ4750D_H__
+#define __INCLUDE_DEBUG_LL_JZ4750D_H__
+
+#include <mach/jz4750d_regs.h>
+
+#ifdef CONFIG_JZ4750D_DEBUG_LL_UART0
+#define DEBUG_LL_UART_ADDR UART0_BASE
+#endif
+
+#ifdef CONFIG_JZ4750D_DEBUG_LL_UART1
+#define DEBUG_LL_UART_ADDR UART1_BASE
+#endif
+
+#ifdef CONFIG_JZ4750D_DEBUG_LL_UART2
+#define DEBUG_LL_UART_ADDR UART2_BASE
+#endif
+
+#define DEBUG_LL_UART_SHIFT 2
+
+#endif /* __INCLUDE_DEBUG_LL_JZ4750D_H__ */
diff --git a/arch/mips/mach-xburst/include/mach/devices.h b/arch/mips/mach-xburst/include/mach/devices.h
new file mode 100644
index 0000000000..931749d424
--- /dev/null
+++ b/arch/mips/mach-xburst/include/mach/devices.h
@@ -0,0 +1,8 @@
+#ifndef __MACH_XBURST_DEVICES_H
+#define __MACH_XBURST_DEVICES_H
+
+#include <driver.h>
+
+struct device_d *jz_add_uart(int id, unsigned long base, unsigned int clock);
+
+#endif /* __MACH_XBURST_DEVICES_H */
diff --git a/arch/mips/mach-xburst/include/mach/jz4750d_regs.h b/arch/mips/mach-xburst/include/mach/jz4750d_regs.h
index eafdd2fa79..7a3daadb18 100644
--- a/arch/mips/mach-xburst/include/mach/jz4750d_regs.h
+++ b/arch/mips/mach-xburst/include/mach/jz4750d_regs.h
@@ -16,7 +16,9 @@
#define TCU_BASE 0xb0002000
#define WDT_BASE 0xb0002000
#define RTC_BASE 0xb0003000
+#define UART0_BASE 0xb0030000
#define UART1_BASE 0xb0031000
+#define UART2_BASE 0xb0032000
/*************************************************************************
* TCU (Timer Counter Unit)
diff --git a/arch/mips/mach-xburst/serial.c b/arch/mips/mach-xburst/serial.c
new file mode 100644
index 0000000000..acf5648467
--- /dev/null
+++ b/arch/mips/mach-xburst/serial.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2013 Antony Pavlov <antonynpavlov@gmail.com>
+ *
+ * Based on the linux kernel JZ4740 serial support:
+ * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
+ *
+ * This file is part of barebox.
+ * See file CREDITS for list of people who contributed to this project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+
+#include <common.h>
+#include <ns16550.h>
+#include <io.h>
+#include <mach/devices.h>
+
+#define JZ_UART_SHIFT 2
+
+#define ier (1 << JZ_UART_SHIFT)
+#define fcr (2 << JZ_UART_SHIFT)
+
+static void jz_serial_reg_write(unsigned int val, unsigned long base,
+ unsigned char reg_offset)
+{
+ switch (reg_offset) {
+ case fcr:
+ val |= 0x10; /* Enable uart module */
+ break;
+ case ier:
+ val |= (val & 0x4) << 2;
+ break;
+ default:
+ break;
+ }
+
+ writeb(val & 0xff, (void *)(base + reg_offset));
+}
+
+struct device_d *jz_add_uart(int id, unsigned long base, unsigned int clock)
+{
+ struct NS16550_plat *serial_plat;
+
+ serial_plat = xzalloc(sizeof(*serial_plat));
+
+ serial_plat->shift = JZ_UART_SHIFT;
+ serial_plat->reg_write = &jz_serial_reg_write;
+ serial_plat->clock = clock;
+
+ return add_ns16550_device(id, base, 8 << JZ_UART_SHIFT,
+ IORESOURCE_MEM_8BIT, serial_plat);
+}
diff --git a/arch/ppc/boards/.gitignore b/arch/ppc/boards/.gitignore
new file mode 100644
index 0000000000..d1165788c9
--- /dev/null
+++ b/arch/ppc/boards/.gitignore
@@ -0,0 +1 @@
+barebox.lds
diff --git a/arch/ppc/include/asm/io.h b/arch/ppc/include/asm/io.h
index 00529898dd..d3473e5c96 100644
--- a/arch/ppc/include/asm/io.h
+++ b/arch/ppc/include/asm/io.h
@@ -135,73 +135,76 @@ static inline void __raw_writel(unsigned int v, volatile void __iomem *addr)
/*
* 8, 16 and 32 bit, big and little endian I/O operations, with barrier.
*/
-extern inline int in_8(volatile u8 *addr)
+extern inline u8 in_8(const volatile u8 __iomem *addr)
{
- int ret;
+ u8 ret;
- __asm__ __volatile__("lbz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
- return ret;
+ __asm__ __volatile__("sync; lbz%U1%X1 %0,%1; twi 0,%0,0; isync"
+ : "=r" (ret) : "m" (*addr));
+ return ret;
}
-extern inline void out_8(volatile u8 *addr, int val)
+extern inline void out_8(volatile u8 __iomem *addr, u8 val)
{
- __asm__ __volatile__("stb%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
+ __asm__ __volatile__("sync;stb%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
}
-extern inline int in_le16(volatile u16 *addr)
+extern inline u16 in_le16(const volatile u16 __iomem *addr)
{
- int ret;
+ u16 ret;
- __asm__ __volatile__("lhbrx %0,0,%1; eieio" : "=r" (ret) :
- "r" (addr), "m" (*addr));
- return ret;
+ __asm__ __volatile__("sync; lhbrx %0,0,%1; twi 0,%0,0; isync"
+ : "=r" (ret) : "r" (addr), "m" (*addr));
+ return ret;
}
-extern inline int in_be16(volatile u16 *addr)
+extern inline u16 in_be16(const volatile u16 __iomem *addr)
{
- int ret;
+ u16 ret;
- __asm__ __volatile__("lhz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
- return ret;
+ __asm__ __volatile__("sync; lhz%U1%X1 %0,%1; twi 0,%0,0; isync"
+ : "=r" (ret) : "m" (*addr));
+ return ret;
}
-extern inline void out_le16(volatile u16 *addr, int val)
+extern inline void out_le16(volatile u16 __iomem *addr, u16 val)
{
- __asm__ __volatile__("sthbrx %1,0,%2; eieio" : "=m" (*addr) :
- "r" (val), "r" (addr));
+ __asm__ __volatile__("sync; sthbrx %1,0,%2"
+ : "=m" (*addr) : "r" (val), "r" (addr));
}
-extern inline void out_be16(volatile u16 *addr, int val)
+extern inline void out_be16(volatile u16 __iomem *addr, u16 val)
{
- __asm__ __volatile__("sth%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
+ __asm__ __volatile__("sync;sth%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
}
-extern inline unsigned in_le32(volatile u32 *addr)
+extern inline u32 in_le32(const volatile u32 __iomem *addr)
{
- unsigned ret;
+ u32 ret;
- __asm__ __volatile__("lwbrx %0,0,%1; eieio" : "=r" (ret) :
- "r" (addr), "m" (*addr));
- return ret;
+ __asm__ __volatile__("sync; lwbrx %0,0,%1; twi 0,%0,0; isync"
+ : "=r" (ret) : "r" (addr), "m" (*addr));
+ return ret;
}
-extern inline unsigned in_be32(volatile u32 *addr)
+extern inline u32 in_be32(const volatile u32 __iomem *addr)
{
- unsigned ret;
+ u32 ret;
- __asm__ __volatile__("lwz%U1%X1 %0,%1; eieio" : "=r" (ret) : "m" (*addr));
- return ret;
+ __asm__ __volatile__("sync; lwz%U1%X1 %0,%1; twi 0,%0,0; isync"
+ : "=r" (ret) : "m" (*addr));
+ return ret;
}
-extern inline void out_le32(volatile unsigned *addr, int val)
+extern inline void out_le32(volatile u32 __iomem *addr, u32 val)
{
- __asm__ __volatile__("stwbrx %1,0,%2; eieio" : "=m" (*addr) :
- "r" (val), "r" (addr));
+ __asm__ __volatile__("sync; stwbrx %1,0,%2"
+ : "=m" (*addr) : "r" (val), "r" (addr));
}
-extern inline void out_be32(volatile unsigned *addr, int val)
+extern inline void out_be32(volatile u32 __iomem *addr, u32 val)
{
- __asm__ __volatile__("stw%U0%X0 %1,%0; eieio" : "=m" (*addr) : "r" (val));
+ __asm__ __volatile__("sync;stw%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
}
/*
diff --git a/arch/sandbox/board/hostfile.c b/arch/sandbox/board/hostfile.c
index 48c6ea35a8..ac29cfa47a 100644
--- a/arch/sandbox/board/hostfile.c
+++ b/arch/sandbox/board/hostfile.c
@@ -77,6 +77,9 @@ static int hf_probe(struct device_d *dev)
priv->cdev.size = hf->size;
priv->cdev.ops = &hf_fops;
priv->cdev.priv = hf;
+
+ dev->info = hf_info;
+
#ifdef CONFIG_FS_DEVFS
devfs_create(&priv->cdev);
#endif
@@ -87,7 +90,6 @@ static int hf_probe(struct device_d *dev)
static struct driver_d hf_drv = {
.name = "hostfile",
.probe = hf_probe,
- .info = hf_info,
};
device_platform_driver(hf_drv);
@@ -111,4 +113,3 @@ int barebox_register_filedev(struct hf_platform_data *hf)
return sandbox_add_device(dev);
}
-
diff --git a/arch/x86/include/asm/types.h b/arch/x86/include/asm/types.h
index b0218d27c0..d473405ff9 100644
--- a/arch/x86/include/asm/types.h
+++ b/arch/x86/include/asm/types.h
@@ -29,12 +29,16 @@ typedef unsigned int __u32;
typedef __signed__ long long __s64;
typedef unsigned long long __u64;
+typedef signed char s8;
typedef unsigned char u8;
+typedef signed short s16;
typedef unsigned short u16;
+typedef signed int s32;
typedef unsigned int u32;
+typedef signed long long s64;
typedef unsigned long long u64;
#endif /* __ASSEMBLY__ */
diff --git a/commands/Kconfig b/commands/Kconfig
index 6a759ce204..a62ed9823b 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -728,6 +728,15 @@ config CMD_CLK
Say yes here to get clk_set_rate, clk_set_parent and clk_dump
commands to manipulate clocks on your system.
+config CMD_DETECT
+ tristate
+ prompt "detect"
+ help
+ say yes here to get the 'detect' command. Some devices take longer
+ time to probe, like slow disks or SD/MMC cards. These can defer the
+ actual probe of the client devices until they are needed. Use the
+ 'detect' command on the physical device to trigger probing.
+
menuconfig CMD_WD
bool
depends on WATCHDOG
diff --git a/commands/Makefile b/commands/Makefile
index 953ecc284b..419d93bc0e 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -90,3 +90,4 @@ obj-$(CONFIG_CMD_TFTP) += tftp.o
obj-$(CONFIG_CMD_FILETYPE) += filetype.o
obj-$(CONFIG_CMD_BAREBOX_UPDATE)+= barebox-update.o
obj-$(CONFIG_CMD_MIITOOL) += miitool.o
+obj-$(CONFIG_CMD_DETECT) += detect.o
diff --git a/commands/bootm.c b/commands/bootm.c
index 5dd1703538..6ce2ca9897 100644
--- a/commands/bootm.c
+++ b/commands/bootm.c
@@ -395,13 +395,9 @@ static int do_bootm(int argc, char *argv[])
goto err_out;
} else {
data.of_root_node = of_get_root_node();
- if (bootm_verbose(&data) && data.of_root_node)
+ if (data.of_root_node)
printf("using internal devicetree\n");
}
-
-
- if (bootm_verbose(&data) > 1 && data.of_root_node)
- of_print_nodes(data.of_root_node, 0);
#endif
if (data.os_address == UIMAGE_SOME_ADDRESS)
data.os_address = UIMAGE_INVALID_ADDRESS;
diff --git a/commands/detect.c b/commands/detect.c
new file mode 100644
index 0000000000..0010a17779
--- /dev/null
+++ b/commands/detect.c
@@ -0,0 +1,77 @@
+/*
+ * detect.c - detect devices command
+ *
+ * Copyright (c) 2013 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * 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.
+ *
+ */
+#include <common.h>
+#include <command.h>
+#include <complete.h>
+#include <driver.h>
+#include <getopt.h>
+
+static int do_detect(int argc, char *argv[])
+{
+ struct device_d *dev;
+ int opt, i, ret;
+ int option_list = 0;
+ int option_error = 0;
+
+ while ((opt = getopt(argc, argv, "el")) > 0) {
+ switch (opt) {
+ case 'l':
+ option_list = 1;
+ break;
+ case 'e':
+ option_error = 1;
+ break;
+ }
+ }
+
+ if (option_list) {
+ for_each_device(dev) {
+ if (dev->detect)
+ printf("%s\n", dev_name(dev));
+ }
+ return 0;
+ }
+
+ if (argc == optind)
+ return COMMAND_ERROR_USAGE;
+
+ for (i = optind; i < argc; i++) {
+ dev = get_device_by_name(argv[i]);
+ if (!dev)
+ return -ENODEV;
+ ret = device_detect(dev);
+ if (ret && option_error)
+ return ret;
+ }
+
+ return 0;
+}
+
+BAREBOX_CMD_HELP_START(detect)
+BAREBOX_CMD_HELP_USAGE("detect [OPTIONS] [devices]\n")
+BAREBOX_CMD_HELP_OPT ("-l", "list detectable devices\n")
+BAREBOX_CMD_HELP_OPT ("-e", "bail out if one device fails to detect\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(detect)
+ .cmd = do_detect,
+ .usage = "detect devices",
+ BAREBOX_CMD_COMPLETE(device_complete)
+ BAREBOX_CMD_HELP(cmd_detect_help)
+BAREBOX_CMD_END
diff --git a/common/block.c b/common/block.c
index 120d65928e..ad07f8b2e2 100644
--- a/common/block.c
+++ b/common/block.c
@@ -176,7 +176,7 @@ static void *block_get(struct block_device *blk, int block)
return outdata;
}
-static ssize_t block_read(struct cdev *cdev, void *buf, size_t count,
+static ssize_t block_op_read(struct cdev *cdev, void *buf, size_t count,
loff_t offset, unsigned long flags)
{
struct block_device *blk = cdev->priv;
@@ -253,7 +253,7 @@ static int block_put(struct block_device *blk, const void *buf, int block)
return 0;
}
-static ssize_t block_write(struct cdev *cdev, const void *buf, size_t count,
+static ssize_t block_op_write(struct cdev *cdev, const void *buf, size_t count,
loff_t offset, ulong flags)
{
struct block_device *blk = cdev->priv;
@@ -310,14 +310,14 @@ static ssize_t block_write(struct cdev *cdev, const void *buf, size_t count,
}
#endif
-static int block_close(struct cdev *cdev)
+static int block_op_close(struct cdev *cdev)
{
struct block_device *blk = cdev->priv;
return writebuffer_flush(blk);
}
-static int block_flush(struct cdev *cdev)
+static int block_op_flush(struct cdev *cdev)
{
struct block_device *blk = cdev->priv;
@@ -325,12 +325,12 @@ static int block_flush(struct cdev *cdev)
}
static struct file_operations block_ops = {
- .read = block_read,
+ .read = block_op_read,
#ifdef CONFIG_BLOCK_WRITE
- .write = block_write,
+ .write = block_op_write,
#endif
- .close = block_close,
- .flush = block_flush,
+ .close = block_op_close,
+ .flush = block_op_flush,
.lseek = dev_lseek_default,
};
@@ -387,3 +387,25 @@ int blockdevice_unregister(struct block_device *blk)
return 0;
}
+
+int block_read(struct block_device *blk, void *buf, int block, int num_blocks)
+{
+ int ret;
+
+ ret = cdev_read(&blk->cdev, buf,
+ num_blocks << blk->blockbits,
+ (loff_t)block << blk->blockbits, 0);
+
+ return ret < 0 ? ret : 0;
+}
+
+int block_write(struct block_device *blk, void *buf, int block, int num_blocks)
+{
+ int ret;
+
+ ret = cdev_write(&blk->cdev, buf,
+ num_blocks << blk->blockbits,
+ (loff_t)block << blk->blockbits, 0);
+
+ return ret < 0 ? ret : 0;
+}
diff --git a/common/globalvar.c b/common/globalvar.c
index a8aaa72553..abcd881adf 100644
--- a/common/globalvar.c
+++ b/common/globalvar.c
@@ -22,7 +22,7 @@ int globalvar_add(const char *name,
* get a concatenated string of all globalvars beginning with 'match'.
* This adds whitespaces between the different globalvars
*/
-char *globalvar_get_match(const char *match, const char *seperator)
+char *globalvar_get_match(const char *match, const char *separator)
{
char *val = NULL;
struct param_d *param;
@@ -31,7 +31,7 @@ char *globalvar_get_match(const char *match, const char *seperator)
if (!strncmp(match, param->name, strlen(match))) {
const char *p = dev_get_param(&global_device, param->name);
if (val) {
- char *new = asprintf("%s%s%s", val, seperator, p);
+ char *new = asprintf("%s%s%s", val, separator, p);
free(val);
val = new;
} else {
diff --git a/common/hush.c b/common/hush.c
index b5e111a019..a3235ba19f 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -1959,7 +1959,7 @@ BAREBOX_CMD_START(getopt)
BAREBOX_CMD_END
#endif
-BAREBOX_MAGICVAR(PATH, "colon seperated list of pathes to search for executables");
+BAREBOX_MAGICVAR(PATH, "colon separated list of pathes to search for executables");
#ifdef CONFIG_HUSH_FANCY_PROMPT
BAREBOX_MAGICVAR(PS1, "hush prompt");
#endif
diff --git a/common/oftree.c b/common/oftree.c
index 776d301186..475d418849 100644
--- a/common/oftree.c
+++ b/common/oftree.c
@@ -98,6 +98,21 @@ void of_print_property(const void *data, int len)
}
}
+void of_print_cmdline(struct device_node *root)
+{
+ struct device_node *node = of_find_node_by_path(root, "/chosen");
+ const char *cmdline;
+
+ if (!node) {
+ printf("commandline: no /chosen node\n");
+ return;
+ }
+
+ cmdline = of_get_property(node, "bootargs", NULL);
+
+ printf("commandline: %s\n", cmdline);
+}
+
static int of_fixup_bootargs(struct device_node *root)
{
struct device_node *node;
@@ -161,12 +176,6 @@ int of_fix_tree(struct device_node *node)
}
/*
- * The size by which we increase the dtb to have space for additional
- * fixups. Ideally this would be done by libfdt automatically
- */
-#define OFTREE_SIZE_INCREASE 0x8000
-
-/*
* Get the fixed fdt. This function uses the fdt input pointer
* if provided or the barebox internal devicetree if not.
* It increases the size of the tree and applies the registered
diff --git a/common/partitions.c b/common/partitions.c
index 683b2586e4..35a604c35f 100644
--- a/common/partitions.c
+++ b/common/partitions.c
@@ -128,7 +128,7 @@ int parse_partition_table(struct block_device *blk)
pdesc = xzalloc(sizeof(*pdesc));
buf = dma_alloc(SECTOR_SIZE * 2);
- rc = blk->ops->read(blk, buf, 0, 2);
+ rc = block_read(blk, buf, 0, 2);
if (rc != 0) {
dev_err(blk->dev, "Cannot read MBR/partition table\n");
goto on_error;
diff --git a/common/partitions/Kconfig b/common/partitions/Kconfig
index 077091cde2..90238ad382 100644
--- a/common/partitions/Kconfig
+++ b/common/partitions/Kconfig
@@ -1,5 +1,6 @@
config PARTITION_DISK
depends on PARTITION
+ depends on BLOCK
bool "DISK partition support"
help
Add support for handling common partition tables on all kind of disk
diff --git a/common/partitions/dos.c b/common/partitions/dos.c
index 597f9ba581..b9f31c3784 100644
--- a/common/partitions/dos.c
+++ b/common/partitions/dos.c
@@ -16,6 +16,8 @@
#include <disks.h>
#include <init.h>
#include <asm/unaligned.h>
+#include <dma.h>
+#include <linux/err.h>
#include "parser.h"
@@ -40,6 +42,74 @@ static int disk_guess_size(struct device_d *dev, struct partition_entry *table)
return (int)size;
}
+static void *read_mbr(struct block_device *blk)
+{
+ void *buf = dma_alloc(SECTOR_SIZE);
+ int ret;
+
+ ret = block_read(blk, buf, 0, 1);
+ if (ret) {
+ free(buf);
+ return NULL;
+ }
+
+ return buf;
+}
+
+static int write_mbr(struct block_device *blk, void *buf)
+{
+ int ret;
+
+ ret = block_write(blk, buf, 0, 1);
+ if (ret)
+ return ret;
+
+ return block_flush(blk);
+}
+
+struct disk_signature_priv {
+ uint32_t signature;
+ struct block_device *blk;
+};
+
+static int dos_set_disk_signature(struct param_d *p, void *_priv)
+{
+ struct disk_signature_priv *priv = _priv;
+ struct block_device *blk = priv->blk;
+ void *buf;
+ __le32 *disksigp;
+ int ret;
+
+ buf = read_mbr(blk);
+ if (!buf)
+ return -EIO;
+
+ disksigp = buf + 0x1b8;
+
+ *disksigp = cpu_to_le32(priv->signature);
+
+ ret = write_mbr(blk, buf);
+
+ free(buf);
+
+ return ret;
+}
+
+static int dos_get_disk_signature(struct param_d *p, void *_priv)
+{
+ struct disk_signature_priv *priv = _priv;
+ struct block_device *blk = priv->blk;
+ void *buf;
+
+ buf = read_mbr(blk);
+ if (!buf)
+ return -EIO;
+
+ priv->signature = le32_to_cpup((__le32 *)(buf + 0x1b8));
+
+ return 0;
+}
+
/**
* Check if a DOS like partition describes this block device
* @param blk Block device to register to
@@ -55,6 +125,7 @@ static void dos_partition(void *buf, struct block_device *blk,
struct partition pentry;
uint8_t *buffer = buf;
int i;
+ struct disk_signature_priv *dsp;
table = (struct partition_entry *)&buffer[446];
@@ -74,6 +145,23 @@ static void dos_partition(void *buf, struct block_device *blk,
dev_dbg(blk->dev, "Skipping empty partition %d\n", i);
}
}
+
+ dsp = xzalloc(sizeof(*dsp));
+ dsp->blk = blk;
+
+ /*
+ * This parameter contains the NT disk signature. This allows to
+ * to specify the Linux rootfs using the following syntax:
+ *
+ * root=PARTUUID=ssssssss-pp
+ *
+ * where ssssssss is a zero-filled hex representation of the 32-bit
+ * signature and pp is a zero-filled hex representation of the 1-based
+ * partition number.
+ */
+ dev_add_param_int(blk->dev, "nt_signature",
+ dos_set_disk_signature, dos_get_disk_signature,
+ &dsp->signature, "%08x", dsp);
}
static struct partition_parser dos = {
diff --git a/common/partitions/efi.c b/common/partitions/efi.c
index e450eebf77..ee1326e622 100644
--- a/common/partitions/efi.c
+++ b/common/partitions/efi.c
@@ -86,7 +86,7 @@ static gpt_entry *alloc_read_gpt_entries(struct block_device *blk,
from = le64_to_cpu(pgpt_head->partition_entry_lba);
size = count / GPT_BLOCK_SIZE;
- ret = blk->ops->read(blk, pte, from, size);
+ ret = block_read(blk, pte, from, size);
if (ret) {
kfree(pte);
pte=NULL;
@@ -121,7 +121,7 @@ static gpt_header *alloc_read_gpt_header(struct block_device *blk,
if (!gpt)
return NULL;
- ret = blk->ops->read(blk, gpt, lba, 1);
+ ret = block_read(blk, gpt, lba, 1);
if (ret) {
kfree(gpt);
gpt=NULL;
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 37419f239a..7def9a093b 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -635,6 +635,7 @@ static int ahci_probe(struct device_d *dev)
ahci->dev = dev;
ahci->mmio_base = regs;
dev->priv = ahci;
+ dev->info = ahci_info;
ret = ahci_add_host(ahci);
if (ret)
@@ -654,7 +655,6 @@ static __maybe_unused struct of_device_id ahci_dt_ids[] = {
static struct driver_d ahci_driver = {
.name = "ahci",
.probe = ahci_probe,
- .info = ahci_info,
.of_compatible = DRV_OF_COMPAT(ahci_dt_ids),
};
device_platform_driver(ahci_driver);
diff --git a/drivers/ata/sata-imx.c b/drivers/ata/sata-imx.c
index bd48fae1f4..13bf116fdd 100644
--- a/drivers/ata/sata-imx.c
+++ b/drivers/ata/sata-imx.c
@@ -107,6 +107,7 @@ static int imx_sata_probe(struct device_d *dev)
imx_ahci->ahci.dev = dev;
dev->priv = &imx_ahci->ahci;
+ dev->info = ahci_info,
ret = ahci_add_host(&imx_ahci->ahci);
if (ret)
@@ -143,7 +144,6 @@ static struct platform_device_id imx_sata_ids[] = {
static struct driver_d imx_sata_driver = {
.name = "imx-sata",
.probe = imx_sata_probe,
- .info = ahci_info,
.id_table = imx_sata_ids,
};
device_platform_driver(imx_sata_driver);
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index edd49b367f..810d0011f6 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -93,6 +93,13 @@ int device_probe(struct device_d *dev)
return 0;
}
+int device_detect(struct device_d *dev)
+{
+ if (!dev->detect)
+ return -ENOSYS;
+ return dev->detect(dev);
+}
+
static int match(struct driver_d *drv, struct device_d *dev)
{
int ret;
@@ -201,15 +208,6 @@ struct driver_d *get_driver_by_name(const char *name)
return NULL;
}
-static void noinfo(struct device_d *dev)
-{
- printf("no info available for %s\n", dev_name(dev));
-}
-
-static void noshortinfo(struct device_d *dev)
-{
-}
-
int register_driver(struct driver_d *drv)
{
struct device_d *dev = NULL;
@@ -221,11 +219,6 @@ int register_driver(struct driver_d *drv)
list_add_tail(&drv->list, &driver_list);
list_add_tail(&drv->bus_list, &drv->bus->driver_list);
- if (!drv->info)
- drv->info = noinfo;
- if (!drv->shortinfo)
- drv->shortinfo = noshortinfo;
-
bus_for_each_device(drv->bus, dev)
match(drv, dev);
@@ -489,14 +482,18 @@ static int do_devinfo(int argc, char *argv[])
printf("bus: %s\n\n", dev->bus ?
dev->bus->name : "none");
- if (dev->driver)
- dev->driver->info(dev);
+ if (dev->info)
+ dev->info(dev);
printf("%s\n", list_empty(&dev->parameters) ?
"no parameters available" : "Parameters:");
- list_for_each_entry(param, &dev->parameters, list)
- printf("%16s = %s\n", param->name, dev_get_param(dev, param->name));
+ list_for_each_entry(param, &dev->parameters, list) {
+ printf("%16s = %s", param->name, dev_get_param(dev, param->name));
+ if (param->info)
+ param->info(param);
+ printf("\n");
+ }
#ifdef CONFIG_OFDEVICE
if (dev->device_node) {
printf("\ndevice node: %s\n", dev->device_node->full_name);
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
index 9f3558b6e4..4ef25ec45b 100644
--- a/drivers/clocksource/Kconfig
+++ b/drivers/clocksource/Kconfig
@@ -14,6 +14,14 @@ config CLOCKSOURCE_CLPS711X
bool
depends on ARCH_CLPS711X
+config CLOCKSOURCE_MVEBU
+ bool
+ depends on ARCH_MVEBU
+
config CLOCKSOURCE_NOMADIK
bool
depends on ARM
+
+config CLOCKSOURCE_ORION
+ bool
+ depends on ARCH_MVEBU
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index d919881fb8..25b7f460da 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -2,4 +2,6 @@ obj-$(CONFIG_AMBA_SP804) += amba-sp804.o
obj-$(CONFIG_ARM_SMP_TWD) += arm_smp_twd.o
obj-$(CONFIG_CLOCKSOURCE_BCM2835) += bcm2835.o
obj-$(CONFIG_CLOCKSOURCE_CLPS711X) += clps711x.o
+obj-$(CONFIG_CLOCKSOURCE_MVEBU) += mvebu.o
obj-$(CONFIG_CLOCKSOURCE_NOMADIK) += nomadik.o
+obj-$(CONFIG_CLOCKSOURCE_ORION) += orion.o
diff --git a/drivers/clocksource/mvebu.c b/drivers/clocksource/mvebu.c
new file mode 100644
index 0000000000..2b48a5c91b
--- /dev/null
+++ b/drivers/clocksource/mvebu.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2013 Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+ *
+ * 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.
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <linux/clk.h>
+#include <io.h>
+
+#define TIMER_CTRL_OFF 0x0000
+#define TIMER0_EN 0x0001
+#define TIMER0_RELOAD_EN 0x0002
+#define TIMER0_25MHZ 0x0800
+#define TIMER0_DIV(div) ((div) << 19)
+#define TIMER1_EN 0x0004
+#define TIMER1_RELOAD_EN 0x0008
+#define TIMER1_25MHZ 0x1000
+#define TIMER1_DIV(div) ((div) << 22)
+#define TIMER_EVENTS_STATUS 0x0004
+#define TIMER0_CLR_MASK (~0x1)
+#define TIMER1_CLR_MASK (~0x100)
+#define TIMER0_RELOAD_OFF 0x0010
+#define TIMER0_VAL_OFF 0x0014
+#define TIMER1_RELOAD_OFF 0x0018
+#define TIMER1_VAL_OFF 0x001c
+
+#define TIMER_DIVIDER_SHIFT 5
+
+static __iomem void *timer_base;
+
+uint64_t mvebu_clocksource_read(void)
+{
+ return __raw_readl(timer_base + TIMER0_VAL_OFF);
+}
+
+static struct clocksource cs = {
+ .read = mvebu_clocksource_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 10,
+};
+
+static int mvebu_timer_probe(struct device_d *dev)
+{
+ struct clk *tclk;
+ u32 val;
+
+ timer_base = dev_request_mem_region(dev, 0);
+
+ tclk = clk_get(dev, "tclk");
+
+ val = __raw_readl(timer_base + TIMER_CTRL_OFF);
+ val &= ~TIMER0_25MHZ;
+ __raw_writel(val, timer_base + TIMER_CTRL_OFF);
+
+ __raw_writel(0xffffffff, timer_base + TIMER0_VAL_OFF);
+ __raw_writel(0xffffffff, timer_base + TIMER0_RELOAD_OFF);
+
+ val = __raw_readl(timer_base + TIMER_CTRL_OFF);
+ val |= TIMER0_EN | TIMER0_RELOAD_EN | TIMER0_DIV(TIMER_DIVIDER_SHIFT);
+ __raw_writel(val, timer_base + TIMER_CTRL_OFF);
+
+ cs.mult = clocksource_hz2mult(clk_get_rate(tclk), cs.shift);
+
+ init_clock(&cs);
+
+ return 0;
+}
+
+static struct driver_d mvebu_timer_driver = {
+ .name = "mvebu-timer",
+ .probe = mvebu_timer_probe,
+};
+
+static int mvebu_timer_init(void)
+{
+ return platform_driver_register(&mvebu_timer_driver);
+}
+postcore_initcall(mvebu_timer_init);
diff --git a/drivers/clocksource/orion.c b/drivers/clocksource/orion.c
new file mode 100644
index 0000000000..604b414742
--- /dev/null
+++ b/drivers/clocksource/orion.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright
+ * (C) 2013 Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
+ *
+ * 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.
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <linux/clk.h>
+#include <io.h>
+
+#define TIMER_CTRL 0x00
+#define TIMER0_EN BIT(0)
+#define TIMER0_RELOAD_EN BIT(1)
+#define TIMER1_EN BIT(2)
+#define TIMER1_RELOAD_EN BIT(3)
+#define TIMER0_RELOAD 0x10
+#define TIMER0_VAL 0x14
+#define TIMER1_RELOAD 0x18
+#define TIMER1_VAL 0x1c
+
+static __iomem void *timer_base;
+
+static uint64_t orion_clocksource_read(void)
+{
+ return __raw_readl(timer_base + TIMER0_VAL);
+}
+
+static struct clocksource clksrc = {
+ .read = orion_clocksource_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 10,
+};
+
+static int orion_timer_probe(struct device_d *dev)
+{
+ struct clk *tclk;
+ uint32_t val;
+
+ timer_base = dev_request_mem_region(dev, 0);
+ tclk = clk_get(dev, "tclk");
+
+ /* setup TIMER0 as free-running clock source */
+ __raw_writel(~0, timer_base + TIMER0_VAL);
+ __raw_writel(~0, timer_base + TIMER0_RELOAD);
+ val = __raw_readl(timer_base + TIMER_CTRL);
+ __raw_writel(val | TIMER0_EN | TIMER0_RELOAD_EN,
+ timer_base + TIMER_CTRL);
+
+ clksrc.mult = clocksource_hz2mult(clk_get_rate(tclk), clksrc.shift);
+ init_clock(&clksrc);
+
+ return 0;
+}
+
+static struct driver_d orion_timer_driver = {
+ .name = "orion-timer",
+ .probe = orion_timer_probe,
+};
+
+static int orion_timer_init(void)
+{
+ return platform_driver_register(&orion_timer_driver);
+}
+postcore_initcall(orion_timer_init);
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 6398268eae..ca6e8adab4 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -1,3 +1,5 @@
+#define pr_fmt(fmt) "gpiolib: " fmt
+
#include <init.h>
#include <common.h>
#include <command.h>
@@ -32,20 +34,30 @@ static int gpio_ensure_requested(struct gpio_info *gi, int gpio)
return gpio_request(gpio, "gpio");
}
+static struct gpio_info *gpio_to_desc(unsigned gpio)
+{
+ if (gpio_is_valid(gpio))
+ if (gpio_desc[gpio].chip)
+ return &gpio_desc[gpio];
+
+ pr_warning("invalid GPIO %d\n", gpio);
+
+ return NULL;
+}
+
int gpio_request(unsigned gpio, const char *label)
{
- struct gpio_info *gi = &gpio_desc[gpio];
- struct gpio_chip *chip = gi->chip;
+ struct gpio_info *gi = gpio_to_desc(gpio);
int ret;
- if (!gpio_is_valid(gpio))
- return -EINVAL;
- if (!chip)
- return -EINVAL;
+ if (!gi)
+ return -ENODEV;
+
if (gi->requested)
return -EBUSY;
- if (chip->ops->request) {
- ret = chip->ops->request(chip, gpio - chip->base);
+
+ if (gi->chip->ops->request) {
+ ret = gi->chip->ops->request(gi->chip, gpio - gi->chip->base);
if (ret)
return ret;
}
@@ -58,17 +70,16 @@ int gpio_request(unsigned gpio, const char *label)
void gpio_free(unsigned gpio)
{
- struct gpio_info *gi = &gpio_desc[gpio];
- struct gpio_chip *chip = gi->chip;
+ struct gpio_info *gi = gpio_to_desc(gpio);
- if (!gpio_is_valid(gpio))
- return;
- if (!chip)
+ if (!gi)
return;
+
if (!gi->requested)
return;
- if (chip->ops->free)
- chip->ops->free(chip, gpio - chip->base);
+
+ if (gi->chip->ops->free)
+ gi->chip->ops->free(gi->chip, gpio - gi->chip->base);
gi->requested = false;
free(gi->label);
@@ -76,75 +87,71 @@ void gpio_free(unsigned gpio)
void gpio_set_value(unsigned gpio, int value)
{
- struct gpio_info *gi = &gpio_desc[gpio];
- struct gpio_chip *chip = gi->chip;
+ struct gpio_info *gi = gpio_to_desc(gpio);
- if (!gpio_is_valid(gpio))
- return;
- if (!chip)
+ if (!gi)
return;
+
if (gpio_ensure_requested(gi, gpio))
return;
- if (!chip->ops->set)
- return;
- chip->ops->set(chip, gpio - chip->base, value);
+
+ if (gi->chip->ops->set)
+ gi->chip->ops->set(gi->chip, gpio - gi->chip->base, value);
}
EXPORT_SYMBOL(gpio_set_value);
int gpio_get_value(unsigned gpio)
{
- struct gpio_info *gi = &gpio_desc[gpio];
- struct gpio_chip *chip = gi->chip;
+ struct gpio_info *gi = gpio_to_desc(gpio);
int ret;
- if (!gpio_is_valid(gpio))
- return -EINVAL;
- if (!chip)
+ if (!gi)
return -ENODEV;
+
ret = gpio_ensure_requested(gi, gpio);
if (ret)
return ret;
- if (!chip->ops->get)
+
+ if (!gi->chip->ops->get)
return -ENOSYS;
- return chip->ops->get(chip, gpio - chip->base);
+ return gi->chip->ops->get(gi->chip, gpio - gi->chip->base);
}
EXPORT_SYMBOL(gpio_get_value);
int gpio_direction_output(unsigned gpio, int value)
{
- struct gpio_info *gi = &gpio_desc[gpio];
- struct gpio_chip *chip = gi->chip;
+ struct gpio_info *gi = gpio_to_desc(gpio);
int ret;
- if (!gpio_is_valid(gpio))
- return -EINVAL;
- if (!chip)
+ if (!gi)
return -ENODEV;
+
ret = gpio_ensure_requested(gi, gpio);
if (ret)
return ret;
- if (!chip->ops->direction_output)
+
+ if (!gi->chip->ops->direction_output)
return -ENOSYS;
- return chip->ops->direction_output(chip, gpio - chip->base, value);
+ return gi->chip->ops->direction_output(gi->chip, gpio - gi->chip->base,
+ value);
}
EXPORT_SYMBOL(gpio_direction_output);
int gpio_direction_input(unsigned gpio)
{
- struct gpio_info *gi = &gpio_desc[gpio];
- struct gpio_chip *chip = gi->chip;
+ struct gpio_info *gi = gpio_to_desc(gpio);
int ret;
- if (!gpio_is_valid(gpio))
- return -EINVAL;
- if (!chip)
+ if (!gi)
return -ENODEV;
+
ret = gpio_ensure_requested(gi, gpio);
if (ret)
return ret;
- if (!chip->ops->direction_input)
+
+ if (!gi->chip->ops->direction_input)
return -ENOSYS;
- return chip->ops->direction_input(chip, gpio - chip->base);
+ return gi->chip->ops->direction_input(gi->chip, gpio - gi->chip->base);
}
EXPORT_SYMBOL(gpio_direction_input);
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c
index 9fcfd5c6f7..c607bcba1a 100644
--- a/drivers/i2c/busses/i2c-imx.c
+++ b/drivers/i2c/busses/i2c-imx.c
@@ -545,6 +545,7 @@ static int __init i2c_fsl_probe(struct device_d *pdev)
i2c_fsl->adapter.master_xfer = i2c_fsl_xfer;
i2c_fsl->adapter.nr = pdev->id;
i2c_fsl->adapter.dev.parent = pdev;
+ i2c_fsl->adapter.dev.device_node = pdev->device_node;
i2c_fsl->base = dev_request_mem_region(pdev, 0);
i2c_fsl->dfsrr = -1;
@@ -572,8 +573,17 @@ fail:
return ret;
}
+static __maybe_unused struct of_device_id imx_i2c_dt_ids[] = {
+ {
+ .compatible = "fsl,imx21-i2c",
+ }, {
+ /* sentinel */
+ }
+};
+
static struct driver_d i2c_fsl_driver = {
.probe = i2c_fsl_probe,
.name = DRIVER_NAME,
+ .of_compatible = DRV_OF_COMPAT(imx_i2c_dt_ids),
};
device_platform_driver(i2c_fsl_driver);
diff --git a/drivers/i2c/i2c.c b/drivers/i2c/i2c.c
index 4862df3c00..b63d94604d 100644
--- a/drivers/i2c/i2c.c
+++ b/drivers/i2c/i2c.c
@@ -254,33 +254,61 @@ struct i2c_client *i2c_new_device(struct i2c_adapter *adapter,
client->dev.platform_data = chip->platform_data;
client->dev.id = DEVICE_ID_DYNAMIC;
client->dev.bus = &i2c_bus;
+ client->dev.device_node = chip->of_node;
client->adapter = adapter;
client->addr = chip->addr;
client->dev.parent = &adapter->dev;
status = register_device(&client->dev);
-
-#if 0
- /* drivers may modify this initial i/o setup */
- status = master->setup(client);
- if (status < 0) {
- printf("can't setup %s, status %d\n",
- client->dev.name, status);
- goto fail;
+ if (status) {
+ free(client);
+ return NULL;
}
-#endif
return client;
-
-#if 0
- fail:
- free(proxy);
- return NULL;
-#endif
}
EXPORT_SYMBOL(i2c_new_device);
+void of_i2c_register_devices(struct i2c_adapter *adap)
+{
+ struct device_node *n;
+
+ /* Only register child devices if the adapter has a node pointer set */
+ if (!IS_ENABLED(CONFIG_OFDEVICE) || !adap->dev.device_node)
+ return;
+
+ device_node_for_nach_child(adap->dev.device_node, n) {
+ struct i2c_board_info info = {};
+ struct i2c_client *result;
+ const __be32 *addr;
+ int len;
+
+ of_modalias_node(n, info.type, I2C_NAME_SIZE);
+
+ info.of_node = n;
+
+ addr = of_get_property(n, "reg", &len);
+ if (!addr || (len < sizeof(int))) {
+ dev_err(&adap->dev, "of_i2c: invalid reg on %s\n",
+ n->full_name);
+ continue;
+ }
+
+ info.addr = be32_to_cpup(addr);
+ if (info.addr > (1 << 10) - 1) {
+ dev_err(&adap->dev, "of_i2c: invalid addr=%x on %s\n",
+ info.addr, n->full_name);
+ continue;
+ }
+
+ result = i2c_new_device(adap, &info);
+ if (!result)
+ dev_err(&adap->dev, "of_i2c: Failure registering %s\n",
+ n->full_name);
+ }
+}
+
/**
* i2c_new_dummy - return a new i2c device bound to a dummy driver
* @adapter: the adapter managing the device
@@ -396,8 +424,17 @@ int i2c_add_numbered_adapter(struct i2c_adapter *adapter)
{
int ret;
- if (i2c_get_adapter(adapter->nr))
- return -EBUSY;
+ if (adapter->nr < 0) {
+ int nr;
+
+ for (nr = 0;; nr++)
+ if (!i2c_get_adapter(nr))
+ break;
+ adapter->nr = nr;
+ } else {
+ if (i2c_get_adapter(adapter->nr))
+ return -EBUSY;
+ }
adapter->dev.id = adapter->nr;
strcpy(adapter->dev.name, "i2c");
@@ -411,6 +448,8 @@ int i2c_add_numbered_adapter(struct i2c_adapter *adapter)
/* populate children from any i2c device tables */
scan_boardinfo(adapter);
+ of_i2c_register_devices(adapter);
+
return 0;
}
EXPORT_SYMBOL(i2c_add_numbered_adapter);
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index 9558f287d3..7aff7df838 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -29,6 +29,9 @@ config MCI_WRITE
default y
select DISK_WRITE
+config MCI_MMC_BOOT_PARTITIONS
+ bool "support MMC boot partitions"
+
comment "--- MCI host drivers ---"
config MCI_MXS
@@ -45,6 +48,10 @@ config MCI_S3C
Enable this entry to add support to read and write SD cards on a
Samsung S3C24xx based system.
+config MCI_BCM2835
+ bool "MCI support for BCM2835"
+ depends on ARCH_BCM2835
+
config MCI_IMX
bool "i.MX"
depends on ARCH_IMX27 || ARCH_IMX31
diff --git a/drivers/mci/Makefile b/drivers/mci/Makefile
index d46d5f50e8..df06a08f61 100644
--- a/drivers/mci/Makefile
+++ b/drivers/mci/Makefile
@@ -1,10 +1,10 @@
-obj-$(CONFIG_MCI) += mci-core.o
-obj-$(CONFIG_MCI_MXS) += mxs.o
-obj-$(CONFIG_MCI_S3C) += s3c.o
-obj-$(CONFIG_MCI_IMX) += imx.o
-obj-$(CONFIG_MCI_IMX_ESDHC) += imx-esdhc.o
-obj-$(CONFIG_MCI_OMAP_HSMMC) += omap_hsmmc.o
-obj-$(CONFIG_MFD_TWL6030) += twl6030.o
-obj-$(CONFIG_MCI_PXA) += pxamci.o
-obj-$(CONFIG_MCI_ATMEL) += atmel_mci.o
-obj-$(CONFIG_MCI_SPI) += mci_spi.o
+obj-$(CONFIG_MCI) += mci-core.o
+obj-$(CONFIG_MCI_ATMEL) += atmel_mci.o
+obj-$(CONFIG_MCI_BCM2835) += mci-bcm2835.o
+obj-$(CONFIG_MCI_IMX) += imx.o
+obj-$(CONFIG_MCI_IMX_ESDHC) += imx-esdhc.o
+obj-$(CONFIG_MCI_MXS) += mxs.o
+obj-$(CONFIG_MCI_OMAP_HSMMC) += omap_hsmmc.o
+obj-$(CONFIG_MCI_PXA) += pxamci.o
+obj-$(CONFIG_MCI_S3C) += s3c.o
+obj-$(CONFIG_MCI_SPI) += mci_spi.o
diff --git a/drivers/mci/atmel_mci.c b/drivers/mci/atmel_mci.c
index c5fd306a9a..b5873f967b 100644
--- a/drivers/mci/atmel_mci.c
+++ b/drivers/mci/atmel_mci.c
@@ -470,7 +470,6 @@ static int atmci_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci_d
return atmci_cmd_done(host, stat);
}
-#ifdef CONFIG_MCI_INFO
static void atmci_info(struct device_d *mci_dev)
{
struct atmel_mci *host = mci_dev->priv;
@@ -493,7 +492,6 @@ static void atmci_info(struct device_d *mci_dev)
gpio_is_valid(pd->detect_pin) ? "yes" : "no");
}
-#endif /* CONFIG_MCI_INFO */
/*
* HSMCI (High Speed MCI) module is not fully compatible with MCI module.
* HSMCI provides DMA support and a new config register but no more supports
@@ -603,6 +601,9 @@ static int atmci_probe(struct device_d *hw_dev)
else
host->sdc_reg = ATMCI_SDCSEL_SLOT_A;
+ if (IS_ENABLED(CONFIG_MCI_INFO))
+ hw_dev->info = atmci_info;
+
mci_register(&host->mci);
return 0;
@@ -617,8 +618,5 @@ err_gpio_cd_request:
static struct driver_d atmci_driver = {
.name = "atmel_mci",
.probe = atmci_probe,
-#ifdef CONFIG_MCI_INFO
- .info = atmci_info,
-#endif
};
device_platform_driver(atmci_driver);
diff --git a/drivers/mci/imx-esdhc.c b/drivers/mci/imx-esdhc.c
index f4fdac8e01..8053b79cb7 100644
--- a/drivers/mci/imx-esdhc.c
+++ b/drivers/mci/imx-esdhc.c
@@ -35,38 +35,15 @@
#include <mach/esdhc.h>
#include <gpio.h>
+#include "sdhci.h"
#include "imx-esdhc.h"
-struct fsl_esdhc {
- u32 dsaddr;
- u32 blkattr;
- u32 cmdarg;
- u32 xfertyp;
- u32 cmdrsp0;
- u32 cmdrsp1;
- u32 cmdrsp2;
- u32 cmdrsp3;
- u32 datport;
- u32 prsstat;
- u32 proctl;
- u32 sysctl;
- u32 irqstat;
- u32 irqstaten;
- u32 irqsigen;
- u32 autoc12err;
- u32 hostcapblt;
- u32 wml;
- u32 mixctrl;
- char reserved1[4];
- u32 fevt;
- char reserved2[168];
- u32 hostver;
-};
+#define IMX_SDHCI_WML 0x44
+#define IMX_SDHCI_MIXCTRL 0x48
struct fsl_esdhc_host {
struct mci_host mci;
- struct fsl_esdhc __iomem *regs;
- unsigned long cur_clock;
+ void __iomem *regs;
struct device_d *dev;
struct clk *clk;
};
@@ -81,34 +58,34 @@ static u32 esdhc_xfertyp(struct mci_cmd *cmd, struct mci_data *data)
u32 xfertyp = 0;
if (data) {
- xfertyp |= XFERTYP_DPSEL;
+ xfertyp |= COMMAND_DPSEL;
#ifndef CONFIG_MCI_IMX_ESDHC_PIO
- xfertyp |= XFERTYP_DMAEN;
+ xfertyp |= TRANSFER_MODE_DMAEN;
#endif
if (data->blocks > 1) {
- xfertyp |= XFERTYP_MSBSEL;
- xfertyp |= XFERTYP_BCEN;
+ xfertyp |= TRANSFER_MODE_MSBSEL;
+ xfertyp |= TRANSFER_MODE_BCEN;
}
if (data->flags & MMC_DATA_READ)
- xfertyp |= XFERTYP_DTDSEL;
+ xfertyp |= TRANSFER_MODE_DTDSEL;
}
if (cmd->resp_type & MMC_RSP_CRC)
- xfertyp |= XFERTYP_CCCEN;
+ xfertyp |= COMMAND_CCCEN;
if (cmd->resp_type & MMC_RSP_OPCODE)
- xfertyp |= XFERTYP_CICEN;
+ xfertyp |= COMMAND_CICEN;
if (cmd->resp_type & MMC_RSP_136)
- xfertyp |= XFERTYP_RSPTYP_136;
+ xfertyp |= COMMAND_RSPTYP_136;
else if (cmd->resp_type & MMC_RSP_BUSY)
- xfertyp |= XFERTYP_RSPTYP_48_BUSY;
+ xfertyp |= COMMAND_RSPTYP_48_BUSY;
else if (cmd->resp_type & MMC_RSP_PRESENT)
- xfertyp |= XFERTYP_RSPTYP_48;
+ xfertyp |= COMMAND_RSPTYP_48;
if ((cpu_is_mx51() || cpu_is_mx53()) &&
cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
xfertyp |= SDHCI_CMD_ABORTCMD;
- return XFERTYP_CMD(cmd->cmdidx) | xfertyp;
+ return COMMAND_CMD(cmd->cmdidx) | xfertyp;
}
#ifdef CONFIG_MCI_IMX_ESDHC_PIO
@@ -119,7 +96,7 @@ static void
esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
{
struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
- struct fsl_esdhc *regs = host->regs;
+ void __iomem *regs = host->regs;
u32 blocks;
char *buffer;
u32 databuf;
@@ -133,8 +110,8 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
while (blocks) {
timeout = PIO_TIMEOUT;
size = data->blocksize;
- irqstat = esdhc_read32(&regs->irqstat);
- while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BREN)
+ irqstat = esdhc_read32(regs + SDHCI_INT_STATUS);
+ while (!(esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_BREN)
&& --timeout);
if (timeout <= 0) {
printf("\nData Read Failed in PIO Mode.");
@@ -142,8 +119,8 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
}
while (size && (!(irqstat & IRQSTAT_TC))) {
udelay(100); /* Wait before last byte transfer complete */
- irqstat = esdhc_read32(&regs->irqstat);
- databuf = esdhc_read32(&regs->datport);
+ irqstat = esdhc_read32(regs + SDHCI_INT_STATUS);
+ databuf = esdhc_read32(regs + SDHCI_BUFFER);
*((u32 *)buffer) = databuf;
buffer += 4;
size -= 4;
@@ -156,8 +133,8 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
while (blocks) {
timeout = PIO_TIMEOUT;
size = data->blocksize;
- irqstat = esdhc_read32(&regs->irqstat);
- while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BWEN)
+ irqstat = esdhc_read32(regs + SDHCI_INT_STATUS);
+ while (!(esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_BWEN)
&& --timeout);
if (timeout <= 0) {
printf("\nData Write Failed in PIO Mode.");
@@ -168,8 +145,8 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
databuf = *((u32 *)buffer);
buffer += 4;
size -= 4;
- irqstat = esdhc_read32(&regs->irqstat);
- esdhc_write32(&regs->datport, databuf);
+ irqstat = esdhc_read32(regs + SDHCI_INT_STATUS);
+ esdhc_write32(regs+ SDHCI_BUFFER, databuf);
}
blocks--;
}
@@ -180,7 +157,7 @@ esdhc_pio_read_write(struct mci_host *mci, struct mci_data *data)
static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data)
{
struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
- struct fsl_esdhc __iomem *regs = host->regs;
+ void __iomem *regs = host->regs;
#ifndef CONFIG_MCI_IMX_ESDHC_PIO
u32 wml_value;
@@ -190,33 +167,33 @@ static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data)
if (wml_value > 0x10)
wml_value = 0x10;
- esdhc_clrsetbits32(&regs->wml, WML_RD_WML_MASK, wml_value);
- esdhc_write32(&regs->dsaddr, (u32)data->dest);
+ esdhc_clrsetbits32(regs + IMX_SDHCI_WML, WML_RD_WML_MASK, wml_value);
+ esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->dest);
} else {
if (wml_value > 0x80)
wml_value = 0x80;
- if ((esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL) == 0) {
+ if ((esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL) == 0) {
printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
return -ETIMEDOUT;
}
- esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
+ esdhc_clrsetbits32(regs + IMX_SDHCI_WML, WML_WR_WML_MASK,
wml_value << 16);
- esdhc_write32(&regs->dsaddr, (u32)data->src);
+ esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->src);
}
#else /* CONFIG_MCI_IMX_ESDHC_PIO */
if (!(data->flags & MMC_DATA_READ)) {
- if ((esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL) == 0) {
+ if ((esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL) == 0) {
printf("\nThe SD card is locked. "
"Can not write to a locked card.\n\n");
return -ETIMEDOUT;
}
- esdhc_write32(&regs->dsaddr, (u32)data->src);
+ esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->src);
} else
- esdhc_write32(&regs->dsaddr, (u32)data->dest);
+ esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->dest);
#endif /* CONFIG_MCI_IMX_ESDHC_PIO */
- esdhc_write32(&regs->blkattr, data->blocks << 16 | data->blocksize);
+ esdhc_write32(regs + SDHCI_BLOCK_SIZE__BLOCK_COUNT, data->blocks << 16 | data->blocksize);
return 0;
}
@@ -232,10 +209,10 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
u32 xfertyp, mixctrl;
u32 irqstat;
struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
- struct fsl_esdhc __iomem *regs = host->regs;
+ void __iomem *regs = host->regs;
int ret;
- esdhc_write32(&regs->irqstat, -1);
+ esdhc_write32(regs + SDHCI_INT_STATUS, -1);
/* Wait at least 8 SD clock cycles before the next command */
udelay(1);
@@ -260,28 +237,28 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
xfertyp = esdhc_xfertyp(cmd, data);
/* Send the command */
- esdhc_write32(&regs->cmdarg, cmd->cmdarg);
+ esdhc_write32(regs + SDHCI_ARGUMENT, cmd->cmdarg);
if (cpu_is_mx6()) {
/* write lower-half of xfertyp to mixctrl */
mixctrl = xfertyp & 0xFFFF;
/* Keep the bits 22-25 of the register as is */
- mixctrl |= (esdhc_read32(&regs->mixctrl) & (0xF << 22));
- esdhc_write32(&regs->mixctrl, mixctrl);
+ mixctrl |= (esdhc_read32(regs + IMX_SDHCI_MIXCTRL) & (0xF << 22));
+ esdhc_write32(regs + IMX_SDHCI_MIXCTRL, mixctrl);
}
- esdhc_write32(&regs->xfertyp, xfertyp);
+ esdhc_write32(regs + SDHCI_TRANSFER_MODE__COMMAND, xfertyp);
/* Wait for the command to complete */
ret = wait_on_timeout(100 * MSECOND,
- esdhc_read32(&regs->irqstat) & IRQSTAT_CC);
+ esdhc_read32(regs + SDHCI_INT_STATUS) & IRQSTAT_CC);
if (ret) {
dev_dbg(host->dev, "timeout 1\n");
return -ETIMEDOUT;
}
- irqstat = esdhc_read32(&regs->irqstat);
- esdhc_write32(&regs->irqstat, irqstat);
+ irqstat = esdhc_read32(regs + SDHCI_INT_STATUS);
+ esdhc_write32(regs + SDHCI_INT_STATUS, irqstat);
if (irqstat & CMD_ERR)
return -EIO;
@@ -293,16 +270,16 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
if (cmd->resp_type & MMC_RSP_136) {
u32 cmdrsp3, cmdrsp2, cmdrsp1, cmdrsp0;
- cmdrsp3 = esdhc_read32(&regs->cmdrsp3);
- cmdrsp2 = esdhc_read32(&regs->cmdrsp2);
- cmdrsp1 = esdhc_read32(&regs->cmdrsp1);
- cmdrsp0 = esdhc_read32(&regs->cmdrsp0);
+ cmdrsp3 = esdhc_read32(regs + SDHCI_RESPONSE_3);
+ cmdrsp2 = esdhc_read32(regs + SDHCI_RESPONSE_2);
+ cmdrsp1 = esdhc_read32(regs + SDHCI_RESPONSE_1);
+ cmdrsp0 = esdhc_read32(regs + SDHCI_RESPONSE_0);
cmd->response[0] = (cmdrsp3 << 8) | (cmdrsp2 >> 24);
cmd->response[1] = (cmdrsp2 << 8) | (cmdrsp1 >> 24);
cmd->response[2] = (cmdrsp1 << 8) | (cmdrsp0 >> 24);
cmd->response[3] = (cmdrsp0 << 8);
} else
- cmd->response[0] = esdhc_read32(&regs->cmdrsp0);
+ cmd->response[0] = esdhc_read32(regs + SDHCI_RESPONSE_0);
/* Wait until all of the blocks are transferred */
if (data) {
@@ -310,7 +287,7 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
esdhc_pio_read_write(mci, data);
#else
do {
- irqstat = esdhc_read32(&regs->irqstat);
+ irqstat = esdhc_read32(regs + SDHCI_INT_STATUS);
if (irqstat & DATA_ERR)
return -EIO;
@@ -318,7 +295,7 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
if (irqstat & IRQSTAT_DTOE)
return -ETIMEDOUT;
} while (!(irqstat & IRQSTAT_TC) &&
- (esdhc_read32(&regs->prsstat) & PRSSTAT_DLA));
+ (esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_DLA));
if (data->flags & MMC_DATA_READ) {
dma_inv_range((unsigned long)data->dest,
@@ -327,11 +304,11 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
#endif
}
- esdhc_write32(&regs->irqstat, -1);
+ esdhc_write32(regs + SDHCI_INT_STATUS, -1);
/* Wait for the bus to be idle */
ret = wait_on_timeout(SECOND,
- !(esdhc_read32(&regs->prsstat) &
+ !(esdhc_read32(regs + SDHCI_PRESENT_STATE) &
(PRSSTAT_CICHB | PRSSTAT_CIDHB)));
if (ret) {
dev_err(host->dev, "timeout 2\n");
@@ -339,7 +316,7 @@ esdhc_send_cmd(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
}
ret = wait_on_timeout(100 * MSECOND,
- !(esdhc_read32(&regs->prsstat) & PRSSTAT_DLA));
+ !(esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_DLA));
if (ret) {
dev_err(host->dev, "timeout 3\n");
return -ETIMEDOUT;
@@ -352,63 +329,78 @@ static void set_sysctl(struct mci_host *mci, u32 clock)
{
int div, pre_div;
struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
- struct fsl_esdhc __iomem *regs = host->regs;
+ void __iomem *regs = host->regs;
int sdhc_clk = clk_get_rate(host->clk);
u32 clk;
-
- if (clock < mci->f_min)
- clock = mci->f_min;
-
- pre_div = 0;
-
- for (pre_div = 1; pre_div < 256; pre_div <<= 1) {
- if (sdhc_clk / pre_div < clock * 16)
+ unsigned long cur_clock;
+
+ /*
+ * With eMMC and imx53 (sdhc_clk=200MHz) a pre_div of 1 results in
+ * pre_div=1,div=4 (=50MHz)
+ * which is valid and should work, but somehow doesn't.
+ * Starting with pre_div=2 gives
+ * pre_div=2, div=2 (=50MHz)
+ * and works fine.
+ */
+ pre_div = 2;
+
+ if (sdhc_clk == clock)
+ pre_div = 1;
+ else if (sdhc_clk / 16 > clock)
+ for (; pre_div < 256; pre_div *= 2)
+ if ((sdhc_clk / pre_div) <= (clock * 16))
+ break;
+
+ for (div = 1; div <= 16; div++)
+ if ((sdhc_clk / (div * pre_div)) <= clock)
break;
- };
- div = sdhc_clk / pre_div / clock;
+ cur_clock = sdhc_clk / pre_div / div;
- if (sdhc_clk / pre_div / div > clock)
- div++;
-
- host->cur_clock = sdhc_clk / pre_div / div;
+ dev_dbg(host->dev, "set clock: wanted: %d got: %ld\n", clock, cur_clock);
+ dev_dbg(host->dev, "pre_div: %d div: %d\n", pre_div, div);
+ /* the register values start with 0 */
div -= 1;
pre_div >>= 1;
- dev_dbg(host->dev, "set clock: wanted: %d got: %ld\n", clock, host->cur_clock);
- dev_dbg(host->dev, "pre_div: %d div: %d\n", pre_div, div);
-
clk = (pre_div << 8) | (div << 4);
- esdhc_clrbits32(&regs->sysctl, SYSCTL_CKEN);
+ esdhc_clrbits32(regs + SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ SYSCTL_CKEN);
- esdhc_clrsetbits32(&regs->sysctl, SYSCTL_CLOCK_MASK, clk);
+ esdhc_clrsetbits32(regs + SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ SYSCTL_CLOCK_MASK, clk);
- udelay(10000);
+ wait_on_timeout(10 * MSECOND,
+ !(esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_SDSTB));
clk = SYSCTL_PEREN | SYSCTL_CKEN;
- esdhc_setbits32(&regs->sysctl, clk);
+ esdhc_setbits32(regs + SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ clk);
}
static void esdhc_set_ios(struct mci_host *mci, struct mci_ios *ios)
{
struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
- struct fsl_esdhc __iomem *regs = host->regs;
+ void __iomem *regs = host->regs;
/* Set the clock speed */
set_sysctl(mci, ios->clock);
/* Set the bus width */
- esdhc_clrbits32(&regs->proctl, PROCTL_DTW_4 | PROCTL_DTW_8);
+ esdhc_clrbits32(regs + SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL,
+ PROCTL_DTW_4 | PROCTL_DTW_8);
switch (ios->bus_width) {
case MMC_BUS_WIDTH_4:
- esdhc_setbits32(&regs->proctl, PROCTL_DTW_4);
+ esdhc_setbits32(regs + SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL,
+ PROCTL_DTW_4);
break;
case MMC_BUS_WIDTH_8:
- esdhc_setbits32(&regs->proctl, PROCTL_DTW_8);
+ esdhc_setbits32(regs + SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL,
+ PROCTL_DTW_8);
break;
case MMC_BUS_WIDTH_1:
break;
@@ -421,7 +413,7 @@ static void esdhc_set_ios(struct mci_host *mci, struct mci_ios *ios)
static int esdhc_card_present(struct mci_host *mci)
{
struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
- struct fsl_esdhc __iomem *regs = host->regs;
+ void __iomem *regs = host->regs;
struct esdhc_platform_data *pdata = host->dev->platform_data;
int ret;
@@ -433,7 +425,7 @@ static int esdhc_card_present(struct mci_host *mci)
case ESDHC_CD_PERMANENT:
return 1;
case ESDHC_CD_CONTROLLER:
- return !(esdhc_read32(&regs->prsstat) & PRSSTAT_WPSPL);
+ return !(esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL);
case ESDHC_CD_GPIO:
ret = gpio_direction_input(pdata->cd_gpio);
if (ret)
@@ -447,45 +439,52 @@ static int esdhc_card_present(struct mci_host *mci)
static int esdhc_init(struct mci_host *mci, struct device_d *dev)
{
struct fsl_esdhc_host *host = to_fsl_esdhc(mci);
- struct fsl_esdhc __iomem *regs = host->regs;
+ void __iomem *regs = host->regs;
int timeout = 1000;
int ret = 0;
/* Reset the entire host controller */
- esdhc_write32(&regs->sysctl, SYSCTL_RSTA);
+ esdhc_write32(regs + SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ SYSCTL_RSTA);
/* Wait until the controller is available */
- while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTA) && --timeout)
+ while ((esdhc_read32(regs + SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET)
+ & SYSCTL_RSTA) && --timeout)
udelay(1000);
- esdhc_write32(&regs->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN);
+ esdhc_write32(regs + SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ SYSCTL_HCKEN | SYSCTL_IPGEN);
/* Set the initial clock speed */
set_sysctl(mci, 400000);
/* Disable the BRR and BWR bits in IRQSTAT */
- esdhc_clrbits32(&regs->irqstaten, IRQSTATEN_BRR | IRQSTATEN_BWR);
+ esdhc_clrbits32(regs + SDHCI_INT_ENABLE, IRQSTATEN_BRR | IRQSTATEN_BWR);
/* Put the PROCTL reg back to the default */
- esdhc_write32(&regs->proctl, PROCTL_INIT);
+ esdhc_write32(regs + SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL,
+ PROCTL_INIT);
/* Set timout to the maximum value */
- esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
+ esdhc_clrsetbits32(regs + SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ SYSCTL_TIMEOUT_MASK, 14 << 16);
return ret;
}
-static int esdhc_reset(struct fsl_esdhc __iomem *regs)
+static int esdhc_reset(void __iomem *regs)
{
uint64_t start;
/* reset the controller */
- esdhc_write32(&regs->sysctl, SYSCTL_RSTA);
+ esdhc_write32(regs + SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ SYSCTL_RSTA);
start = get_time_ns();
/* hardware clears the bit when it is done */
while (1) {
- if (!(esdhc_read32(&regs->sysctl) & SYSCTL_RSTA))
+ if (!(esdhc_read32(regs + SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET)
+ & SYSCTL_RSTA))
break;
if (is_timeout(start, 100 * MSECOND)) {
printf("MMC/SD: Reset never completed.\n");
@@ -496,6 +495,13 @@ static int esdhc_reset(struct fsl_esdhc __iomem *regs)
return 0;
}
+static int fsl_esdhc_detect(struct device_d *dev)
+{
+ struct fsl_esdhc_host *host = dev->priv;
+
+ return mci_detect_card(&host->mci);
+}
+
static int fsl_esdhc_probe(struct device_d *dev)
{
struct fsl_esdhc_host *host;
@@ -522,7 +528,7 @@ static int fsl_esdhc_probe(struct device_d *dev)
return ret;
}
- caps = esdhc_read32(&host->regs->hostcapblt);
+ caps = esdhc_read32(host->regs + SDHCI_CAPABILITIES);
if (caps & ESDHC_HOSTCAPBLT_VS18)
mci->voltages |= MMC_VDD_165_195;
@@ -536,8 +542,13 @@ static int fsl_esdhc_probe(struct device_d *dev)
else
mci->host_caps = MMC_MODE_4BIT;
- if (pdata && pdata->devname)
+ if (pdata && pdata->devname) {
mci->devname = pdata->devname;
+ } else if (dev->device_node) {
+ const char *alias = of_alias_get(dev->device_node);
+ if (alias)
+ mci->devname = xstrdup(alias);
+ }
if (caps & ESDHC_HOSTCAPBLT_HSS)
mci->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
@@ -548,15 +559,19 @@ static int fsl_esdhc_probe(struct device_d *dev)
host->mci.card_present = esdhc_card_present;
host->mci.hw_dev = dev;
+ dev->detect = fsl_esdhc_detect,
+
rate = clk_get_rate(host->clk);
host->mci.f_min = rate >> 12;
if (host->mci.f_min < 200000)
host->mci.f_min = 200000;
host->mci.f_max = rate;
- mci_register(&host->mci);
+ mci_of_parse(&host->mci);
- return 0;
+ dev->priv = host;
+
+ return mci_register(&host->mci);
}
static __maybe_unused struct of_device_id fsl_esdhc_compatible[] = {
diff --git a/drivers/mci/imx-esdhc.h b/drivers/mci/imx-esdhc.h
index 2be63a5ba0..ea1cb318e5 100644
--- a/drivers/mci/imx-esdhc.h
+++ b/drivers/mci/imx-esdhc.h
@@ -25,8 +25,6 @@
#include <errno.h>
#include <asm/byteorder.h>
-/* FSL eSDHC-specific constants */
-#define SYSCTL 0x0002e02c
#define SYSCTL_INITA 0x08000000
#define SYSCTL_TIMEOUT_MASK 0x000f0000
#define SYSCTL_CLOCK_MASK 0x0000fff0
@@ -36,104 +34,17 @@
#define SYSCTL_HCKEN 0x00000002
#define SYSCTL_IPGEN 0x00000001
-#define IRQSTAT 0x0002e030
-#define IRQSTAT_DMAE (0x10000000)
-#define IRQSTAT_AC12E (0x01000000)
-#define IRQSTAT_DEBE (0x00400000)
-#define IRQSTAT_DCE (0x00200000)
-#define IRQSTAT_DTOE (0x00100000)
-#define IRQSTAT_CIE (0x00080000)
-#define IRQSTAT_CEBE (0x00040000)
-#define IRQSTAT_CCE (0x00020000)
-#define IRQSTAT_CTOE (0x00010000)
-#define IRQSTAT_CINT (0x00000100)
-#define IRQSTAT_CRM (0x00000080)
-#define IRQSTAT_CINS (0x00000040)
-#define IRQSTAT_BRR (0x00000020)
-#define IRQSTAT_BWR (0x00000010)
-#define IRQSTAT_DINT (0x00000008)
-#define IRQSTAT_BGE (0x00000004)
-#define IRQSTAT_TC (0x00000002)
-#define IRQSTAT_CC (0x00000001)
-
#define CMD_ERR (IRQSTAT_CIE | IRQSTAT_CEBE | IRQSTAT_CCE)
#define DATA_ERR (IRQSTAT_DEBE | IRQSTAT_DCE | IRQSTAT_DTOE)
-#define IRQSTATEN 0x0002e034
-#define IRQSTATEN_DMAE (0x10000000)
-#define IRQSTATEN_AC12E (0x01000000)
-#define IRQSTATEN_DEBE (0x00400000)
-#define IRQSTATEN_DCE (0x00200000)
-#define IRQSTATEN_DTOE (0x00100000)
-#define IRQSTATEN_CIE (0x00080000)
-#define IRQSTATEN_CEBE (0x00040000)
-#define IRQSTATEN_CCE (0x00020000)
-#define IRQSTATEN_CTOE (0x00010000)
-#define IRQSTATEN_CINT (0x00000100)
-#define IRQSTATEN_CRM (0x00000080)
-#define IRQSTATEN_CINS (0x00000040)
-#define IRQSTATEN_BRR (0x00000020)
-#define IRQSTATEN_BWR (0x00000010)
-#define IRQSTATEN_DINT (0x00000008)
-#define IRQSTATEN_BGE (0x00000004)
-#define IRQSTATEN_TC (0x00000002)
-#define IRQSTATEN_CC (0x00000001)
-
-#define PRSSTAT 0x0002e024
-#define PRSSTAT_CLSL (0x00800000)
-#define PRSSTAT_WPSPL (0x00080000)
-#define PRSSTAT_CDPL (0x00040000)
-#define PRSSTAT_CINS (0x00010000)
-#define PRSSTAT_BREN (0x00000800)
-#define PRSSTAT_BWEN (0x00000400)
-#define PRSSTAT_DLA (0x00000004)
-#define PRSSTAT_CICHB (0x00000002)
-#define PRSSTAT_CIDHB (0x00000001)
-
-#define PROCTL 0x0002e028
#define PROCTL_INIT 0x00000020
#define PROCTL_DTW_4 0x00000002
#define PROCTL_DTW_8 0x00000004
-#define CMDARG 0x0002e008
-
-#define XFERTYP 0x0002e00c
-#define XFERTYP_CMD(x) ((x & 0x3f) << 24)
-#define XFERTYP_CMDTYP_NORMAL 0x0
-#define XFERTYP_CMDTYP_SUSPEND 0x00400000
-#define XFERTYP_CMDTYP_RESUME 0x00800000
-#define XFERTYP_CMDTYP_ABORT 0x00c00000
-#define XFERTYP_DPSEL 0x00200000
-#define XFERTYP_CICEN 0x00100000
-#define XFERTYP_CCCEN 0x00080000
-#define XFERTYP_RSPTYP_NONE 0
-#define XFERTYP_RSPTYP_136 0x00010000
-#define XFERTYP_RSPTYP_48 0x00020000
-#define XFERTYP_RSPTYP_48_BUSY 0x00030000
-#define XFERTYP_MSBSEL 0x00000020
-#define XFERTYP_DTDSEL 0x00000010
-#define XFERTYP_AC12EN 0x00000004
-#define XFERTYP_BCEN 0x00000002
-#define XFERTYP_DMAEN 0x00000001
-
-#define CINS_TIMEOUT 1000
-#define PIO_TIMEOUT 100000
-
-#define DSADDR 0x2e004
-
-#define CMDRSP0 0x2e010
-#define CMDRSP1 0x2e014
-#define CMDRSP2 0x2e018
-#define CMDRSP3 0x2e01c
-
-#define DATPORT 0x2e020
-
-#define WML 0x2e044
#define WML_WRITE 0x00010000
#define WML_RD_WML_MASK 0xff
#define WML_WR_WML_MASK 0xff0000
-#define BLKATTR 0x2e004
#define BLKATTR_CNT(x) ((x & 0xffff) << 16)
#define BLKATTR_SIZE(x) (x & 0x1fff)
#define MAX_BLK_CNT 0x7fff /* so malloc will have enough room with 32M */
diff --git a/drivers/mci/imx.c b/drivers/mci/imx.c
index c98596434e..2bf48eb1d3 100644
--- a/drivers/mci/imx.c
+++ b/drivers/mci/imx.c
@@ -2,7 +2,7 @@
* This is a driver for the SDHC controller found in Freescale MX2/MX3
* SoCs. It is basically the same hardware as found on MX1 (imxmmc.c).
* Unlike the hardware found on MX1, this hardware just works and does
- * not need all the quirks found in imxmmc.c, hence the seperate driver.
+ * not need all the quirks found in imxmmc.c, hence the separate driver.
*
* Copyright (C) 2009 Ilya Yanok, <yanok@emcraft.com>
* Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
diff --git a/drivers/mci/mci-bcm2835.c b/drivers/mci/mci-bcm2835.c
new file mode 100644
index 0000000000..b76f134af2
--- /dev/null
+++ b/drivers/mci/mci-bcm2835.c
@@ -0,0 +1,591 @@
+/*
+ * Raspberry PI MCI driver
+ *
+ * Support for SDHCI device on bcm2835
+ * Based on sdhci-bcm2708.c (c) 2010 Broadcom
+ * Inspired by bcm2835_sdhci.c from git://github.com/gonzoua/u-boot-pi.git
+ *
+ * Portions (e.g. read/write macros, concepts for back-to-back register write
+ * timing workarounds) obviously extracted from the Linux kernel at:
+ * https://github.com/raspberrypi/linux.git rpi-3.6.y
+ *
+ * The Linux kernel code has the following (c) and license, which is hence
+ * propagated to here:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Author: Wilhelm Lundgren <wilhelm.lundgren@cybercom.com>
+ */
+
+#include <common.h>
+#include <init.h>
+#include <mci.h>
+#include <io.h>
+#include <malloc.h>
+#include <clock.h>
+#include "mci-bcm2835.h"
+#include "sdhci.h"
+
+#define to_bcm2835_host(h) container_of(h, struct bcm2835_mci_host, mci)
+static int twoticks_delay;
+struct bcm2835_mci_host {
+ struct mci_host mci;
+ void __iomem *regs;
+ struct device_d *hw_dev;
+ int bus_width;
+ u32 clock;
+ u32 max_clock;
+ u32 version;
+ uint64_t last_write;
+};
+
+void bcm2835_mci_write(struct bcm2835_mci_host *host, u32 reg, u32 val)
+{
+ /*
+ * The Arasan has a bugette whereby it may lose the content of
+ * successive writes to registers that are within two SD-card clock
+ * cycles of each other (a clock domain crossing problem).
+ * It seems, however, that the data register does not have this problem.
+ * (Which is just as well - otherwise we'd have to nobble the DMA engine
+ * too)
+ */
+
+ if (host->last_write != 0)
+ while ((get_time_ns() - host->last_write) < twoticks_delay)
+ ;
+ host->last_write = get_time_ns();
+ writel(val, host->regs + reg);
+}
+
+u32 bcm2835_mci_read(struct bcm2835_mci_host *host, u32 reg)
+{
+ return readl(host->regs + reg);
+}
+
+/* Create special write data function since the data
+ * register is not affected by the twoticks_delay bug
+ * and we can thus get better speed here
+ */
+void bcm2835_mci_write_data(struct bcm2835_mci_host *host, u32 *p)
+{
+ writel(*p, host->regs + SDHCI_BUFFER);
+}
+
+/* Make a read data functions as well just to keep structure */
+void bcm2835_mci_read_data(struct bcm2835_mci_host *host, u32 *p)
+{
+ *p = readl(host->regs + SDHCI_BUFFER);
+}
+
+static int bcm2835_mci_transfer_data(struct bcm2835_mci_host *host,
+ struct mci_cmd *cmd, struct mci_data *data) {
+ u32 *p;
+ u32 data_size, status, intr_status = 0;
+ u32 data_ready_intr_mask;
+ u32 data_ready_status_mask;
+ int i = 0;
+ void (*read_write_func)(struct bcm2835_mci_host*, u32*);
+
+ data_size = data->blocksize * data->blocks;
+
+ if (data->flags & MMC_DATA_READ) {
+ p = (u32 *) data->dest;
+ data_ready_intr_mask = IRQSTAT_BRR;
+ data_ready_status_mask = PRSSTAT_BREN;
+ read_write_func = &bcm2835_mci_read_data;
+ } else {
+ p = (u32 *) data->src;
+ data_ready_intr_mask = IRQSTAT_BWR;
+ data_ready_status_mask = PRSSTAT_BWEN;
+ read_write_func = &bcm2835_mci_write_data;
+ }
+ do {
+ intr_status = bcm2835_mci_read(host, SDHCI_INT_STATUS);
+ if (intr_status & IRQSTAT_CIE) {
+ dev_err(host->hw_dev,
+ "Error occured while transferring data: 0x%X\n",
+ intr_status);
+ return -EPERM;
+ }
+ if (intr_status & data_ready_intr_mask) {
+ status = bcm2835_mci_read(host, SDHCI_PRESENT_STATE);
+ if ((status & data_ready_status_mask) == 0)
+ continue;
+ /*Clear latest int and transfer one block size of data*/
+ bcm2835_mci_write(host, SDHCI_INT_STATUS,
+ data_ready_intr_mask);
+ for (i = 0; i < data->blocksize; i += 4) {
+ read_write_func(host, p);
+ p++;
+ data_size -= 4;
+ }
+ }
+ } while ((intr_status & IRQSTAT_TC) == 0);
+
+ if (data_size != 0) {
+ if (data->flags & MMC_DATA_READ)
+ dev_err(host->hw_dev, "Error while reading:\n");
+ else
+ dev_err(host->hw_dev, "Error while writing:\n");
+
+ dev_err(host->hw_dev, "Transferred %d bytes of data, wanted %d\n",
+ (data->blocksize * data->blocks) - data_size,
+ data->blocksize * data->blocks);
+
+ dev_err(host->hw_dev, "Status: 0x%X, Interrupt: 0x%X\n",
+ bcm2835_mci_read(host, SDHCI_PRESENT_STATE),
+ bcm2835_mci_read(host, SDHCI_INT_STATUS));
+
+ return -EPERM;
+ }
+ return 0;
+}
+
+static u32 bcm2835_mci_wait_command_done(struct bcm2835_mci_host *host)
+{
+ u32 interrupt = 0;
+
+ while (true) {
+ interrupt = bcm2835_mci_read(
+ host, SDHCI_INT_STATUS);
+ if (interrupt & IRQSTAT_CIE)
+ return -EPERM;
+ if (interrupt & IRQSTAT_CC)
+ break;
+ }
+ return 0;
+}
+
+static void bcm2835_mci_reset_emmc(struct bcm2835_mci_host *host, u32 reset,
+ u32 wait_for)
+{
+ u32 ret;
+ u32 current = bcm2835_mci_read(host,
+ SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET);
+
+ bcm2835_mci_write(host,
+ SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ current | reset);
+
+ while (true) {
+ ret = bcm2835_mci_read(host,
+ SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET);
+ if (ret & wait_for)
+ continue;
+ break;
+ }
+}
+
+/**
+ * Process one command to the MCI card
+ * @param host MCI host
+ * @param cmd The command to process
+ * @param data The data to handle in the command (can be NULL)
+ * @return 0 on success, negative value else
+ */
+static int bcm2835_mci_request(struct mci_host *mci, struct mci_cmd *cmd,
+ struct mci_data *data) {
+ u32 command, block_data = 0, ret = 0;
+ u32 wait_inhibit_mask = PRSSTAT_CICHB | PRSSTAT_CIDHB;
+ struct bcm2835_mci_host *host = to_bcm2835_host(mci);
+
+ command = COMMAND_CMD(cmd->cmdidx);
+
+ if (cmd->resp_type != MMC_RSP_NONE) {
+ if (cmd->resp_type & MMC_RSP_136)
+ command |= COMMAND_RSPTYP_136;
+ else if (cmd->resp_type & MMC_RSP_BUSY)
+ command |= COMMAND_RSPTYP_48_BUSY;
+ else
+ command |= COMMAND_RSPTYP_48;
+ if (cmd->resp_type & MMC_RSP_CRC)
+ command |= COMMAND_CCCEN;
+ }
+ if (data != NULL) {
+ command |= COMMAND_DPSEL | TRANSFER_MODE_BCEN;
+
+ if (data->blocks > 1)
+ command |= TRANSFER_MODE_MSBSEL;
+
+ if (data->flags & MMC_DATA_READ)
+ command |= TRANSFER_MODE_DTDSEL;
+
+ block_data = (data->blocks << BLOCK_SHIFT);
+ block_data |= data->blocksize;
+ }
+
+ /* We shouldn't wait for data inihibit for stop commands, even
+ though they might use busy signaling */
+ if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
+ wait_inhibit_mask = PRSSTAT_CICHB;
+
+ /*Wait for old command*/
+ while (bcm2835_mci_read(host, SDHCI_PRESENT_STATE)
+ & wait_inhibit_mask)
+ ;
+
+ bcm2835_mci_write(host, SDHCI_INT_ENABLE, 0xFFFFFFFF);
+ bcm2835_mci_write(host, SDHCI_INT_STATUS, 0xFFFFFFFF);
+
+ bcm2835_mci_write(host, SDHCI_BLOCK_SIZE__BLOCK_COUNT, block_data);
+ bcm2835_mci_write(host, SDHCI_ARGUMENT, cmd->cmdarg);
+ bcm2835_mci_write(host, SDHCI_TRANSFER_MODE__COMMAND, command);
+
+ ret = bcm2835_mci_wait_command_done(host);
+ if (ret) {
+ dev_err(host->hw_dev, "Error while executing command %d\n",
+ cmd->cmdidx);
+ dev_err(host->hw_dev, "Status: 0x%X, Interrupt: 0x%X\n",
+ bcm2835_mci_read(host, SDHCI_PRESENT_STATE),
+ bcm2835_mci_read(host, SDHCI_INT_STATUS));
+ }
+ if (cmd->resp_type != 0 && ret != -1) {
+ int i = 0;
+
+ /* CRC is stripped so we need to do some shifting. */
+ if (cmd->resp_type & MMC_RSP_136) {
+ for (i = 0; i < 4; i++) {
+ cmd->response[i] = bcm2835_mci_read(
+ host,
+ SDHCI_RESPONSE_0 + (3 - i) * 4) << 8;
+ if (i != 3)
+ cmd->response[i] |=
+ readb((u32) (host->regs) +
+ SDHCI_RESPONSE_0 +
+ (3 - i) * 4 - 1);
+ }
+ } else {
+ cmd->response[0] = bcm2835_mci_read(
+ host, SDHCI_RESPONSE_0);
+ }
+ bcm2835_mci_write(host, SDHCI_INT_STATUS,
+ IRQSTAT_CC);
+ }
+
+ if (!ret && data)
+ ret = bcm2835_mci_transfer_data(host, cmd, data);
+
+ bcm2835_mci_write(host, SDHCI_INT_STATUS, 0xFFFFFFFF);
+ if (ret) {
+ bcm2835_mci_reset_emmc(host, CONTROL1_CMDRST,
+ CONTROL1_CMDRST);
+ bcm2835_mci_reset_emmc(host, CONTROL1_DATARST,
+ CONTROL1_DATARST);
+ }
+
+ return ret;
+}
+
+static u32 bcm2835_mci_get_clock_divider(struct bcm2835_mci_host *host,
+ u32 desired_hz)
+{
+ u32 div;
+ u32 clk_hz;
+
+ if (host->version >= SDHCI_SPEC_300) {
+ /* Version 3.00 divisors must be a multiple of 2. */
+ if (host->max_clock <= desired_hz)
+ div = 1;
+ else {
+ for (div = 2; div < MAX_CLK_DIVIDER_V3; div += 2) {
+ clk_hz = host->max_clock / div;
+ if (clk_hz <= desired_hz)
+ break;
+ }
+ }
+ } else {
+ /* Version 2.00 divisors must be a power of 2. */
+ for (div = 1; div < MAX_CLK_DIVIDER_V2; div *= 2) {
+ clk_hz = host->max_clock / div;
+ if (clk_hz <= desired_hz)
+ break;
+ }
+
+ }
+
+ /*Since setting lowest bit means divide by two, shift down*/
+ dev_dbg(host->hw_dev,
+ "Wanted %d hz, returning divider %d (%d) which yields %d hz\n",
+ desired_hz, div >> 1, div, host->max_clock / div);
+ twoticks_delay = ((2 * 1000000000) / (host->max_clock / div)) + 1;
+
+ div = div >> 1;
+ host->clock = desired_hz;
+ return div;
+}
+
+/**
+ * Setup the bus width and IO speed
+ * @param host MCI host
+ * @param bus_width New bus width value (1, 4 or 8)
+ * @param clock New clock in Hz (can be '0' to disable the clock)
+ */
+static void bcm2835_mci_set_ios(struct mci_host *mci, struct mci_ios *ios)
+{
+ u32 divider;
+ u32 divider_msb, divider_lsb;
+ u32 enable;
+ u32 current_val;
+
+ struct bcm2835_mci_host *host = to_bcm2835_host(mci);
+
+ current_val = bcm2835_mci_read(host,
+ SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL);
+
+ switch (ios->bus_width) {
+ case MMC_BUS_WIDTH_4:
+ bcm2835_mci_write(host,
+ SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL,
+ current_val | CONTROL0_4DATA);
+ host->bus_width = 1;
+ dev_dbg(host->hw_dev, "Changing bus width to 4\n");
+ break;
+ case MMC_BUS_WIDTH_1:
+ bcm2835_mci_write(host,
+ SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL,
+ current_val & ~CONTROL0_4DATA);
+ host->bus_width = 0;
+ dev_dbg(host->hw_dev, "Changing bus width to 1\n");
+ break;
+ default:
+ dev_warn(host->hw_dev, "Unsupported width received: %d\n",
+ ios->bus_width);
+ return;
+ }
+ if (ios->clock != host->clock && ios->clock != 0) {
+ bcm2835_mci_write(host,
+ SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ 0x00);
+
+ if (ios->clock > 26000000) {
+ enable = bcm2835_mci_read(host,
+ SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL);
+ enable |= CONTROL0_HISPEED;
+ bcm2835_mci_write(host,
+ SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ enable);
+ }
+
+ divider = bcm2835_mci_get_clock_divider(host, ios->clock);
+ divider_msb = divider & 0x300;
+ divider_msb >>= CONTROL1_CLKLSB;
+ divider_lsb = divider & 0xFF;
+ enable = (divider_lsb << CONTROL1_CLKLSB);
+ enable |= (divider_msb << CONTROL1_CLKMSB);
+ enable |= CONTROL1_INTCLKENA | CONTROL1_TIMEOUT;
+
+ bcm2835_mci_write(host,
+ SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ enable);
+ while (true) {
+ u32 ret = bcm2835_mci_read(host,
+ SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET);
+ if (ret & CONTROL1_CLK_STABLE)
+ break;
+ }
+
+ enable |= CONTROL1_CLKENA;
+ bcm2835_mci_write(host,
+ SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ enable);
+
+ mdelay(100);
+
+ bcm2835_mci_reset_emmc(host, CONTROL1_CMDRST,
+ CONTROL1_CMDRST);
+ bcm2835_mci_reset_emmc(host, CONTROL1_DATARST,
+ CONTROL1_DATARST);
+
+ host->clock = ios->clock;
+ }
+ dev_dbg(host->hw_dev, "IO settings: bus width=%d, frequency=%u Hz\n",
+ host->bus_width, host->clock);
+}
+
+int bcm2835_mci_reset(struct mci_host *mci, struct device_d *mci_dev)
+{
+ struct bcm2835_mci_host *host;
+ u32 ret = 0;
+ u32 reset = CONTROL1_HOSTRST | CONTROL1_CMDRST | CONTROL1_DATARST;
+ u32 enable = 0;
+ u32 divider;
+ u32 divider_msb, divider_lsb;
+
+ host = to_bcm2835_host(mci);
+ divider = bcm2835_mci_get_clock_divider(host, MIN_FREQ);
+ divider_msb = divider & 0x300;
+ divider_msb = divider_msb >> CONTROL1_CLKLSB;
+ divider_lsb = divider & 0xFF;
+
+ enable = (divider_lsb << CONTROL1_CLKLSB);
+ enable |= (divider_msb << CONTROL1_CLKMSB);
+ enable |= CONTROL1_INTCLKENA | CONTROL1_TIMEOUT;
+
+ bcm2835_mci_reset_emmc(host, enable | reset, CONTROL1_HOSTRST);
+
+ bcm2835_mci_write(host,
+ SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL,
+ 0x00);
+ bcm2835_mci_write(host, SDHCI_ACMD12_ERR__HOST_CONTROL2,
+ 0x00);
+ bcm2835_mci_write(host,
+ SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ enable);
+ while (true) {
+ ret = bcm2835_mci_read(host,
+ SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET);
+ if (ret & CONTROL1_CLK_STABLE)
+ break;
+ }
+
+ enable |= CONTROL1_CLKENA;
+ bcm2835_mci_write(host,
+ SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET,
+ enable);
+
+ /*Delay atelast 74 clk cycles for card init*/
+ mdelay(100);
+
+ bcm2835_mci_write(host, SDHCI_INT_ENABLE,
+ 0xFFFFFFFF);
+ bcm2835_mci_write(host, SDHCI_INT_STATUS,
+ 0xFFFFFFFF);
+
+ /*Now write command 0 and see if we get response*/
+ bcm2835_mci_write(host, SDHCI_ARGUMENT, 0x0);
+ bcm2835_mci_write(host, SDHCI_TRANSFER_MODE__COMMAND, 0x0);
+ return bcm2835_mci_wait_command_done(host);
+}
+
+static u32 bcm2835_mci_get_emmc_clock(struct msg_get_clock_rate *clk_data)
+{
+ u32 val;
+ struct bcm2835_mbox_regs *regs =
+ (struct bcm2835_mbox_regs *) BCM2835_MBOX_PHYSADDR;
+
+ /*Read out old msg*/
+ while (true) {
+ val = readl(&regs->status);
+ if (val & BCM2835_MBOX_STATUS_RD_EMPTY)
+ break;
+ val = readl(&regs->read);
+ }
+
+ /*Check for ok to write*/
+ while (true) {
+ val = readl(&regs->status);
+ if (!(val & BCM2835_MBOX_STATUS_WR_FULL))
+ break;
+ }
+ val = BCM2835_MBOX_PROP_CHAN + ((u32) &clk_data->hdr);
+ writel(val, &regs->write);
+
+ while (true) {
+ /* Wait for the response */
+ while (true) {
+ val = readl(&regs->status);
+ if (!(val & BCM2835_MBOX_STATUS_RD_EMPTY))
+ break;
+ }
+
+ /* Read the response */
+ val = readl(&regs->read);
+ if ((val & 0x0F) == BCM2835_MBOX_PROP_CHAN)
+ break;
+ }
+ if ((val & ~0x0F) == ((u32) &clk_data->hdr))
+ if (clk_data->get_clock_rate.tag_hdr.val_len
+ & BCM2835_MBOX_TAG_VAL_LEN_RESPONSE)
+ return 1;
+ return 0;
+}
+
+static int bcm2835_mci_probe(struct device_d *hw_dev)
+{
+ struct bcm2835_mci_host *host;
+ struct msg_get_clock_rate *clk_data;
+
+ host = xzalloc(sizeof(*host));
+ host->mci.send_cmd = bcm2835_mci_request;
+ host->mci.set_ios = bcm2835_mci_set_ios;
+ host->mci.init = bcm2835_mci_reset;
+ host->mci.hw_dev = hw_dev;
+ host->hw_dev = hw_dev;
+
+ /* Allocate a buffer thats 16 bytes aligned in memory
+ * Of the 32 bits address passed into the mbox 28 bits
+ * are the address of the buffer, lower 4 bits is channel
+ */
+ clk_data = memalign(16, sizeof(struct msg_get_clock_rate));
+ memset(clk_data, 0, sizeof(struct msg_get_clock_rate));
+ clk_data->hdr.buf_size = sizeof(struct msg_get_clock_rate);
+ clk_data->get_clock_rate.tag_hdr.tag = BCM2835_MBOX_TAG_GET_CLOCK_RATE;
+ clk_data->get_clock_rate.tag_hdr.val_buf_size =
+ sizeof(clk_data->get_clock_rate.body);
+ clk_data->get_clock_rate.tag_hdr.val_len =
+ sizeof(clk_data->get_clock_rate.body.req);
+ clk_data->get_clock_rate.body.req.clock_id = BCM2835_MBOX_CLOCK_ID_EMMC;
+
+ if (!bcm2835_mci_get_emmc_clock(clk_data)) {
+ dev_warn(host->hw_dev,
+ "Failed getting emmc clock, lets go anyway with 50MHz\n");
+ host->max_clock = 50000000;
+ } else {
+ host->max_clock = clk_data->get_clock_rate.body.resp.rate_hz;
+ dev_info(host->hw_dev, "Got emmc clock at %d Hz\n",
+ host->max_clock);
+ }
+
+ host->regs = dev_request_mem_region(hw_dev, 0);
+ if (host->regs == NULL) {
+ dev_err(host->hw_dev, "Failed request mem region, aborting...\n");
+ return -EBUSY;
+ }
+
+ host->mci.host_caps |= MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HS_52MHz;
+
+ host->mci.voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
+
+ host->mci.f_min = MIN_FREQ;
+ host->mci.f_max = host->max_clock;
+
+ /*
+ * The Arasan has a bugette whereby it may lose the content of
+ * successive writes to registers that are within two SD-card clock
+ * cycles of each other (a clock domain crossing problem).
+ *
+ * 1/MIN_FREQ is (max) time per tick of eMMC clock.
+ * 2/MIN_FREQ is time for two ticks.
+ * Multiply by 1000000000 to get nS per two ticks.
+ * +1 for hack rounding.
+ */
+
+ twoticks_delay = ((2 * 1000000000) / MIN_FREQ) + 1;
+
+ host->version = bcm2835_mci_read(
+ host, BCM2835_MCI_SLOTISR_VER);
+ host->version = (host->version >> 16) & 0xFF;
+ return mci_register(&host->mci);
+}
+
+static struct driver_d bcm2835_mci_driver = {
+ .name = "bcm2835_mci",
+ .probe = bcm2835_mci_probe,
+};
+
+static int bcm2835_mci_add(void)
+{
+ return platform_driver_register(&bcm2835_mci_driver);
+}
+coredevice_initcall(bcm2835_mci_add);
diff --git a/drivers/mci/mci-bcm2835.h b/drivers/mci/mci-bcm2835.h
new file mode 100644
index 0000000000..4158a18065
--- /dev/null
+++ b/drivers/mci/mci-bcm2835.h
@@ -0,0 +1,73 @@
+#define BCM2835_MCI_SLOTISR_VER 0xfc
+
+#define MIN_FREQ 400000
+#define BLOCK_SHIFT 16
+
+#define SDHCI_SPEC_100 0
+#define SDHCI_SPEC_200 1
+#define SDHCI_SPEC_300 2
+
+#define CONTROL0_HISPEED (1 << 2)
+#define CONTROL0_4DATA (1 << 1)
+
+#define CONTROL1_DATARST (1 << 26)
+#define CONTROL1_CMDRST (1 << 25)
+#define CONTROL1_HOSTRST (1 << 24)
+#define CONTROL1_CLKSELPROG (1 << 5)
+#define CONTROL1_CLKENA (1 << 2)
+#define CONTROL1_CLK_STABLE (1 << 1)
+#define CONTROL1_INTCLKENA (1 << 0)
+#define CONTROL1_CLKMSB 6
+#define CONTROL1_CLKLSB 8
+#define CONTROL1_TIMEOUT (0x0E << 16)
+
+#define MAX_CLK_DIVIDER_V3 2046
+#define MAX_CLK_DIVIDER_V2 256
+
+/*this is only for mbox comms*/
+#define BCM2835_MBOX_PHYSADDR 0x2000b880
+#define BCM2835_MBOX_TAG_GET_CLOCK_RATE 0x00030002
+#define BCM2835_MBOX_CLOCK_ID_EMMC 1
+#define BCM2835_MBOX_STATUS_WR_FULL 0x80000000
+#define BCM2835_MBOX_STATUS_RD_EMPTY 0x40000000
+#define BCM2835_MBOX_PROP_CHAN 8
+#define BCM2835_MBOX_TAG_VAL_LEN_RESPONSE 0x80000000
+
+struct bcm2835_mbox_regs {
+ u32 read;
+ u32 rsvd0[5];
+ u32 status;
+ u32 config;
+ u32 write;
+};
+
+
+struct bcm2835_mbox_hdr {
+ u32 buf_size;
+ u32 code;
+};
+
+struct bcm2835_mbox_tag_hdr {
+ u32 tag;
+ u32 val_buf_size;
+ u32 val_len;
+};
+
+struct bcm2835_mbox_tag_get_clock_rate {
+ struct bcm2835_mbox_tag_hdr tag_hdr;
+ union {
+ struct {
+ u32 clock_id;
+ } req;
+ struct {
+ u32 clock_id;
+ u32 rate_hz;
+ } resp;
+ } body;
+};
+
+struct msg_get_clock_rate {
+ struct bcm2835_mbox_hdr hdr;
+ struct bcm2835_mbox_tag_get_clock_rate get_clock_rate;
+ u32 end_tag;
+};
diff --git a/drivers/mci/mci-core.c b/drivers/mci/mci-core.c
index 90ac2a3748..ce568df706 100644
--- a/drivers/mci/mci-core.c
+++ b/drivers/mci/mci-core.c
@@ -215,7 +215,7 @@ static int mci_go_idle(struct mci *mci)
err = mci_send_cmd(mci, &cmd, NULL);
if (err) {
- dev_dbg(mci->mci_dev, "Activating IDLE state failed: %d\n", err);
+ dev_dbg(&mci->dev, "Activating IDLE state failed: %d\n", err);
return err;
}
@@ -252,7 +252,7 @@ static int sd_send_op_cond(struct mci *mci)
mci_setup_cmd(&cmd, MMC_CMD_APP_CMD, 0, MMC_RSP_R1);
err = mci_send_cmd(mci, &cmd, NULL);
if (err) {
- dev_dbg(mci->mci_dev, "Preparing SD for operating conditions failed: %d\n", err);
+ dev_dbg(&mci->dev, "Preparing SD for operating conditions failed: %d\n", err);
return err;
}
@@ -264,7 +264,7 @@ static int sd_send_op_cond(struct mci *mci)
mci_setup_cmd(&cmd, SD_CMD_APP_SEND_OP_COND, arg, MMC_RSP_R3);
err = mci_send_cmd(mci, &cmd, NULL);
if (err) {
- dev_dbg(mci->mci_dev, "SD operation condition set failed: %d\n", err);
+ dev_dbg(&mci->dev, "SD operation condition set failed: %d\n", err);
return err;
}
udelay(1000);
@@ -277,7 +277,7 @@ static int sd_send_op_cond(struct mci *mci)
} while (busy && timeout--);
if (timeout <= 0) {
- dev_dbg(mci->mci_dev, "SD operation condition set timed out\n");
+ dev_dbg(&mci->dev, "SD operation condition set timed out\n");
return -ENODEV;
}
@@ -320,7 +320,7 @@ static int mmc_send_op_cond(struct mci *mci)
err = mci_send_cmd(mci, &cmd, NULL);
if (err) {
- dev_dbg(mci->mci_dev, "Preparing MMC for operating conditions failed: %d\n", err);
+ dev_dbg(&mci->dev, "Preparing MMC for operating conditions failed: %d\n", err);
return err;
}
@@ -328,7 +328,7 @@ static int mmc_send_op_cond(struct mci *mci)
} while (!(cmd.response[0] & OCR_BUSY) && timeout--);
if (timeout <= 0) {
- dev_dbg(mci->mci_dev, "SD operation condition set timed out\n");
+ dev_dbg(&mci->dev, "SD operation condition set timed out\n");
return -ENODEV;
}
@@ -388,6 +388,35 @@ static int mci_switch(struct mci *mci, unsigned set, unsigned index,
return mci_send_cmd(mci, &cmd, NULL);
}
+static int mci_calc_blk_cnt(uint64_t cap, unsigned shift)
+{
+ unsigned ret = cap >> shift;
+
+ if (ret > 0x7fffffff) {
+ pr_warn("Limiting card size due to 31 bit contraints\n");
+ return 0x7fffffff;
+ }
+
+ return (int)ret;
+}
+
+static void mci_part_add(struct mci *mci, uint64_t size,
+ unsigned int part_cfg, char *name, int idx, bool ro,
+ int area_type)
+{
+ struct mci_part *part = &mci->part[mci->nr_parts];
+
+ part->mci = mci;
+ part->size = size;
+ part->blk.cdev.name = name;
+ part->blk.blockbits = SECTOR_SHIFT;
+ part->blk.num_blocks = mci_calc_blk_cnt(size, part->blk.blockbits);
+ part->area_type = area_type;
+ part->part_cfg = part_cfg;
+
+ mci->nr_parts++;
+}
+
/**
* Change transfer frequency for an MMC card
* @param mci MCI instance
@@ -409,7 +438,7 @@ static int mmc_change_freq(struct mci *mci)
err = mci_send_ext_csd(mci, mci->ext_csd);
if (err) {
- dev_dbg(mci->mci_dev, "Preparing for frequency setup failed: %d\n", err);
+ dev_dbg(&mci->dev, "Preparing for frequency setup failed: %d\n", err);
return err;
}
@@ -418,7 +447,7 @@ static int mmc_change_freq(struct mci *mci)
err = mci_switch(mci, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
if (err) {
- dev_dbg(mci->mci_dev, "MMC frequency changing failed: %d\n", err);
+ dev_dbg(&mci->dev, "MMC frequency changing failed: %d\n", err);
return err;
}
@@ -426,13 +455,13 @@ static int mmc_change_freq(struct mci *mci)
err = mci_send_ext_csd(mci, mci->ext_csd);
if (err) {
- dev_dbg(mci->mci_dev, "Verifying frequency change failed: %d\n", err);
+ dev_dbg(&mci->dev, "Verifying frequency change failed: %d\n", err);
return err;
}
/* No high-speed support */
if (!mci->ext_csd[EXT_CSD_HS_TIMING]) {
- dev_dbg(mci->mci_dev, "No high-speed support\n");
+ dev_dbg(&mci->dev, "No high-speed support\n");
return 0;
}
@@ -442,6 +471,26 @@ static int mmc_change_freq(struct mci *mci)
else
mci->card_caps |= MMC_MODE_HS;
+ if (IS_ENABLED(CONFIG_MCI_MMC_BOOT_PARTITIONS) &&
+ mci->ext_csd[EXT_CSD_REV] >= 3 && mci->ext_csd[EXT_CSD_BOOT_MULT]) {
+ int idx;
+ unsigned int part_size;
+
+ for (idx = 0; idx < MMC_NUM_BOOT_PARTITION; idx++) {
+ char *name;
+ part_size = mci->ext_csd[EXT_CSD_BOOT_MULT] << 17;
+
+ name = asprintf("%s.boot%d", mci->cdevname, idx);
+ mci_part_add(mci, part_size,
+ EXT_CSD_PART_CONFIG_ACC_BOOT0 + idx,
+ name, idx, true,
+ MMC_BLK_DATA_AREA_BOOT);
+ }
+
+ mci->ext_csd_part_config = mci->ext_csd[EXT_CSD_PART_CONFIG];
+ mci->bootpart = (mci->ext_csd_part_config >> 3) & 0x7;
+ }
+
return 0;
}
@@ -496,14 +545,14 @@ static int sd_change_freq(struct mci *mci)
if (mmc_host_is_spi(host))
return 0;
- dev_dbg(mci->mci_dev, "Changing transfer frequency\n");
+ dev_dbg(&mci->dev, "Changing transfer frequency\n");
mci->card_caps = 0;
/* Read the SCR to find out if this card supports higher speeds */
mci_setup_cmd(&cmd, MMC_CMD_APP_CMD, mci->rca << 16, MMC_RSP_R1);
err = mci_send_cmd(mci, &cmd, NULL);
if (err) {
- dev_dbg(mci->mci_dev, "Query SD card capabilities failed: %d\n", err);
+ dev_dbg(&mci->dev, "Query SD card capabilities failed: %d\n", err);
return err;
}
@@ -512,7 +561,7 @@ static int sd_change_freq(struct mci *mci)
timeout = 3;
retry_scr:
- dev_dbg(mci->mci_dev, "Trying to read the SCR (try %d of %d)\n", 4 - timeout, 3);
+ dev_dbg(&mci->dev, "Trying to read the SCR (try %d of %d)\n", 4 - timeout, 3);
data.dest = (char *)scr;
data.blocksize = 8;
data.blocks = 1;
@@ -520,12 +569,12 @@ retry_scr:
err = mci_send_cmd(mci, &cmd, &data);
if (err) {
- dev_dbg(mci->mci_dev, " Catch error (%d)", err);
+ dev_dbg(&mci->dev, " Catch error (%d)", err);
if (timeout--) {
- dev_dbg(mci->mci_dev, "-- retrying\n");
+ dev_dbg(&mci->dev, "-- retrying\n");
goto retry_scr;
}
- dev_dbg(mci->mci_dev, "-- giving up\n");
+ dev_dbg(&mci->dev, "-- giving up\n");
return err;
}
@@ -556,7 +605,7 @@ retry_scr:
err = sd_switch(mci, SD_SWITCH_CHECK, 0, 1,
(uint8_t*)switch_status);
if (err) {
- dev_dbg(mci->mci_dev, "Checking SD transfer switch frequency feature failed: %d\n", err);
+ dev_dbg(&mci->dev, "Checking SD transfer switch frequency feature failed: %d\n", err);
return err;
}
@@ -574,7 +623,7 @@ retry_scr:
err = sd_switch(mci, SD_SWITCH_SWITCH, 0, 1, (uint8_t*)switch_status);
if (err) {
- dev_dbg(mci->mci_dev, "Switching SD transfer frequency failed: %d\n", err);
+ dev_dbg(&mci->dev, "Switching SD transfer frequency failed: %d\n", err);
return err;
}
@@ -677,7 +726,7 @@ static void mci_detect_version_from_csd(struct mci *mci)
break;
}
- dev_info(mci->mci_dev, "detected card version %s\n", vstr);
+ dev_info(&mci->dev, "detected card version %s\n", vstr);
}
}
@@ -729,13 +778,13 @@ static void mci_extract_max_tran_speed_from_csd(struct mci *mci)
unit = tran_speed_unit[(mci->csd[0] & 0x7)];
time = tran_speed_time[((mci->csd[0] >> 3) & 0xf)];
if ((unit == 0) || (time == 0)) {
- dev_dbg(mci->mci_dev, "Unsupported 'TRAN_SPEED' unit/time value."
+ dev_dbg(&mci->dev, "Unsupported 'TRAN_SPEED' unit/time value."
" Can't calculate card's max. transfer speed\n");
return;
}
mci->tran_speed = time * unit;
- dev_dbg(mci->mci_dev, "Transfer speed: %u\n", mci->tran_speed);
+ dev_dbg(&mci->dev, "Transfer speed: %u\n", mci->tran_speed);
}
/**
@@ -753,7 +802,7 @@ static void mci_extract_block_lengths_from_csd(struct mci *mci)
else
mci->write_bl_len = 1 << ((mci->csd[3] >> 22) & 0xf);
- dev_dbg(mci->mci_dev, "Max. block length are: Write=%u, Read=%u Bytes\n",
+ dev_dbg(&mci->dev, "Max. block length are: Write=%u, Read=%u Bytes\n",
mci->write_bl_len, mci->read_bl_len);
}
@@ -782,7 +831,7 @@ static void mci_extract_card_capacity_from_csd(struct mci *mci)
}
mci->capacity *= 1 << UNSTUFF_BITS(mci->csd, 80, 4);;
- dev_dbg(mci->mci_dev, "Capacity: %u MiB\n", (unsigned)(mci->capacity >> 20));
+ dev_dbg(&mci->dev, "Capacity: %u MiB\n", (unsigned)(mci->capacity >> 20));
}
static int mmc_compare_ext_csds(struct mci *mci, unsigned bus_width)
@@ -796,7 +845,7 @@ static int mmc_compare_ext_csds(struct mci *mci, unsigned bus_width)
bw_ext_csd = xmalloc(512);
err = mci_send_ext_csd(mci, bw_ext_csd);
if (err) {
- dev_info(mci->mci_dev, "mci_send_ext_csd failed with %d\n", err);
+ dev_info(&mci->dev, "mci_send_ext_csd failed with %d\n", err);
if (bus_width != MMC_BUS_WIDTH_1)
err = -EINVAL;
goto out;
@@ -852,19 +901,19 @@ static int mci_startup_sd(struct mci *mci)
int err;
if (mci->card_caps & MMC_MODE_4BIT) {
- dev_dbg(mci->mci_dev, "Prepare for bus width change\n");
+ dev_dbg(&mci->dev, "Prepare for bus width change\n");
mci_setup_cmd(&cmd, MMC_CMD_APP_CMD, mci->rca << 16, MMC_RSP_R1);
err = mci_send_cmd(mci, &cmd, NULL);
if (err) {
- dev_dbg(mci->mci_dev, "Preparing SD for bus width change failed: %d\n", err);
+ dev_dbg(&mci->dev, "Preparing SD for bus width change failed: %d\n", err);
return err;
}
- dev_dbg(mci->mci_dev, "Set SD bus width to 4 bit\n");
+ dev_dbg(&mci->dev, "Set SD bus width to 4 bit\n");
mci_setup_cmd(&cmd, SD_CMD_APP_SET_BUS_WIDTH, 2, MMC_RSP_R1);
err = mci_send_cmd(mci, &cmd, NULL);
if (err) {
- dev_dbg(mci->mci_dev, "Changing SD bus width failed: %d\n", err);
+ dev_dbg(&mci->dev, "Changing SD bus width failed: %d\n", err);
/* TODO continue with 1 bit? */
return err;
}
@@ -955,25 +1004,25 @@ static int mci_startup(struct mci *mci)
err = mci_send_cmd(mci, &cmd, NULL);
if (err) {
- dev_dbg(mci->mci_dev, "Can't enable CRC check : %d\n", err);
+ dev_dbg(&mci->dev, "Can't enable CRC check : %d\n", err);
return err;
}
}
#endif
- dev_dbg(mci->mci_dev, "Put the Card in Identify Mode\n");
+ dev_dbg(&mci->dev, "Put the Card in Identify Mode\n");
/* Put the Card in Identify Mode */
mci_setup_cmd(&cmd, mmc_host_is_spi(host) ? MMC_CMD_SEND_CID : MMC_CMD_ALL_SEND_CID, 0, MMC_RSP_R2);
err = mci_send_cmd(mci, &cmd, NULL);
if (err) {
- dev_dbg(mci->mci_dev, "Can't bring card into identify mode: %d\n", err);
+ dev_dbg(&mci->dev, "Can't bring card into identify mode: %d\n", err);
return err;
}
memcpy(mci->cid, cmd.response, 16);
- dev_dbg(mci->mci_dev, "Card's identification data is: %08X-%08X-%08X-%08X\n",
+ dev_dbg(&mci->dev, "Card's identification data is: %08X-%08X-%08X-%08X\n",
mci->cid[0], mci->cid[1], mci->cid[2], mci->cid[3]);
/*
@@ -982,11 +1031,11 @@ static int mci_startup(struct mci *mci)
* This also puts the cards into Standby State
*/
if (!mmc_host_is_spi(host)) { /* cmd not supported in spi */
- dev_dbg(mci->mci_dev, "Get/Set relative address\n");
+ dev_dbg(&mci->dev, "Get/Set relative address\n");
mci_setup_cmd(&cmd, SD_CMD_SEND_RELATIVE_ADDR, mci->rca << 16, MMC_RSP_R6);
err = mci_send_cmd(mci, &cmd, NULL);
if (err) {
- dev_dbg(mci->mci_dev, "Get/Set relative address failed: %d\n", err);
+ dev_dbg(&mci->dev, "Get/Set relative address failed: %d\n", err);
return err;
}
}
@@ -994,19 +1043,19 @@ static int mci_startup(struct mci *mci)
if (IS_SD(mci))
mci->rca = (cmd.response[0] >> 16) & 0xffff;
- dev_dbg(mci->mci_dev, "Get card's specific data\n");
+ dev_dbg(&mci->dev, "Get card's specific data\n");
/* Get the Card-Specific Data */
mci_setup_cmd(&cmd, MMC_CMD_SEND_CSD, mci->rca << 16, MMC_RSP_R2);
err = mci_send_cmd(mci, &cmd, NULL);
if (err) {
- dev_dbg(mci->mci_dev, "Getting card's specific data failed: %d\n", err);
+ dev_dbg(&mci->dev, "Getting card's specific data failed: %d\n", err);
return err;
}
/* CSD is of 128 bit */
memcpy(mci->csd, cmd.response, 16);
- dev_dbg(mci->mci_dev, "Card's specific data is: %08X-%08X-%08X-%08X\n",
+ dev_dbg(&mci->dev, "Card's specific data is: %08X-%08X-%08X-%08X\n",
mci->csd[0], mci->csd[1], mci->csd[2], mci->csd[3]);
mci_detect_version_from_csd(mci);
@@ -1016,25 +1065,25 @@ static int mci_startup(struct mci *mci)
/* sanitiy? */
if (mci->read_bl_len > SECTOR_SIZE) {
mci->read_bl_len = SECTOR_SIZE;
- dev_dbg(mci->mci_dev, "Limiting max. read block size down to %u\n",
+ dev_dbg(&mci->dev, "Limiting max. read block size down to %u\n",
mci->read_bl_len);
}
if (mci->write_bl_len > SECTOR_SIZE) {
mci->write_bl_len = SECTOR_SIZE;
- dev_dbg(mci->mci_dev, "Limiting max. write block size down to %u\n",
+ dev_dbg(&mci->dev, "Limiting max. write block size down to %u\n",
mci->read_bl_len);
}
- dev_dbg(mci->mci_dev, "Read block length: %u, Write block length: %u\n",
+ dev_dbg(&mci->dev, "Read block length: %u, Write block length: %u\n",
mci->read_bl_len, mci->write_bl_len);
if (!mmc_host_is_spi(host)) { /* cmd not supported in spi */
- dev_dbg(mci->mci_dev, "Select the card, and put it into Transfer Mode\n");
+ dev_dbg(&mci->dev, "Select the card, and put it into Transfer Mode\n");
/* Select the card, and put it into Transfer Mode */
mci_setup_cmd(&cmd, MMC_CMD_SELECT_CARD, mci->rca << 16, MMC_RSP_R1b);
err = mci_send_cmd(mci, &cmd, NULL);
if (err) {
- dev_dbg(mci->mci_dev, "Putting in transfer mode failed: %d\n", err);
+ dev_dbg(&mci->dev, "Putting in transfer mode failed: %d\n", err);
return err;
}
}
@@ -1063,6 +1112,10 @@ static int mci_startup(struct mci *mci)
/* we setup the blocklength only one times for all accesses to this media */
err = mci_set_blocklen(mci, mci->read_bl_len);
+ mci_part_add(mci, mci->capacity, 0,
+ mci->cdevname, 0, true,
+ MMC_BLK_DATA_AREA_MAIN);
+
return err;
}
@@ -1089,21 +1142,51 @@ static int sd_send_if_cond(struct mci *mci)
MMC_RSP_R7);
err = mci_send_cmd(mci, &cmd, NULL);
if (err) {
- dev_dbg(mci->mci_dev, "Query interface conditions failed: %d\n", err);
+ dev_dbg(&mci->dev, "Query interface conditions failed: %d\n", err);
return err;
}
if ((cmd.response[0] & 0xff) != 0xaa) {
- dev_dbg(mci->mci_dev, "Card cannot work with hosts supply voltages\n");
+ dev_dbg(&mci->dev, "Card cannot work with hosts supply voltages\n");
return -EINVAL;
} else {
- dev_dbg(mci->mci_dev, "SD Card Rev. 2.00 or later detected\n");
+ dev_dbg(&mci->dev, "SD Card Rev. 2.00 or later detected\n");
mci->version = SD_VERSION_2;
}
return 0;
}
+static int mci_blk_part_switch(struct mci_part *part)
+{
+ struct mci *mci = part->mci;
+ int ret;
+
+ if (!IS_ENABLED(CONFIG_MCI_MMC_BOOT_PARTITIONS))
+ return 0;
+
+ if (mci->part_curr == part)
+ return 0;
+
+ if (!IS_SD(mci)) {
+ u8 part_config = mci->ext_csd_part_config;
+
+ part_config &= ~EXT_CSD_PART_CONFIG_ACC_MASK;
+ part_config |= part->part_cfg;
+
+ ret = mci_switch(mci, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_PART_CONFIG, part_config);
+ if (ret)
+ return ret;
+
+ mci->ext_csd_part_config = part_config;
+ }
+
+ mci->part_curr = part;
+
+ return 0;
+}
+
/* ------------------ attach to the blocklayer --------------------------- */
/**
@@ -1119,33 +1202,36 @@ static int sd_send_if_cond(struct mci *mci)
static int __maybe_unused mci_sd_write(struct block_device *blk,
const void *buffer, int block, int num_blocks)
{
- struct mci *mci = container_of(blk, struct mci, blk);
+ struct mci_part *part = container_of(blk, struct mci_part, blk);
+ struct mci *mci = part->mci;
struct mci_host *host = mci->host;
int rc;
+ mci_blk_part_switch(part);
+
if (host->card_write_protected && host->card_write_protected(host)) {
- dev_err(mci->mci_dev, "card write protected\n");
+ dev_err(&mci->dev, "card write protected\n");
return -EPERM;
}
- dev_dbg(mci->mci_dev, "%s: Write %d block(s), starting at %d\n",
+ dev_dbg(&mci->dev, "%s: Write %d block(s), starting at %d\n",
__func__, num_blocks, block);
if (mci->write_bl_len != SECTOR_SIZE) {
- dev_dbg(mci->mci_dev, "MMC/SD block size is not %d bytes (its %u bytes instead)\n",
+ dev_dbg(&mci->dev, "MMC/SD block size is not %d bytes (its %u bytes instead)\n",
SECTOR_SIZE, mci->read_bl_len);
return -EINVAL;
}
/* size of the block number field in the MMC/SD command is 32 bit only */
if (block > MAX_BUFFER_NUMBER) {
- dev_dbg(mci->mci_dev, "Cannot handle block number %d. Too large!\n", block);
+ dev_dbg(&mci->dev, "Cannot handle block number %d. Too large!\n", block);
return -EINVAL;
}
rc = mci_block_write(mci, buffer, block, num_blocks);
if (rc != 0) {
- dev_dbg(mci->mci_dev, "Writing block %d failed with %d\n", block, rc);
+ dev_dbg(&mci->dev, "Writing block %d failed with %d\n", block, rc);
return rc;
}
@@ -1165,26 +1251,29 @@ static int __maybe_unused mci_sd_write(struct block_device *blk,
static int mci_sd_read(struct block_device *blk, void *buffer, int block,
int num_blocks)
{
- struct mci *mci = container_of(blk, struct mci, blk);
+ struct mci_part *part = container_of(blk, struct mci_part, blk);
+ struct mci *mci = part->mci;
int rc;
- dev_dbg(mci->mci_dev, "%s: Read %d block(s), starting at %d\n",
+ mci_blk_part_switch(part);
+
+ dev_dbg(&mci->dev, "%s: Read %d block(s), starting at %d\n",
__func__, num_blocks, block);
if (mci->read_bl_len != 512) {
- dev_dbg(mci->mci_dev, "MMC/SD block size is not 512 bytes (its %u bytes instead)\n",
+ dev_dbg(&mci->dev, "MMC/SD block size is not 512 bytes (its %u bytes instead)\n",
mci->read_bl_len);
return -EINVAL;
}
if (block > MAX_BUFFER_NUMBER) {
- dev_err(mci->mci_dev, "Cannot handle block number %d. Too large!\n", block);
+ dev_err(&mci->dev, "Cannot handle block number %d. Too large!\n", block);
return -EINVAL;
}
rc = mci_read_block(mci, buffer, block, num_blocks);
if (rc != 0) {
- dev_dbg(mci->mci_dev, "Reading block %d failed with %d\n", block, rc);
+ dev_dbg(&mci->dev, "Reading block %d failed with %d\n", block, rc);
return rc;
}
@@ -1193,7 +1282,6 @@ static int mci_sd_read(struct block_device *blk, void *buffer, int block,
/* ------------------ attach to the device API --------------------------- */
-#ifdef CONFIG_MCI_INFO
/**
* Extract the Manufacturer ID from the CID
* @param mci Instance data
@@ -1282,9 +1370,9 @@ static unsigned extract_mtd_year(struct mci *mci)
* Output some valuable information when the user runs 'devinfo' on an MCI device
* @param mci MCI device instance
*/
-static void mci_info(struct device_d *mci_dev)
+static void mci_info(struct device_d *dev)
{
- struct mci *mci = mci_dev->priv;
+ struct mci *mci = container_of(dev, struct mci, dev);
if (mci->ready_for_use == 0) {
printf(" No information available:\n MCI card not probed yet\n");
@@ -1319,7 +1407,6 @@ static void mci_info(struct device_d *mci_dev)
printf(" Manufacturing date: %u.%u\n", extract_mtd_month(mci),
extract_mtd_year(mci));
}
-#endif
/**
* Check if the MCI card is already probed
@@ -1338,18 +1425,6 @@ static int mci_check_if_already_initialized(struct mci *mci)
return 0;
}
-static int mci_calc_blk_cnt(uint64_t cap, unsigned shift)
-{
- unsigned ret = cap >> shift;
-
- if (ret > 0x7fffffff) {
- pr_warn("Limiting card size due to 31 bit contraints\n");
- return 0x7fffffff;
- }
-
- return (int)ret;
-}
-
static struct block_device_ops mci_ops = {
.read = mci_sd_read,
#ifdef CONFIG_BLOCK_WRITE
@@ -1357,6 +1432,28 @@ static struct block_device_ops mci_ops = {
#endif
};
+static int mci_set_boot(struct param_d *param, void *priv)
+{
+ struct mci *mci = priv;
+
+ mci->ext_csd_part_config &= ~(7 << 3);
+ mci->ext_csd_part_config |= mci->bootpart << 3;
+
+ return mci_switch(mci, EXT_CSD_CMD_SET_NORMAL,
+ EXT_CSD_PART_CONFIG, mci->ext_csd_part_config);
+}
+
+static const char *mci_boot_names[] = {
+ "disabled",
+ "boot0",
+ "boot1",
+ NULL, /* reserved */
+ NULL, /* reserved */
+ NULL, /* reserved */
+ NULL, /* reserved */
+ "user",
+};
+
/**
* Probe an MCI card at the given host interface
* @param mci MCI device instance
@@ -1365,17 +1462,17 @@ static struct block_device_ops mci_ops = {
static int mci_card_probe(struct mci *mci)
{
struct mci_host *host = mci->host;
- int rc, disknum;
+ int i, rc, disknum;
if (host->card_present && !host->card_present(host)) {
- dev_err(mci->mci_dev, "no card inserted\n");
+ dev_err(&mci->dev, "no card inserted\n");
return -ENODEV;
}
/* start with a host interface reset */
- rc = (host->init)(host, mci->mci_dev);
+ rc = (host->init)(host, &mci->dev);
if (rc) {
- dev_err(mci->mci_dev, "Cannot reset the SD/MMC interface\n");
+ dev_err(&mci->dev, "Cannot reset the SD/MMC interface\n");
return rc;
}
@@ -1386,7 +1483,7 @@ static int mci_card_probe(struct mci *mci)
/* reset the card */
rc = mci_go_idle(mci);
if (rc) {
- dev_warn(mci->mci_dev, "Cannot reset the SD/MMC card\n");
+ dev_warn(&mci->dev, "Cannot reset the SD/MMC card\n");
goto on_error;
}
@@ -1395,55 +1492,65 @@ static int mci_card_probe(struct mci *mci)
rc = sd_send_op_cond(mci);
if (rc && rc == -ETIMEDOUT) {
/* If the command timed out, we check for an MMC card */
- dev_dbg(mci->mci_dev, "Card seems to be a MultiMediaCard\n");
+ dev_dbg(&mci->dev, "Card seems to be a MultiMediaCard\n");
rc = mmc_send_op_cond(mci);
}
if (rc)
goto on_error;
+ if (host->devname) {
+ mci->cdevname = strdup(host->devname);
+ } else {
+ disknum = cdev_find_free_index("disk");
+ mci->cdevname = asprintf("disk%d", disknum);
+ }
+
rc = mci_startup(mci);
if (rc) {
- dev_dbg(mci->mci_dev, "Card's startup fails with %d\n", rc);
+ dev_dbg(&mci->dev, "Card's startup fails with %d\n", rc);
goto on_error;
}
- dev_dbg(mci->mci_dev, "Card is up and running now, registering as a disk\n");
+ dev_dbg(&mci->dev, "Card is up and running now, registering as a disk\n");
mci->ready_for_use = 1; /* TODO now or later? */
- /*
- * An MMC/SD card acts like an ordinary disk.
- * So, re-use the disk driver to gain access to this media
- */
- mci->blk.dev = mci->mci_dev;
- mci->blk.ops = &mci_ops;
-
- if (host->devname) {
- mci->blk.cdev.name = strdup(host->devname);
- } else {
- disknum = cdev_find_free_index("disk");
- mci->blk.cdev.name = asprintf("disk%d", disknum);
- }
-
- mci->blk.blockbits = SECTOR_SHIFT;
- mci->blk.num_blocks = mci_calc_blk_cnt(mci->capacity, mci->blk.blockbits);
+ for (i = 0; i < mci->nr_parts; i++) {
+ struct mci_part *part = &mci->part[i];
- rc = blockdevice_register(&mci->blk);
- if (rc != 0) {
- dev_err(mci->mci_dev, "Failed to register MCI/SD blockdevice\n");
- goto on_error;
- }
+ /*
+ * An MMC/SD card acts like an ordinary disk.
+ * So, re-use the disk driver to gain access to this media
+ */
+ part->blk.dev = &mci->dev;
+ part->blk.ops = &mci_ops;
- dev_info(mci->mci_dev, "registered %s\n", mci->blk.cdev.name);
+ rc = blockdevice_register(&part->blk);
+ if (rc != 0) {
+ dev_err(&mci->dev, "Failed to register MCI/SD blockdevice\n");
+ goto on_error;
+ }
+ dev_info(&mci->dev, "registered %s\n", part->blk.cdev.name);
+
+ /* create partitions on demand */
+ if (part->area_type == MMC_BLK_DATA_AREA_MAIN) {
+ rc = parse_partition_table(&part->blk);
+ if (rc != 0) {
+ dev_warn(&mci->dev, "No partition table found\n");
+ rc = 0; /* it's not a failure */
+ }
+ }
- /* create partitions on demand */
- rc = parse_partition_table(&mci->blk);
- if (rc != 0) {
- dev_warn(mci->mci_dev, "No partition table found\n");
- rc = 0; /* it's not a failure */
+ if (IS_ENABLED(CONFIG_MCI_MMC_BOOT_PARTITIONS) &&
+ part->area_type == MMC_BLK_DATA_AREA_BOOT &&
+ !mci->param_boot) {
+ mci->param_boot = dev_add_param_enum(&mci->dev, "boot",
+ mci_set_boot, NULL, &mci->bootpart,
+ mci_boot_names, ARRAY_SIZE(mci_boot_names), mci);
+ }
}
- dev_dbg(mci->mci_dev, "SD Card successfully added\n");
+ dev_dbg(&mci->dev, "SD Card successfully added\n");
on_error:
if (rc != 0) {
@@ -1480,75 +1587,125 @@ static int mci_set_probe(struct param_d *param, void *priv)
return 0;
}
+static int mci_init(void)
+{
+ sector_buf = xmemalign(32, 512);
+
+ return 0;
+}
+
+device_initcall(mci_init);
+
+int mci_detect_card(struct mci_host *host)
+{
+ int rc;
+
+ rc = mci_check_if_already_initialized(host->mci);
+ if (rc != 0)
+ return 0;
+
+ return mci_card_probe(host->mci);
+}
+
+static int mci_detect(struct device_d *dev)
+{
+ struct mci *mci = container_of(dev, struct mci, dev);
+
+ return mci_detect_card(mci->host);
+}
+
/**
- * Prepare for MCI card's usage
- * @param mci_dev MCI device instance
+ * Create a new mci device (for convenience)
+ * @param host mci_host for this MCI device
* @return 0 on success
- *
- * This routine will probe an attached MCI card immediately or provide
- * a parameter to do it later on user's demand.
*/
-static int mci_probe(struct device_d *mci_dev)
+int mci_register(struct mci_host *host)
{
struct mci *mci;
- int rc;
+ int ret;
- mci = xzalloc(sizeof(struct mci));
- mci_dev->priv = mci;
- mci->mci_dev = mci_dev;
- mci->host = mci_dev->platform_data;
+ mci = xzalloc(sizeof(*mci));
+ mci->host = host;
- dev_info(mci->host->hw_dev, "registered as %s\n", dev_name(mci_dev));
+ if (host->devname) {
+ strcpy(mci->dev.name, host->devname);
+ mci->dev.id = DEVICE_ID_SINGLE;
+ } else {
+ strcpy(mci->dev.name, "mci");
+ mci->dev.id = DEVICE_ID_DYNAMIC;
+ }
+
+ mci->dev.platform_data = host;
+ mci->dev.parent = host->hw_dev;
+ mci->host = host;
+ host->mci = mci;
+ mci->dev.detect = mci_detect;
+
+ ret = register_device(&mci->dev);
+ if (ret)
+ goto err_free;
- mci->param_probe = dev_add_param_bool(mci_dev, "probe",
+ dev_info(mci->host->hw_dev, "registered as %s\n", dev_name(&mci->dev));
+
+ mci->param_probe = dev_add_param_bool(&mci->dev, "probe",
mci_set_probe, NULL, &mci->probe, mci);
if (IS_ERR(mci->param_probe)) {
- dev_dbg(mci->mci_dev, "Failed to add 'probe' parameter to the MCI device\n");
- goto on_error;
+ dev_dbg(&mci->dev, "Failed to add 'probe' parameter to the MCI device\n");
+ goto err_unregister;
}
-#ifdef CONFIG_MCI_STARTUP
+ if (IS_ENABLED(CONFIG_MCI_INFO))
+ mci->dev.info = mci_info;
+
/* if enabled, probe the attached card immediately */
- mci_card_probe(mci);
-#endif
+ if (IS_ENABLED(CONFIG_MCI_STARTUP))
+ mci_card_probe(mci);
return 0;
-on_error:
+err_unregister:
+ unregister_device(&mci->dev);
+err_free:
free(mci);
- return rc;
-}
-static struct driver_d mci_driver = {
- .name = "mci",
- .probe = mci_probe,
-#ifdef CONFIG_MCI_INFO
- .info = mci_info,
-#endif
-};
+ return ret;
+}
-static int mci_init(void)
+void mci_of_parse(struct mci_host *host)
{
- sector_buf = xmemalign(32, 512);
- return platform_driver_register(&mci_driver);
-}
+ struct device_node *np;
+ u32 bus_width;
-device_initcall(mci_init);
+ if (!IS_ENABLED(CONFIG_OFDEVICE))
+ return;
-/**
- * Create a new mci device (for convenience)
- * @param host mci_host for this MCI device
- * @return 0 on success
- */
-int mci_register(struct mci_host *host)
-{
- struct device_d *mci_dev = xzalloc(sizeof(struct device_d));
+ if (!host->hw_dev || !host->hw_dev->device_node)
+ return;
+
+ np = host->hw_dev->device_node;
- mci_dev->id = DEVICE_ID_DYNAMIC;
- strcpy(mci_dev->name, mci_driver.name);
- mci_dev->platform_data = host;
- mci_dev->parent = host->hw_dev;
+ /* "bus-width" is translated to MMC_CAP_*_BIT_DATA flags */
+ if (of_property_read_u32(np, "bus-width", &bus_width) < 0) {
+ dev_dbg(host->hw_dev,
+ "\"bus-width\" property is missing, assuming 1 bit.\n");
+ bus_width = 1;
+ }
+
+ switch (bus_width) {
+ case 8:
+ host->host_caps |= MMC_MODE_8BIT;
+ /* Hosts capable of 8-bit transfers can also do 4 bits */
+ case 4:
+ host->host_caps |= MMC_MODE_4BIT;
+ break;
+ case 1:
+ break;
+ default:
+ dev_err(host->hw_dev,
+ "Invalid \"bus-width\" value %ud!\n", bus_width);
+ }
- return platform_device_register(mci_dev);
+ /* f_max is obtained from the optional "max-frequency" property */
+ of_property_read_u32(np, "max-frequency", &host->f_max);
}
diff --git a/drivers/mci/mxs.c b/drivers/mci/mxs.c
index 9dee863aaf..e6f40ebc35 100644
--- a/drivers/mci/mxs.c
+++ b/drivers/mci/mxs.c
@@ -536,7 +536,6 @@ static void mxs_mci_set_ios(struct mci_host *host, struct mci_ios *ios)
/* ----------------------------------------------------------------------- */
-#ifdef CONFIG_MCI_INFO
const unsigned char bus_width[3] = { 1, 4, 8 };
static void mxs_mci_info(struct device_d *hw_dev)
@@ -550,7 +549,6 @@ static void mxs_mci_info(struct device_d *hw_dev)
printf(" Bus width: %u bit\n", bus_width[mxs_mci->bus_width]);
printf("\n");
}
-#endif
static int mxs_mci_probe(struct device_d *hw_dev)
{
@@ -617,10 +615,11 @@ static int mxs_mci_probe(struct device_d *hw_dev)
host->f_max, mxs_mci_get_unit_clock(mxs_mci) / 2 / 1);
}
-#ifdef CONFIG_MCI_INFO
- mxs_mci->f_min = host->f_min;
- mxs_mci->f_max = host->f_max;
-#endif
+ if (IS_ENABLED(CONFIG_MCI_INFO)) {
+ mxs_mci->f_min = host->f_min;
+ mxs_mci->f_max = host->f_max;
+ hw_dev->info = mxs_mci_info;
+ }
return mci_register(host);
}
@@ -628,8 +627,5 @@ static int mxs_mci_probe(struct device_d *hw_dev)
static struct driver_d mxs_mci_driver = {
.name = "mxs_mci",
.probe = mxs_mci_probe,
-#ifdef CONFIG_MCI_INFO
- .info = mxs_mci_info,
-#endif
};
device_platform_driver(mxs_mci_driver);
diff --git a/drivers/mci/s3c.c b/drivers/mci/s3c.c
index 4e7345c8d5..773c84ad09 100644
--- a/drivers/mci/s3c.c
+++ b/drivers/mci/s3c.c
@@ -700,7 +700,6 @@ static void mci_set_ios(struct mci_host *host, struct mci_ios *ios)
/* ----------------------------------------------------------------------- */
-#ifdef CONFIG_MCI_INFO
static void s3c_info(struct device_d *hw_dev)
{
struct s3c_mci_host *host = hw_dev->priv;
@@ -720,7 +719,6 @@ static void s3c_info(struct device_d *hw_dev)
printf("\n Card detection support: %s\n",
pd->gpio_detect != 0 ? "yes" : "no");
}
-#endif
static int s3c_mci_probe(struct device_d *hw_dev)
{
@@ -751,6 +749,9 @@ static int s3c_mci_probe(struct device_d *hw_dev)
s3c_host->host.f_min = pd->f_min == 0 ? s3c_get_pclk() / 256 : pd->f_min;
s3c_host->host.f_max = pd->f_max == 0 ? s3c_get_pclk() / 2 : pd->f_max;
+ if (IS_ENABLED(iCONFIG_MCI_INFO))
+ hw_dev->info = s3c_info;
+
/*
* Start the clock to let the engine and the card finishes its startup
*/
@@ -763,8 +764,5 @@ static int s3c_mci_probe(struct device_d *hw_dev)
static struct driver_d s3c_mci_driver = {
.name = "s3c_mci",
.probe = s3c_mci_probe,
-#ifdef CONFIG_MCI_INFO
- .info = s3c_info,
-#endif
};
device_platform_driver(s3c_mci_driver);
diff --git a/drivers/mci/sdhci.h b/drivers/mci/sdhci.h
new file mode 100644
index 0000000000..b2d6779ef6
--- /dev/null
+++ b/drivers/mci/sdhci.h
@@ -0,0 +1,89 @@
+#ifndef __MCI_SDHCI_H
+#define __MCI_SDHCI_H
+
+#define SDHCI_DMA_ADDRESS 0x00
+#define SDHCI_BLOCK_SIZE__BLOCK_COUNT 0x04
+#define SDHCI_ARGUMENT 0x08
+#define SDHCI_TRANSFER_MODE__COMMAND 0x0c
+#define SDHCI_RESPONSE_0 0x10
+#define SDHCI_RESPONSE_1 0x14
+#define SDHCI_RESPONSE_2 0x18
+#define SDHCI_RESPONSE_3 0x1c
+#define SDHCI_BUFFER 0x20
+#define SDHCI_PRESENT_STATE 0x24
+#define SDHCI_HOST_CONTROL__POWER_CONTROL__BLOCK_GAP_CONTROL 0x28
+#define SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET 0x2c
+#define SDHCI_INT_STATUS 0x30
+#define SDHCI_INT_ENABLE 0x34
+#define SDHCI_SIGNAL_ENABLE 0x38
+#define SDHCI_ACMD12_ERR__HOST_CONTROL2 0x3C
+#define SDHCI_CAPABILITIES 0x40
+
+#define COMMAND_CMD(x) ((x & 0x3f) << 24)
+#define COMMAND_CMDTYP_NORMAL 0x0
+#define COMMAND_CMDTYP_SUSPEND 0x00400000
+#define COMMAND_CMDTYP_RESUME 0x00800000
+#define COMMAND_CMDTYP_ABORT 0x00c00000
+#define COMMAND_DPSEL 0x00200000
+#define COMMAND_CICEN 0x00100000
+#define COMMAND_CCCEN 0x00080000
+#define COMMAND_RSPTYP_NONE 0
+#define COMMAND_RSPTYP_136 0x00010000
+#define COMMAND_RSPTYP_48 0x00020000
+#define COMMAND_RSPTYP_48_BUSY 0x00030000
+#define TRANSFER_MODE_MSBSEL 0x00000020
+#define TRANSFER_MODE_DTDSEL 0x00000010
+#define TRANSFER_MODE_AC12EN 0x00000004
+#define TRANSFER_MODE_BCEN 0x00000002
+#define TRANSFER_MODE_DMAEN 0x00000001
+
+#define IRQSTAT_DMAE 0x10000000
+#define IRQSTAT_AC12E 0x01000000
+#define IRQSTAT_DEBE 0x00400000
+#define IRQSTAT_DCE 0x00200000
+#define IRQSTAT_DTOE 0x00100000
+#define IRQSTAT_CIE 0x00080000
+#define IRQSTAT_CEBE 0x00040000
+#define IRQSTAT_CCE 0x00020000
+#define IRQSTAT_CTOE 0x00010000
+#define IRQSTAT_CINT 0x00000100
+#define IRQSTAT_CRM 0x00000080
+#define IRQSTAT_CINS 0x00000040
+#define IRQSTAT_BRR 0x00000020
+#define IRQSTAT_BWR 0x00000010
+#define IRQSTAT_DINT 0x00000008
+#define IRQSTAT_BGE 0x00000004
+#define IRQSTAT_TC 0x00000002
+#define IRQSTAT_CC 0x00000001
+
+#define IRQSTATEN_DMAE 0x10000000
+#define IRQSTATEN_AC12E 0x01000000
+#define IRQSTATEN_DEBE 0x00400000
+#define IRQSTATEN_DCE 0x00200000
+#define IRQSTATEN_DTOE 0x00100000
+#define IRQSTATEN_CIE 0x00080000
+#define IRQSTATEN_CEBE 0x00040000
+#define IRQSTATEN_CCE 0x00020000
+#define IRQSTATEN_CTOE 0x00010000
+#define IRQSTATEN_CINT 0x00000100
+#define IRQSTATEN_CRM 0x00000080
+#define IRQSTATEN_CINS 0x00000040
+#define IRQSTATEN_BRR 0x00000020
+#define IRQSTATEN_BWR 0x00000010
+#define IRQSTATEN_DINT 0x00000008
+#define IRQSTATEN_BGE 0x00000004
+#define IRQSTATEN_TC 0x00000002
+#define IRQSTATEN_CC 0x00000001
+
+#define PRSSTAT_CLSL 0x00800000
+#define PRSSTAT_WPSPL 0x00080000
+#define PRSSTAT_CDPL 0x00040000
+#define PRSSTAT_CINS 0x00010000
+#define PRSSTAT_BREN 0x00000800
+#define PRSSTAT_BWEN 0x00000400
+#define PRSSTAT_SDSTB 0x00000008
+#define PRSSTAT_DLA 0x00000004
+#define PRSSTAT_CIDHB 0x00000002
+#define PRSSTAT_CICHB 0x00000001
+
+#endif /* __MCI_SDHCI_H */
diff --git a/drivers/mci/twl6030.c b/drivers/mci/twl6030.c
deleted file mode 100644
index 4a875bd62b..0000000000
--- a/drivers/mci/twl6030.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * MCI pmic power.
- */
-
-#include <mfd/twl6030.h>
-#include <mci/twl6030.h>
-#include <asm/io.h>
-
-static int twl6030_mci_write(u8 address, u8 data)
-{
- int ret;
- struct twl6030 *twl6030 = twl6030_get();
-
- ret = twl6030_reg_write(twl6030, address, data);
- if (ret != 0)
- printf("TWL6030:MCI:Write[0x%x] Error %d\n", address, ret);
-
- return ret;
-}
-
-void twl6030_mci_power_init(void)
-{
- twl6030_mci_write(TWL6030_PMCS_VMMC_CFG_VOLTAGE,
- TWL6030_VMMC_VSEL_0 | TWL6030_VMMC_VSEL_2 |
- TWL6030_VMMC_VSEL_4);
- twl6030_mci_write(TWL6030_PMCS_VMMC_CFG_STATE,
- TWL6030_VMMC_STATE0 | TWL6030_VMMC_GRP_APP);
-}
-
diff --git a/drivers/misc/jtag.c b/drivers/misc/jtag.c
index d302237e37..310da81074 100644
--- a/drivers/misc/jtag.c
+++ b/drivers/misc/jtag.c
@@ -269,6 +269,25 @@ static struct file_operations jtag_operations = {
.ioctl = jtag_ioctl,
};
+static void jtag_info(struct device_d *pdev)
+{
+ int dn, ret;
+ struct jtag_rd_id jid;
+ struct jtag_info *info = pdev->priv;
+
+ printf(" JTAG:\n");
+ printf(" Devices found: %d\n", info->devices);
+ for (dn = 0; dn < info->devices; dn++) {
+ jid.device = dn;
+ ret = jtag_ioctl(&info->cdev, JTAG_GET_ID, &jid);
+ printf(" Device number: %d\n", dn);
+ if (ret == -1)
+ printf(" JTAG_GET_ID failed: %s\n", strerror(errno));
+ else
+ printf(" ID: 0x%lX\n", jid.id);
+ }
+}
+
static int jtag_probe(struct device_d *pdev)
{
int i, ret;
@@ -323,6 +342,7 @@ static int jtag_probe(struct device_d *pdev)
info->devices = i;
info->pdata = pdata;
pdev->priv = info;
+ pdev->info = jtag_info;
info->cdev.name = JTAG_NAME;
info->cdev.dev = pdev;
@@ -341,25 +361,6 @@ fail_devfs_create:
return ret;
}
-static void jtag_info(struct device_d *pdev)
-{
- int dn, ret;
- struct jtag_rd_id jid;
- struct jtag_info *info = pdev->priv;
-
- printf(" JTAG:\n");
- printf(" Devices found: %d\n", info->devices);
- for (dn = 0; dn < info->devices; dn++) {
- jid.device = dn;
- ret = jtag_ioctl(&info->cdev, JTAG_GET_ID, &jid);
- printf(" Device number: %d\n", dn);
- if (ret == -1)
- printf(" JTAG_GET_ID failed: %s\n", strerror(errno));
- else
- printf(" ID: 0x%lX\n", jid.id);
- }
-}
-
static void jtag_remove(struct device_d *pdev)
{
struct jtag_info *info = (struct jtag_info *) pdev->priv;
@@ -374,7 +375,6 @@ static struct driver_d jtag_driver = {
.name = JTAG_NAME,
.probe = jtag_probe,
.remove = jtag_remove,
- .info = jtag_info,
};
device_platform_driver(jtag_driver);
diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 61744b69dc..f3580981f0 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -107,6 +107,12 @@ static int mtd_op_erase(struct cdev *cdev, size_t count, loff_t offset)
memset(&erase, 0, sizeof(erase));
erase.mtd = mtd;
erase.addr = offset;
+
+ if (!mtd->block_isbad) {
+ erase.len = count;
+ return mtd_erase(mtd, &erase);
+ }
+
erase.len = mtd->erasesize;
while (count > 0) {
diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c
index 048d1783dc..57fe1f27ef 100644
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -947,9 +947,18 @@ static int m25p_probe(struct device_d *dev)
return add_mtd_device(&flash->mtd, flash->mtd.name);
}
+static __maybe_unused struct of_device_id m25p80_dt_ids[] = {
+ {
+ .compatible = "m25p80",
+ }, {
+ /* sentinel */
+ }
+};
+
static struct driver_d m25p80_driver = {
.name = "m25p80",
.probe = m25p_probe,
+ .of_compatible = DRV_OF_COMPAT(m25p80_dt_ids),
};
device_spi_driver(m25p80_driver);
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index ddab6bbb79..52bd84266c 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -871,9 +871,20 @@ static int dataflash_probe(struct device_d *dev)
return status;
}
+static __maybe_unused struct of_device_id dataflash_dt_ids[] = {
+ {
+ .compatible = "atmel,at45",
+ }, {
+ .compatible = "atmel,dataflash",
+ }, {
+ /* sentinel */
+ }
+};
+
static struct driver_d dataflash_driver = {
.name = "mtd_dataflash",
.probe = dataflash_probe,
+ .of_compatible = DRV_OF_COMPAT(dataflash_dt_ids),
};
device_spi_driver(dataflash_driver);
diff --git a/drivers/mtd/nor/cfi_flash.c b/drivers/mtd/nor/cfi_flash.c
index 0cfac2d036..51fc6bc89f 100644
--- a/drivers/mtd/nor/cfi_flash.c
+++ b/drivers/mtd/nor/cfi_flash.c
@@ -187,10 +187,10 @@ static ulong flash_read_long (struct flash_info *info, flash_sect_t sect, uint o
addr = flash_make_addr (info, sect, offset);
#ifdef DEBUG
- debug ("long addr is at %p info->portwidth = %d\n", addr,
+ dev_dbg(info->dev, "long addr is at %p info->portwidth = %d\n", addr,
info->portwidth);
for (x = 0; x < 4 * info->portwidth; x++) {
- debug ("addr[%x] = 0x%x\n", x, flash_read8(addr + x));
+ dev_dbg(info->dev, "addr[%x] = 0x%x\n", x, flash_read8(addr + x));
}
#endif
#if defined __LITTLE_ENDIAN
@@ -240,10 +240,10 @@ static void flash_read_cfi (struct flash_info *info, void *buf,
p[i] = flash_read_uchar(info, start + i);
}
-static int flash_detect_cfi (struct flash_info *info, struct cfi_qry *qry)
+static int flash_detect_width (struct flash_info *info, struct cfi_qry *qry)
{
int cfi_offset;
- debug ("flash detect cfi\n");
+
for (info->portwidth = CFG_FLASH_CFI_WIDTH;
info->portwidth <= FLASH_CFI_64BIT; info->portwidth <<= 1) {
@@ -262,11 +262,11 @@ static int flash_detect_cfi (struct flash_info *info, struct cfi_qry *qry)
info->interface = le16_to_cpu(qry->interface_desc);
info->cfi_offset=flash_offset_cfi[cfi_offset];
- debug ("device interface is %d\n",
+ dev_dbg(info->dev, "device interface is %d\n",
info->interface);
- debug ("found port %d chip %d ",
- info->portwidth, info->chipwidth);
- debug ("port %d bits chip %d bits\n",
+ dev_dbg(info->dev, "found port %d chip %d chip_lsb %d ",
+ info->portwidth, info->chipwidth, info->chip_lsb);
+ dev_dbg(info->dev, "port %d bits chip %d bits\n",
info->portwidth << CFI_FLASH_SHIFT_WIDTH,
info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
return 1;
@@ -274,10 +274,25 @@ static int flash_detect_cfi (struct flash_info *info, struct cfi_qry *qry)
}
}
}
- debug ("not found\n");
+ dev_dbg(info->dev, "not found\n");
return 0;
}
+static int flash_detect_cfi (struct flash_info *info, struct cfi_qry *qry)
+{
+ int ret;
+
+ dev_dbg(info->dev, "flash detect cfi\n");
+
+ info->chip_lsb = 0;
+ ret = flash_detect_width (info, qry);
+ if (!ret) {
+ info->chip_lsb = 1;
+ ret = flash_detect_width (info, qry);
+ }
+ return ret;
+}
+
/*
* The following code cannot be run from FLASH!
*/
@@ -339,7 +354,7 @@ static ulong flash_get_size (struct flash_info *info)
break;
#endif
default:
- printf("unsupported vendor\n");
+ dev_err(info->dev, "unsupported vendor\n");
return 0;
}
info->cfi_cmd_set->flash_read_jedec_ids (info);
@@ -347,22 +362,23 @@ static ulong flash_get_size (struct flash_info *info)
info->cfi_cmd_set->flash_fixup (info, &qry);
- debug ("manufacturer is %d\n", info->vendor);
- debug ("manufacturer id is 0x%x\n", info->manufacturer_id);
- debug ("device id is 0x%x\n", info->device_id);
- debug ("device id2 is 0x%x\n", info->device_id2);
- debug ("cfi version is 0x%04x\n", info->cfi_version);
+ dev_dbg(info->dev, "manufacturer is %d\n", info->vendor);
+ dev_dbg(info->dev, "manufacturer id is 0x%x\n", info->manufacturer_id);
+ dev_dbg(info->dev, "device id is 0x%x\n", info->device_id);
+ dev_dbg(info->dev, "device id2 is 0x%x\n", info->device_id2);
+ dev_dbg(info->dev, "cfi version is 0x%04x\n", info->cfi_version);
size_ratio = info->portwidth / info->chipwidth;
/* if the chip is x8/x16 reduce the ratio by half */
if ((info->interface == FLASH_CFI_X8X16)
- && (info->chipwidth == FLASH_CFI_BY8)) {
+ && (info->chipwidth == FLASH_CFI_BY8)
+ && (size_ratio != 1)) {
size_ratio >>= 1;
}
- debug ("size_ratio %d port %d bits chip %d bits\n",
+ dev_dbg(info->dev, "size_ratio %d port %d bits chip %d bits\n",
size_ratio, info->portwidth << CFI_FLASH_SHIFT_WIDTH,
info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
- debug ("found %d erase regions\n", num_erase_regions);
+ dev_dbg(info->dev, "found %d erase regions\n", num_erase_regions);
info->eraseregions = xzalloc(sizeof(*(info->eraseregions)) * num_erase_regions);
info->numeraseregions = num_erase_regions;
sect_cnt = 0;
@@ -372,19 +388,19 @@ static ulong flash_get_size (struct flash_info *info)
struct mtd_erase_region_info *region = &info->eraseregions[i];
if (i > NUM_ERASE_REGIONS) {
- printf ("%d erase regions found, only %d used\n",
+ dev_info(info->dev, "%d erase regions found, only %d used\n",
num_erase_regions, NUM_ERASE_REGIONS);
break;
}
tmp = le32_to_cpu(qry.erase_region_info[i]);
- debug("erase region %u: 0x%08lx\n", i, tmp);
+ dev_dbg(info->dev, "erase region %u: 0x%08lx\n", i, tmp);
erase_region_count = (tmp & 0xffff) + 1;
tmp >>= 16;
erase_region_size =
(tmp & 0xffff) ? ((tmp & 0xffff) * 256) : 128;
- debug ("erase_region_count = %d erase_region_size = %d\n",
+ dev_dbg(info->dev, "erase_region_count = %d erase_region_size = %d\n",
erase_region_count, erase_region_size);
region->offset = cur_offset;
@@ -459,7 +475,7 @@ static int cfi_erase(struct flash_info *finfo, size_t count, loff_t offset)
unsigned long start, end;
int i, ret = 0;
- debug("%s: erase 0x%08llx (size %zu)\n", __func__, offset, count);
+ dev_dbg(finfo->dev, "%s: erase 0x%08llx (size %zu)\n", __func__, offset, count);
start = find_sector(finfo, (unsigned long)finfo->base + offset);
end = find_sector(finfo, (unsigned long)finfo->base + offset +
@@ -786,7 +802,7 @@ int flash_generic_status_check (struct flash_info *info, flash_sect_t sector,
start = get_time_ns();
while (info->cfi_cmd_set->flash_is_busy (info, sector)) {
if (is_timeout(start, tout)) {
- printf ("Flash %s timeout at address %lx data %lx\n",
+ dev_err(info->dev, "Flash %s timeout at address %lx data %lx\n",
prompt, info->start[sector],
flash_read_long (info, sector, 0));
flash_write_cmd (info, sector, 0, info->cmd_reset);
@@ -823,7 +839,7 @@ void flash_write_cmd(struct flash_info *info, flash_sect_t sect,
addr = flash_make_addr (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
- debug("%s: %p %lX %X => %p " CFI_WORD_FMT "\n", __func__,
+ dev_dbg(info->dev, "%s: %p %lX %X => %p " CFI_WORD_FMT "\n", __func__,
info, sect, offset, addr, cword);
flash_write_word(info, cword, addr);
@@ -839,15 +855,15 @@ int flash_isequal(struct flash_info *info, flash_sect_t sect,
addr = flash_make_addr (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
- debug ("is= cmd %x(%c) addr %p ", cmd, cmd, addr);
+ dev_dbg(info->dev, "is= cmd %x(%c) addr %p ", cmd, cmd, addr);
if (bankwidth_is_1(info)) {
- debug ("is= %x %x\n", flash_read8(addr), (u8)cword);
+ dev_dbg(info->dev, "is= %x %x\n", flash_read8(addr), (u8)cword);
retval = (flash_read8(addr) == cword);
} else if (bankwidth_is_2(info)) {
- debug ("is= %4.4x %4.4x\n", flash_read16(addr), (u16)cword);
+ dev_dbg(info->dev, "is= %4.4x %4.4x\n", flash_read16(addr), (u16)cword);
retval = (flash_read16(addr) == cword);
} else if (bankwidth_is_4(info)) {
- debug ("is= %8.8x %8.8x\n", flash_read32(addr), (u32)cword);
+ dev_dbg(info->dev, "is= %8.8x %8.8x\n", flash_read32(addr), (u32)cword);
retval = (flash_read32(addr) == cword);
} else if (bankwidth_is_8(info)) {
#ifdef DEBUG
@@ -857,7 +873,7 @@ int flash_isequal(struct flash_info *info, flash_sect_t sect,
print_longlong (str1, flash_read32(addr));
print_longlong (str2, cword);
- debug ("is= %s %s\n", str1, str2);
+ dev_dbg(info->dev, "is= %s %s\n", str1, str2);
}
#endif
retval = (flash_read64(addr) == cword);
@@ -947,6 +963,7 @@ static void cfi_init_mtd(struct flash_info *info)
mtd->numeraseregions = info->numeraseregions;
mtd->flags = MTD_CAP_NORFLASH;
mtd->type = MTD_NORFLASH;
+ mtd->parent = info->dev;
add_mtd_device(mtd, "nor");
}
@@ -962,9 +979,10 @@ static int cfi_probe (struct device_d *dev)
info->cmd_reset = FLASH_CMD_RESET;
info->base = dev_request_mem_region(dev, 0);
info->size = flash_get_size(info);
+ info->dev = dev;
if (info->flash_id == FLASH_UNKNOWN) {
- printf ("## Unknown FLASH on Bank at 0x%08x - Size = 0x%08lx = %ld MB\n",
+ dev_warn(dev, "## Unknown FLASH on Bank at 0x%08x - Size = 0x%08lx = %ld MB\n",
dev->resource[0].start, info->size, info->size << 20);
return -ENODEV;
}
@@ -972,6 +990,8 @@ static int cfi_probe (struct device_d *dev)
dev_info(dev, "found cfi flash at %p, size %ld\n",
info->base, info->size);
+ dev->info = cfi_info;
+
cfi_init_mtd(info);
return 0;
@@ -988,7 +1008,6 @@ static __maybe_unused struct of_device_id cfi_dt_ids[] = {
static struct driver_d cfi_driver = {
.name = "cfi_flash",
.probe = cfi_probe,
- .info = cfi_info,
.of_compatible = DRV_OF_COMPAT(cfi_dt_ids),
};
device_platform_driver(cfi_driver);
diff --git a/drivers/mtd/nor/cfi_flash.h b/drivers/mtd/nor/cfi_flash.h
index bcf5c40c73..9aad5c41f6 100644
--- a/drivers/mtd/nor/cfi_flash.h
+++ b/drivers/mtd/nor/cfi_flash.h
@@ -48,7 +48,7 @@ struct cfi_cmd_set;
*/
struct flash_info {
- struct driver_d driver;
+ struct device_d *dev;
ulong size; /* total bank size in bytes */
ushort sector_count; /* number of erase units */
ulong flash_id; /* combined device & manufacturer code */
@@ -57,6 +57,8 @@ struct flash_info {
uchar portwidth; /* the width of the port */
uchar chipwidth; /* the width of the chip */
+ uchar chip_lsb; /* extra Least Significant Bit in the */
+ /* address of chip. */
ushort buffer_size; /* # of bytes in write buffer */
ulong erase_blk_tout; /* maximum block erase timeout */
ulong write_tout; /* maximum write timeout */
@@ -298,7 +300,7 @@ static inline u64 flash_read64(void *addr)
*/
static inline uchar *flash_make_addr (struct flash_info *info, flash_sect_t sect, uint offset)
{
- return ((uchar *) (info->start[sect] + (offset * info->portwidth)));
+ return ((uchar *) (info->start[sect] + ((offset * info->portwidth) << info->chip_lsb)));
}
uchar flash_read_uchar (struct flash_info *info, uint offset);
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 2736094b8b..5ad3e4d46e 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -27,6 +27,13 @@ menu "Network drivers"
source "drivers/net/phy/Kconfig"
+config DRIVER_NET_AR231X
+ bool "AR231X Ethernet support"
+ depends on MACH_MIPS_AR231X
+ select PHYLIB
+ help
+ Support for the AR231x/531x ethernet controller
+
config DRIVER_NET_CALXEDA_XGMAC
bool "Calxeda xgmac"
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 42136f87c8..73403fecfd 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_DRIVER_NET_AR231X) += ar231x.o
obj-$(CONFIG_DRIVER_NET_CALXEDA_XGMAC) += xgmac.o
obj-$(CONFIG_DRIVER_NET_CS8900) += cs8900.o
obj-$(CONFIG_DRIVER_NET_CPSW) += cpsw.o
diff --git a/drivers/net/ar231x.c b/drivers/net/ar231x.c
new file mode 100644
index 0000000000..5c091140ac
--- /dev/null
+++ b/drivers/net/ar231x.c
@@ -0,0 +1,437 @@
+/*
+ * ar231x.c: driver for the Atheros AR231x Ethernet device.
+ * This device is build in to SoC on ar231x series.
+ * All known of them are big endian.
+ *
+ * Based on Linux driver:
+ * Copyright (C) 2004 by Sameer Dekate <sdekate@arubanetworks.com>
+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
+ * Ported to Barebox:
+ * Copyright (C) 2013 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * 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.
+ */
+/*
+ * Known issues:
+ * - broadcast packets are not filtered by hardware. On noisy network with
+ * lots of bcast packages rx_buffer can be completely filled after. Currently
+ * we clear rx_buffer transmit some package.
+ */
+
+#include <common.h>
+#include <net.h>
+#include <init.h>
+#include <io.h>
+
+#include "ar231x.h"
+
+static inline void dma_writel(struct ar231x_eth_priv *priv,
+ u32 val, int reg)
+{
+ __raw_writel(val, priv->dma_regs + reg);
+}
+
+static inline u32 dma_readl(struct ar231x_eth_priv *priv, int reg)
+{
+ return __raw_readl(priv->dma_regs + reg);
+}
+
+static inline void eth_writel(struct ar231x_eth_priv *priv,
+ u32 val, int reg)
+{
+ __raw_writel(val, priv->eth_regs + reg);
+}
+
+static inline u32 eth_readl(struct ar231x_eth_priv *priv, int reg)
+{
+ return __raw_readl(priv->eth_regs + reg);
+}
+
+static inline void phy_writel(struct ar231x_eth_priv *priv,
+ u32 val, int reg)
+{
+ __raw_writel(val, priv->phy_regs + reg);
+}
+
+static inline u32 phy_readl(struct ar231x_eth_priv *priv, int reg)
+{
+ return __raw_readl(priv->phy_regs + reg);
+}
+
+static void ar231x_reset_bit_(struct ar231x_eth_priv *priv,
+ u32 val, enum reset_state state)
+{
+ if (priv->reset_bit)
+ (*priv->reset_bit)(val, state);
+}
+
+static int ar231x_set_ethaddr(struct eth_device *edev, unsigned char *addr);
+static void ar231x_reset_regs(struct eth_device *edev)
+{
+ struct ar231x_eth_priv *priv = edev->priv;
+ struct ar231x_eth_platform_data *cfg = priv->cfg;
+ u32 flags;
+
+ ar231x_reset_bit_(priv, cfg->reset_mac, SET);
+ mdelay(10);
+
+ ar231x_reset_bit_(priv, cfg->reset_mac, REMOVE);
+ mdelay(10);
+
+ ar231x_reset_bit_(priv, cfg->reset_phy, SET);
+ mdelay(10);
+
+ ar231x_reset_bit_(priv, cfg->reset_phy, REMOVE);
+ mdelay(10);
+
+ dma_writel(priv, DMA_BUS_MODE_SWR, AR231X_DMA_BUS_MODE);
+ mdelay(10);
+
+ dma_writel(priv, ((32 << DMA_BUS_MODE_PBL_SHIFT) | DMA_BUS_MODE_BLE),
+ AR231X_DMA_BUS_MODE);
+
+ /* FIXME: priv->{t,r}x_ring are virtual addresses,
+ * use virt-to-phys convertion */
+ dma_writel(priv, (u32)priv->tx_ring, AR231X_DMA_TX_RING);
+ dma_writel(priv, (u32)priv->rx_ring, AR231X_DMA_RX_RING);
+
+ dma_writel(priv, (DMA_CONTROL_SR | DMA_CONTROL_ST | DMA_CONTROL_SF),
+ AR231X_DMA_CONTROL);
+
+ eth_writel(priv, FLOW_CONTROL_FCE, AR231X_ETH_FLOW_CONTROL);
+ /* TODO: not sure if we need it here. */
+ eth_writel(priv, 0x8100, AR231X_ETH_VLAN_TAG);
+
+ /* Enable Ethernet Interface */
+ flags = (MAC_CONTROL_TE | /* transmit enable */
+ /* FIXME: MAC_CONTROL_PM - pass mcast.
+ * Seems like it makes no difference on some WiSoCs,
+ * for example ar2313.
+ * It should be tested on ar231[5,6,7] */
+ MAC_CONTROL_PM |
+ MAC_CONTROL_F | /* full duplex */
+ MAC_CONTROL_HBD); /* heart beat disabled */
+ eth_writel(priv, flags, AR231X_ETH_MAC_CONTROL);
+}
+
+static void ar231x_flash_rxdsc(struct ar231x_descr *rxdsc)
+{
+ rxdsc->status = DMA_RX_OWN;
+ rxdsc->devcs = ((AR2313_RX_BUFSIZE << DMA_RX1_BSIZE_SHIFT) |
+ DMA_RX1_CHAINED);
+}
+
+static void ar231x_allocate_dma_descriptors(struct eth_device *edev)
+{
+ struct ar231x_eth_priv *priv = edev->priv;
+ u16 ar231x_descr_size = sizeof(struct ar231x_descr);
+ u16 i;
+
+ priv->tx_ring = xmalloc(ar231x_descr_size);
+ dev_dbg(&edev->dev, "allocate tx_ring @ %p\n", priv->tx_ring);
+
+ priv->rx_ring = xmalloc(ar231x_descr_size * AR2313_RXDSC_ENTRIES);
+ dev_dbg(&edev->dev, "allocate rx_ring @ %p\n", priv->rx_ring);
+
+ priv->rx_buffer = xmalloc(AR2313_RX_BUFSIZE * AR2313_RXDSC_ENTRIES);
+ dev_dbg(&edev->dev, "allocate rx_buffer @ %p\n", priv->rx_buffer);
+
+ /* Initialize the rx Descriptors */
+ for (i = 0; i < AR2313_RXDSC_ENTRIES; i++) {
+ struct ar231x_descr *rxdsc = &priv->rx_ring[i];
+ ar231x_flash_rxdsc(rxdsc);
+ rxdsc->buffer_ptr =
+ (u32)(priv->rx_buffer + AR2313_RX_BUFSIZE * i);
+ rxdsc->next_dsc_ptr = (u32)&priv->rx_ring[DSC_NEXT(i)];
+ }
+ /* set initial position of ring descriptor */
+ priv->next_rxdsc = &priv->rx_ring[0];
+}
+
+static void ar231x_adjust_link(struct eth_device *edev)
+{
+ struct ar231x_eth_priv *priv = edev->priv;
+ u32 mc;
+
+ if (edev->phydev->duplex != priv->oldduplex) {
+ mc = eth_readl(priv, AR231X_ETH_MAC_CONTROL);
+ mc &= ~(MAC_CONTROL_F | MAC_CONTROL_DRO);
+ if (edev->phydev->duplex)
+ mc |= MAC_CONTROL_F;
+ else
+ mc |= MAC_CONTROL_DRO;
+ eth_writel(priv, mc, AR231X_ETH_MAC_CONTROL);
+ priv->oldduplex = edev->phydev->duplex;
+ }
+}
+
+static int ar231x_eth_init(struct eth_device *edev)
+{
+ struct ar231x_eth_priv *priv = edev->priv;
+
+ ar231x_allocate_dma_descriptors(edev);
+ ar231x_reset_regs(edev);
+ ar231x_set_ethaddr(edev, priv->mac);
+ return 0;
+}
+
+static int ar231x_eth_open(struct eth_device *edev)
+{
+ struct ar231x_eth_priv *priv = edev->priv;
+ u32 tmp;
+
+ /* Enable RX. Now the rx_buffer will be filled.
+ * If it is full we may lose first transmission. In this case
+ * barebox should retry it.
+ * Or TODO: - force HW to filter some how broadcasts
+ * - disable RX if we do not need it. */
+ tmp = eth_readl(priv, AR231X_ETH_MAC_CONTROL);
+ eth_writel(priv, (tmp | MAC_CONTROL_RE), AR231X_ETH_MAC_CONTROL);
+
+ return phy_device_connect(edev, &priv->miibus, (int)priv->phy_regs,
+ ar231x_adjust_link, 0, PHY_INTERFACE_MODE_MII);
+}
+
+static int ar231x_eth_recv(struct eth_device *edev)
+{
+ struct ar231x_eth_priv *priv = edev->priv;
+
+ while (1) {
+ struct ar231x_descr *rxdsc = priv->next_rxdsc;
+ u32 status = rxdsc->status;
+
+ /* owned by DMA? */
+ if (status & DMA_RX_OWN)
+ break;
+
+ /* Pick only packets what we can handle:
+ * - only complete packet per buffer
+ * (First and Last at same time)
+ * - drop multicast */
+ if (!priv->kill_rx_ring &&
+ ((status & DMA_RX_MASK) == DMA_RX_FSLS)) {
+ u16 length =
+ ((status >> DMA_RX_LEN_SHIFT) & 0x3fff)
+ - CRC_LEN;
+ net_receive((void *)rxdsc->buffer_ptr, length);
+ }
+ /* Clean descriptor. now it is owned by DMA. */
+ priv->next_rxdsc = (struct ar231x_descr *)rxdsc->next_dsc_ptr;
+ ar231x_flash_rxdsc(rxdsc);
+ }
+ priv->kill_rx_ring = 0;
+ return 0;
+}
+
+static int ar231x_eth_send(struct eth_device *edev, void *packet,
+ int length)
+{
+ struct ar231x_eth_priv *priv = edev->priv;
+ struct ar231x_descr *txdsc = priv->tx_ring;
+ u32 rx_missed;
+
+ /* We do not do async work.
+ * If rx_ring is full, there is nothing we can use. */
+ rx_missed = dma_readl(priv, AR231X_DMA_RX_MISSED);
+ if (rx_missed) {
+ priv->kill_rx_ring = 1;
+ ar231x_eth_recv(edev);
+ }
+
+ /* Setup the transmit descriptor. */
+ txdsc->devcs = ((length << DMA_TX1_BSIZE_SHIFT) | DMA_TX1_DEFAULT);
+ txdsc->buffer_ptr = (uint)packet;
+ txdsc->status = DMA_TX_OWN;
+
+ /* Trigger transmission */
+ dma_writel(priv, 0, AR231X_DMA_TX_POLL);
+
+ /* Take enough time to transmit packet. 100 is not enough. */
+ wait_on_timeout(2000 * MSECOND,
+ !(txdsc->status & DMA_TX_OWN));
+
+ /* We can't do match here. If it is still in progress,
+ * then engine is probably stalled or we wait not enough. */
+ if (txdsc->status & DMA_TX_OWN)
+ dev_err(&edev->dev, "Frame is still in progress.\n");
+
+ if (txdsc->status & DMA_TX_ERROR)
+ dev_err(&edev->dev, "Frame was aborted by engine\n");
+
+ /* Ready or not. Stop it. */
+ txdsc->status = 0;
+ return 0;
+}
+
+static void ar231x_eth_halt(struct eth_device *edev)
+{
+ struct ar231x_eth_priv *priv = edev->priv;
+ u32 tmp;
+
+ /* kill the MAC: disable RX and TX */
+ tmp = eth_readl(priv, AR231X_ETH_MAC_CONTROL);
+ eth_writel(priv, tmp & ~(MAC_CONTROL_RE | MAC_CONTROL_TE),
+ AR231X_ETH_MAC_CONTROL);
+
+ /* stop DMA */
+ dma_writel(priv, 0, AR231X_DMA_CONTROL);
+ dma_writel(priv, DMA_BUS_MODE_SWR, AR231X_DMA_BUS_MODE);
+
+ /* place PHY and MAC in reset */
+ ar231x_reset_bit_(priv, (priv->cfg->reset_mac | priv->cfg->reset_phy), SET);
+}
+
+static int ar231x_get_ethaddr(struct eth_device *edev, unsigned char *addr)
+{
+ struct ar231x_eth_priv *priv = edev->priv;
+
+ /* MAC address is stored on flash, in some kind of atheros config
+ * area. Platform code should read it and pass to the driver. */
+ memcpy(addr, priv->mac, 6);
+ return 0;
+}
+
+/**
+ * These device do not have build in MAC address.
+ * It is located on atheros-config field on flash.
+ */
+static int ar231x_set_ethaddr(struct eth_device *edev, unsigned char *addr)
+{
+ struct ar231x_eth_priv *priv = edev->priv;
+
+ eth_writel(priv,
+ (addr[5] << 8) | (addr[4]),
+ AR231X_ETH_MAC_ADDR1);
+ eth_writel(priv,
+ (addr[3] << 24) | (addr[2] << 16) |
+ (addr[1] << 8) | addr[0],
+ AR231X_ETH_MAC_ADDR2);
+
+ mdelay(10);
+ return 0;
+}
+
+#define MII_ADDR(phy, reg) \
+ ((reg << MII_ADDR_REG_SHIFT) | (phy << MII_ADDR_PHY_SHIFT))
+
+static int ar231x_miibus_read(struct mii_bus *bus, int phy_id, int regnum)
+{
+ struct ar231x_eth_priv *priv = bus->priv;
+ uint64_t time_start;
+
+ phy_writel(priv, MII_ADDR(phy_id, regnum), AR231X_ETH_MII_ADDR);
+ time_start = get_time_ns();
+ while (phy_readl(priv, AR231X_ETH_MII_ADDR) & MII_ADDR_BUSY) {
+ if (is_timeout(time_start, SECOND)) {
+ dev_err(&bus->dev, "miibus read timeout\n");
+ return -ETIMEDOUT;
+ }
+ }
+ return phy_readl(priv, AR231X_ETH_MII_DATA) >> MII_DATA_SHIFT;
+}
+
+static int ar231x_miibus_write(struct mii_bus *bus, int phy_id,
+ int regnum, u16 val)
+{
+ struct ar231x_eth_priv *priv = bus->priv;
+ uint64_t time_start = get_time_ns();
+
+ while (phy_readl(priv, AR231X_ETH_MII_ADDR) & MII_ADDR_BUSY) {
+ if (is_timeout(time_start, SECOND)) {
+ dev_err(&bus->dev, "miibus write timeout\n");
+ return -ETIMEDOUT;
+ }
+ }
+ phy_writel(priv, val << MII_DATA_SHIFT, AR231X_ETH_MII_DATA);
+ phy_writel(priv, MII_ADDR(phy_id, regnum) | MII_ADDR_WRITE,
+ AR231X_ETH_MII_ADDR);
+ return 0;
+}
+
+static int ar231x_mdiibus_reset(struct mii_bus *bus)
+{
+ struct ar231x_eth_priv *priv = bus->priv;
+
+ ar231x_reset_regs(&priv->edev);
+ return 0;
+}
+
+static int ar231x_eth_probe(struct device_d *dev)
+{
+ struct ar231x_eth_priv *priv;
+ struct eth_device *edev;
+ struct mii_bus *miibus;
+ struct ar231x_eth_platform_data *pdata;
+
+ if (!dev->platform_data) {
+ dev_err(dev, "no platform data\n");
+ return -ENODEV;
+ }
+
+ pdata = dev->platform_data;
+
+ priv = xzalloc(sizeof(struct ar231x_eth_priv));
+ edev = &priv->edev;
+ miibus = &priv->miibus;
+ edev->priv = priv;
+
+ /* link all platform depended regs */
+ priv->mac = pdata->mac;
+ priv->reset_bit = pdata->reset_bit;
+
+ priv->eth_regs = dev_request_mem_region(dev, 0);
+ if (priv->eth_regs == NULL) {
+ dev_err(dev, "No eth_regs!!\n");
+ return -ENODEV;
+ }
+ /* we have 0x100000 for eth, part of it are dma regs.
+ * So they are already requested */
+ priv->dma_regs = (void *)(priv->eth_regs + 0x1000);
+
+ priv->phy_regs = dev_request_mem_region(dev, 1);
+ if (priv->phy_regs == NULL) {
+ dev_err(dev, "No phy_regs!!\n");
+ return -ENODEV;
+ }
+
+ priv->cfg = pdata;
+ edev->init = ar231x_eth_init;
+ edev->open = ar231x_eth_open;
+ edev->send = ar231x_eth_send;
+ edev->recv = ar231x_eth_recv;
+ edev->halt = ar231x_eth_halt;
+ edev->get_ethaddr = ar231x_get_ethaddr;
+ edev->set_ethaddr = ar231x_set_ethaddr;
+
+ priv->miibus.read = ar231x_miibus_read;
+ priv->miibus.write = ar231x_miibus_write;
+ priv->miibus.reset = ar231x_mdiibus_reset;
+ priv->miibus.priv = priv;
+ priv->miibus.parent = dev;
+
+ mdiobus_register(miibus);
+ eth_register(edev);
+
+ return 0;
+}
+
+static void ar231x_eth_remove(struct device_d *dev)
+{
+
+}
+
+static struct driver_d ar231x_eth_driver = {
+ .name = "ar231x_eth",
+ .probe = ar231x_eth_probe,
+ .remove = ar231x_eth_remove,
+};
+
+static int ar231x_eth_driver_init(void)
+{
+ return platform_driver_register(&ar231x_eth_driver);
+}
+device_initcall(ar231x_eth_driver_init);
diff --git a/drivers/net/ar231x.h b/drivers/net/ar231x.h
new file mode 100644
index 0000000000..24684127cc
--- /dev/null
+++ b/drivers/net/ar231x.h
@@ -0,0 +1,219 @@
+/*
+ * ar231x.h: Linux driver for the Atheros AR231x Ethernet device.
+ * Based on Linux driver:
+ * Copyright (C) 2004 by Sameer Dekate <sdekate@arubanetworks.com>
+ * Copyright (C) 2006 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (C) 2006-2009 Felix Fietkau <nbd@openwrt.org>
+ * Ported to Barebox:
+ * Copyright (C) 2013 Oleksij Rempel <linux@rempel-privat.de>
+ *
+ * Thanks to Atheros for providing hardware and documentation
+ * enabling me to write this driver.
+ *
+ * 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.
+ */
+
+#ifndef _AR2313_2_H_
+#define _AR2313_2_H_
+
+#include <net.h>
+#include <mach/ar231x_platform.h>
+
+/* Allocate 64 RX buffers. This will reduce packet loss, until we will start
+ * processing them. It is important in noisy network with lots of broadcasts. */
+#define AR2313_RXDSC_ENTRIES 64
+#define DSC_NEXT(idx) (((idx) + 1) & (AR2313_RXDSC_ENTRIES - 1))
+
+/* Use system default buffers size. At the moment of writing it was 1518 */
+#define AR2313_RX_BUFSIZE PKTSIZE
+#define CRC_LEN 4
+
+/**
+ * DMA controller
+ */
+#define AR231X_DMA_BUS_MODE 0x00 /* (CSR0) */
+#define AR231X_DMA_TX_POLL 0x04 /* (CSR1) */
+#define AR231X_DMA_RX_POLL 0x08 /* (CSR2) */
+#define AR231X_DMA_RX_RING 0x0c /* (CSR3) */
+#define AR231X_DMA_TX_RING 0x10 /* (CSR4) */
+#define AR231X_DMA_STATUS 0x14 /* (CSR5) */
+#define AR231X_DMA_CONTROL 0x18 /* (CSR6) */
+#define AR231X_DMA_INTR_ENA 0x1c /* (CSR7) */
+#define AR231X_DMA_RX_MISSED 0x20 /* (CSR8) */
+/* reserverd 0x24-0x4c (CSR9-19) */
+#define AR231X_DMA_CUR_TX_BUF_ADDR 0x50 /* (CSR20) */
+#define AR231X_DMA_CUR_RX_BUF_ADDR 0x54 /* (CSR21) */
+
+/**
+ * Ethernet controller
+ */
+#define AR231X_ETH_MAC_CONTROL 0x00
+#define AR231X_ETH_MAC_ADDR1 0x04
+#define AR231X_ETH_MAC_ADDR2 0x08
+#define AR231X_ETH_MCAST_TABLE1 0x0c
+#define AR231X_ETH_MCAST_TABLE2 0x10
+#define AR231X_ETH_MII_ADDR 0x14
+#define AR231X_ETH_MII_DATA 0x18
+#define AR231X_ETH_FLOW_CONTROL 0x1c
+#define AR231X_ETH_VLAN_TAG 0x20
+/* pad 0x24 - 0x3c */
+/* ucast_table 0x40-0x5c */
+
+/**
+ * RX descriptor status bits. ar231x_descr.status
+ */
+#define DMA_RX_ERR_CRC BIT(1)
+#define DMA_RX_ERR_DRIB BIT(2)
+#define DMA_RX_ERR_MII BIT(3)
+#define DMA_RX_EV2 BIT(5)
+#define DMA_RX_ERR_COL BIT(6)
+#define DMA_RX_LONG BIT(7)
+#define DMA_RX_LS BIT(8) /* last descriptor */
+#define DMA_RX_FS BIT(9) /* first descriptor */
+#define DMA_RX_MF BIT(10) /* multicast frame */
+#define DMA_RX_ERR_RUNT BIT(11) /* runt frame */
+#define DMA_RX_ERR_LENGTH BIT(12) /* length error */
+#define DMA_RX_ERR_DESC BIT(14) /* descriptor error */
+#define DMA_RX_ERROR BIT(15) /* error summary */
+#define DMA_RX_LEN_MASK 0x3fff0000
+#define DMA_RX_LEN_SHIFT 16
+#define DMA_RX_FILT BIT(30)
+#define DMA_RX_OWN BIT(31) /* desc owned by DMA controller */
+#define DMA_RX_FSLS (DMA_RX_LS | DMA_RX_FS)
+#define DMA_RX_MASK (DMA_RX_FSLS | DMA_RX_MF | DMA_RX_ERROR)
+
+/**
+ * RX descriptor configuration bits. ar231x_descr.devcs
+ */
+#define DMA_RX1_BSIZE_MASK 0x000007ff
+#define DMA_RX1_BSIZE_SHIFT 0
+#define DMA_RX1_CHAINED BIT(24)
+#define DMA_RX1_RER BIT(25)
+
+/**
+ * TX descriptor status fields. ar231x_descr.status
+ */
+#define DMA_TX_ERR_UNDER BIT(1) /* underflow error */
+#define DMA_TX_ERR_DEFER BIT(2) /* excessive deferral */
+#define DMA_TX_COL_MASK 0x78
+#define DMA_TX_COL_SHIFT 3
+#define DMA_TX_ERR_HB BIT(7) /* hearbeat failure */
+#define DMA_TX_ERR_COL BIT(8) /* excessive collisions */
+#define DMA_TX_ERR_LATE BIT(9) /* late collision */
+#define DMA_TX_ERR_LINK BIT(10) /* no carrier */
+#define DMA_TX_ERR_LOSS BIT(11) /* loss of carrier */
+#define DMA_TX_ERR_JABBER BIT(14) /* transmit jabber timeout */
+#define DMA_TX_ERROR BIT(15) /* frame aborted */
+#define DMA_TX_OWN BIT(31) /* descr owned by DMA controller */
+
+/**
+ * TX descriptor configuration bits. ar231x_descr.devcs
+ */
+#define DMA_TX1_BSIZE_MASK 0x000007ff
+#define DMA_TX1_BSIZE_SHIFT 0
+#define DMA_TX1_CHAINED BIT(24) /* chained descriptors */
+#define DMA_TX1_TER BIT(25) /* transmit end of ring */
+#define DMA_TX1_FS BIT(29) /* first segment */
+#define DMA_TX1_LS BIT(30) /* last segment */
+#define DMA_TX1_IC BIT(31) /* interrupt on completion */
+#define DMA_TX1_DEFAULT (DMA_TX1_FS | DMA_TX1_LS | DMA_TX1_TER)
+
+#define MAC_CONTROL_RE BIT(2) /* receive enable */
+#define MAC_CONTROL_TE BIT(3) /* transmit enable */
+#define MAC_CONTROL_DC BIT(5) /* Deferral check */
+#define MAC_CONTROL_ASTP BIT(8) /* Auto pad strip */
+#define MAC_CONTROL_DRTY BIT(10) /* Disable retry */
+#define MAC_CONTROL_DBF BIT(11) /* Disable bcast frames */
+#define MAC_CONTROL_LCC BIT(12) /* late collision ctrl */
+#define MAC_CONTROL_HP BIT(13) /* Hash Perfect filtering */
+#define MAC_CONTROL_HASH BIT(14) /* Unicast hash filtering */
+#define MAC_CONTROL_HO BIT(15) /* Hash only filtering */
+#define MAC_CONTROL_PB BIT(16) /* Pass Bad frames */
+#define MAC_CONTROL_IF BIT(17) /* Inverse filtering */
+#define MAC_CONTROL_PR BIT(18) /* promiscuous mode
+ * (valid frames only) */
+#define MAC_CONTROL_PM BIT(19) /* pass multicast */
+#define MAC_CONTROL_F BIT(20) /* full-duplex */
+#define MAC_CONTROL_DRO BIT(23) /* Disable Receive Own */
+#define MAC_CONTROL_HBD BIT(28) /* heart-beat disabled (MUST BE SET) */
+#define MAC_CONTROL_BLE BIT(30) /* big endian mode */
+#define MAC_CONTROL_RA BIT(31) /* receive all
+ * (valid and invalid frames) */
+
+#define MII_ADDR_BUSY BIT(0)
+#define MII_ADDR_WRITE BIT(1)
+#define MII_ADDR_REG_SHIFT 6
+#define MII_ADDR_PHY_SHIFT 11
+#define MII_DATA_SHIFT 0
+
+#define FLOW_CONTROL_FCE BIT(1)
+
+#define DMA_BUS_MODE_SWR BIT(0) /* software reset */
+#define DMA_BUS_MODE_BLE BIT(7) /* big endian mode */
+#define DMA_BUS_MODE_PBL_SHIFT 8 /* programmable burst length 32 */
+#define DMA_BUS_MODE_DBO BIT(20) /* big-endian descriptors */
+
+#define DMA_STATUS_TI BIT(0) /* transmit interrupt */
+#define DMA_STATUS_TPS BIT(1) /* transmit process stopped */
+#define DMA_STATUS_TU BIT(2) /* transmit buffer unavailable */
+#define DMA_STATUS_TJT BIT(3) /* transmit buffer timeout */
+#define DMA_STATUS_UNF BIT(5) /* transmit underflow */
+#define DMA_STATUS_RI BIT(6) /* receive interrupt */
+#define DMA_STATUS_RU BIT(7) /* receive buffer unavailable */
+#define DMA_STATUS_RPS BIT(8) /* receive process stopped */
+#define DMA_STATUS_ETI BIT(10) /* early transmit interrupt */
+#define DMA_STATUS_FBE BIT(13) /* fatal bus interrupt */
+#define DMA_STATUS_ERI BIT(14) /* early receive interrupt */
+#define DMA_STATUS_AIS BIT(15) /* abnormal interrupt summary */
+#define DMA_STATUS_NIS BIT(16) /* normal interrupt summary */
+#define DMA_STATUS_RS_SHIFT 17 /* receive process state */
+#define DMA_STATUS_TS_SHIFT 20 /* transmit process state */
+#define DMA_STATUS_EB_SHIFT 23 /* error bits */
+
+#define DMA_CONTROL_SR BIT(1) /* start receive */
+#define DMA_CONTROL_ST BIT(13) /* start transmit */
+#define DMA_CONTROL_SF BIT(21) /* store and forward */
+
+
+struct ar231x_descr {
+ u32 status; /* OWN, Device control and status. */
+ u32 devcs; /* Packet control bitmap + Length. */
+ u32 buffer_ptr; /* Pointer to packet buffer. */
+ u32 next_dsc_ptr; /* Pointer to next descriptor in chain. */
+};
+
+/**
+ * Struct private for the Sibyte.
+ *
+ * Elements are grouped so variables used by the tx handling goes
+ * together, and will go into the same cache lines etc. in order to
+ * avoid cache line contention between the rx and tx handling on SMP.
+ *
+ * Frequently accessed variables are put at the beginning of the
+ * struct to help the compiler generate better/shorter code.
+ */
+struct ar231x_eth_priv {
+ struct ar231x_eth_platform_data *cfg;
+ u8 *mac;
+ void __iomem *phy_regs;
+ void __iomem *eth_regs;
+ void __iomem *dma_regs;
+ void __iomem *reset_regs;
+
+ struct eth_device edev;
+ struct mii_bus miibus;
+
+ struct ar231x_descr *tx_ring;
+ struct ar231x_descr *rx_ring;
+ struct ar231x_descr *next_rxdsc;
+ u8 kill_rx_ring;
+ void *rx_buffer;
+
+ int oldduplex;
+ void (*reset_bit)(u32 val, enum reset_state state);
+};
+
+#endif /* _AR2313_H_ */
diff --git a/drivers/net/cs8900.c b/drivers/net/cs8900.c
index b0d045a4e9..aa9d9a0798 100644
--- a/drivers/net/cs8900.c
+++ b/drivers/net/cs8900.c
@@ -459,6 +459,8 @@ static int cs8900_probe(struct device_d *dev)
edev->set_ethaddr = cs8900_set_ethaddr;
edev->parent = dev;
+ dev->info = cs8900_info;
+
eth_register(edev);
return 0;
}
@@ -466,6 +468,5 @@ static int cs8900_probe(struct device_d *dev)
static struct driver_d cs8900_driver = {
.name = "cs8900",
.probe = cs8900_probe,
- .info = cs8900_info,
};
device_platform_driver(cs8900_driver);
diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 1a85d15b7b..1346c91348 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -707,6 +707,7 @@ static int fec_probe(struct device_d *dev)
if (dev->device_node) {
ret = fec_probe_dt(dev, fec);
+ fec->phy_addr = -1;
} else if (pdata) {
fec->interface = pdata->xcv_type;
fec->phy_init = pdata->phy_init;
@@ -746,6 +747,9 @@ static void fec_remove(struct device_d *dev)
static __maybe_unused struct of_device_id imx_fec_dt_ids[] = {
{
+ .compatible = "fsl,imx25-fec",
+ .data = FEC_TYPE_IMX27,
+ }, {
.compatible = "fsl,imx27-fec",
.data = FEC_TYPE_IMX27,
}, {
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig
index 56762e4f63..ffe063e0b7 100644
--- a/drivers/of/Kconfig
+++ b/drivers/of/Kconfig
@@ -1,6 +1,11 @@
config OFTREE
bool
+config OFTREE_MEM_GENERIC
+ depends on OFTREE
+ depends on PPC || ARM
+ def_bool y
+
config DTC
bool
diff --git a/drivers/of/Makefile b/drivers/of/Makefile
index d16a94624d..c81bbec89b 100644
--- a/drivers/of/Makefile
+++ b/drivers/of/Makefile
@@ -1,4 +1,5 @@
obj-y += base.o fdt.o
+obj-$(CONFIG_OFTREE_MEM_GENERIC) += mem_generic.o
obj-$(CONFIG_GPIOLIB) += gpio.o
obj-y += partition.o
obj-y += of_net.o
diff --git a/drivers/of/base.c b/drivers/of/base.c
index 8383549821..4241e65b3f 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -145,6 +145,9 @@ static void of_alias_scan(void)
INIT_LIST_HEAD(&aliases_lookup);
+ if (!root_node)
+ return;
+
of_aliases = of_find_node_by_path(root_node, "/aliases");
if (!of_aliases)
return;
@@ -212,6 +215,19 @@ int of_alias_get_id(struct device_node *np, const char *stem)
}
EXPORT_SYMBOL_GPL(of_alias_get_id);
+const char *of_alias_get(struct device_node *np)
+{
+ struct property *pp;
+
+ list_for_each_entry(pp, &of_aliases->properties, list) {
+ if (!strcmp(np->full_name, pp->value))
+ return pp->name;
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(of_alias_get);
+
u64 of_translate_address(struct device_node *node, const __be32 *in_addr)
{
struct property *p;
@@ -295,21 +311,36 @@ int of_device_is_compatible(const struct device_node *device,
}
EXPORT_SYMBOL(of_device_is_compatible);
+/**
+ * of_match_node - Tell if an device_node has a matching of_match structure
+ * @matches: array of of device match structures to search in
+ * @node: the of device structure to match against
+ *
+ * Low level utility function used by device matching.
+ */
+const struct of_device_id *of_match_node(const struct of_device_id *matches,
+ const struct device_node *node)
+{
+ while (matches->compatible) {
+ if (of_device_is_compatible(node, matches->compatible) == 1)
+ return matches;
+ matches++;
+ }
+
+ return NULL;
+}
+
int of_match(struct device_d *dev, struct driver_d *drv)
{
- struct of_device_id *id;
+ const struct of_device_id *id;
- id = drv->of_compatible;
+ id = of_match_node(drv->of_compatible, dev->device_node);
+ if (!id)
+ return 1;
- while (id->compatible) {
- if (of_device_is_compatible(dev->device_node, id->compatible) == 1) {
- dev->of_id_entry = id;
- return 0;
- }
- id++;
- }
+ dev->of_id_entry = id;
- return 1;
+ return 0;
}
EXPORT_SYMBOL(of_match);
@@ -625,6 +656,33 @@ int of_property_read_string_index(struct device_node *np, const char *propname,
}
EXPORT_SYMBOL_GPL(of_property_read_string_index);
+/**
+ * of_modalias_node - Lookup appropriate modalias for a device node
+ * @node: pointer to a device tree node
+ * @modalias: Pointer to buffer that modalias value will be copied into
+ * @len: Length of modalias value
+ *
+ * Based on the value of the compatible property, this routine will attempt
+ * to choose an appropriate modalias value for a particular device tree node.
+ * It does this by stripping the manufacturer prefix (as delimited by a ',')
+ * from the first entry in the compatible list property.
+ *
+ * This routine returns 0 on success, <0 on failure.
+ */
+int of_modalias_node(struct device_node *node, char *modalias, int len)
+{
+ const char *compatible, *p;
+ int cplen;
+
+ compatible = of_get_property(node, "compatible", &cplen);
+ if (!compatible || strlen(compatible) > cplen)
+ return -ENODEV;
+ p = strchr(compatible, ',');
+ strlcpy(modalias, p ? p + 1 : compatible, len);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(of_modalias_node);
+
struct device_node *of_get_root_node(void)
{
return root_node;
@@ -663,9 +721,6 @@ void of_print_nodes(struct device_node *node, int indent)
if (!node)
return;
- if (of_node_disabled(node))
- return;
-
for (i = 0; i < indent; i++)
printf("\t");
@@ -810,13 +865,16 @@ static struct device_d *add_of_amba_device(struct device_node *node)
return &dev->dev;
}
-static struct device_d *add_of_platform_device(struct device_node *node)
+static struct device_d *add_of_platform_device(struct device_node *node,
+ struct device_d *parent)
{
struct device_d *dev;
char *name, *at;
dev = xzalloc(sizeof(*dev));
+ dev->parent = parent;
+
name = xstrdup(node->name);
at = strchr(name, '@');
if (at) {
@@ -841,7 +899,8 @@ static struct device_d *add_of_platform_device(struct device_node *node)
return dev;
}
-static struct device_d *add_of_device(struct device_node *node)
+static struct device_d *add_of_device(struct device_node *node,
+ struct device_d *parent)
{
const struct property *cp;
@@ -856,7 +915,7 @@ static struct device_d *add_of_device(struct device_node *node)
of_device_is_compatible(node, "arm,primecell") == 1)
return add_of_amba_device(node);
else
- return add_of_platform_device(node);
+ return add_of_platform_device(node, parent);
}
EXPORT_SYMBOL(add_of_device);
@@ -873,7 +932,6 @@ int of_add_memory(struct device_node *node, bool dump)
int na, nc;
const __be32 *reg, *endp;
int len, r = 0, ret;
- static char str[6];
const char *device_type;
ret = of_property_read_string(node, "device_type", &device_type);
@@ -900,12 +958,7 @@ int of_add_memory(struct device_node *node, bool dump)
if (size == 0)
continue;
- sprintf(str, "ram%d", r);
-
- barebox_add_memory_bank(str, base, size);
-
- if (dump)
- pr_info("%s: %s: 0x%llx@0x%llx\n", node->name, str, size, base);
+ of_add_memory_bank(node, dump, r, base, size);
r++;
}
@@ -913,7 +966,8 @@ int of_add_memory(struct device_node *node, bool dump)
return 0;
}
-static int add_of_device_resource(struct device_node *node)
+static struct device_d *add_of_device_resource(struct device_node *node,
+ struct device_d *parent)
{
u64 address = 0, size;
struct resource *res, *resp;
@@ -923,13 +977,9 @@ static int add_of_device_resource(struct device_node *node)
int na, nc, n_resources;
int ret, len, index;
- ret = of_add_memory(node, false);
- if (ret != -ENXIO)
- return ret;
-
reg = of_get_property(node, "reg", &len);
if (!reg)
- return -EINVAL;
+ return add_of_device(node, parent);
of_bus_count_cells(node, &na, &nc);
@@ -970,7 +1020,8 @@ static int add_of_device_resource(struct device_node *node)
for_each_device(dev) {
if (!dev->resource)
continue;
- if (dev->resource->start == address) {
+ if (dev->resource->start == res->start &&
+ dev->resource->end == res->end) {
debug("connecting %s to %s\n", node->name, dev_name(dev));
node->device = dev;
dev->device_node = node;
@@ -983,14 +1034,12 @@ static int add_of_device_resource(struct device_node *node)
node->resource = res;
node->num_resource = n_resources;
- add_of_device(node);
-
- return 0;
+ return add_of_device(node, parent);
err_free:
free(res);
- return ret;
+ return NULL;
}
void of_free(struct device_node *node)
@@ -1030,17 +1079,23 @@ void of_free(struct device_node *node)
of_set_root_node(NULL);
}
-static void __of_probe(struct device_node *node)
+static void __of_probe(struct device_node *node,
+ const struct of_device_id *matches,
+ struct device_d *parent)
{
struct device_node *n;
+ struct device_d *dev;
if (node->device)
return;
- add_of_device_resource(node);
+ dev = add_of_device_resource(node, parent);
+
+ if (!of_match_node(matches, node))
+ return;
list_for_each_entry(n, &node->children, parent_list)
- __of_probe(n);
+ __of_probe(n, matches, dev);
}
static void __of_parse_phandles(struct device_node *node)
@@ -1067,8 +1122,18 @@ const char *of_get_model(void)
return of_model;
}
+const struct of_device_id of_default_bus_match_table[] = {
+ {
+ .compatible = "simple-bus",
+ }, {
+ /* sentinel */
+ }
+};
+
int of_probe(void)
{
+ struct device_node *memory, *n;
+
if(!root_node)
return -ENODEV;
@@ -1076,7 +1141,13 @@ int of_probe(void)
of_property_read_string(root_node, "model", &of_model);
__of_parse_phandles(root_node);
- __of_probe(root_node);
+
+ memory = of_find_node_by_path(root_node, "/memory");
+ if (memory)
+ of_add_memory(memory, false);
+
+ list_for_each_entry(n, &root_node->children, parent_list)
+ __of_probe(n, of_default_bus_match_table, NULL);
return 0;
}
diff --git a/drivers/of/mem_generic.c b/drivers/of/mem_generic.c
new file mode 100644
index 0000000000..9094243c04
--- /dev/null
+++ b/drivers/of/mem_generic.c
@@ -0,0 +1,15 @@
+#include <common.h>
+#include <of.h>
+#include <memory.h>
+
+void of_add_memory_bank(struct device_node *node, bool dump, int r,
+ u64 base, u64 size)
+{
+ static char str[6];
+
+ sprintf(str, "ram%d", r);
+ barebox_add_memory_bank(str, base, size);
+
+ if (dump)
+ pr_info("%s: %s: 0x%llx@0x%llx\n", node->name, str, size, base);
+}
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index e6aee50a5f..0b859b8494 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -25,4 +25,10 @@ config PINCTRL_IMX_IOMUX_V3
help
This iomux controller is found on i.MX25,35,51,53,6.
+config PINCTRL_TEGRA20
+ select PINCTRL
+ bool "Tegra 20 pinmux"
+ help
+ The pinmux controller found on the Tegra 20 line of SoCs.
+
endmenu
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index e9272d0fb0..169ed184c7 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -2,3 +2,4 @@ obj-$(CONFIG_PINCTRL) += pinctrl.o
obj-$(CONFIG_PINCTRL_IMX_IOMUX_V1) += imx-iomux-v1.o
obj-$(CONFIG_PINCTRL_IMX_IOMUX_V2) += imx-iomux-v2.o
obj-$(CONFIG_PINCTRL_IMX_IOMUX_V3) += imx-iomux-v3.o
+obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
diff --git a/drivers/pinctrl/imx-iomux-v3.c b/drivers/pinctrl/imx-iomux-v3.c
index 3ff3c1571d..c867a23703 100644
--- a/drivers/pinctrl/imx-iomux-v3.c
+++ b/drivers/pinctrl/imx-iomux-v3.c
@@ -177,7 +177,7 @@ static int imx_iomux_v3_probe(struct device_d *dev)
iomuxv3_base = dev_request_mem_region(dev, 0);
iomuxv3_dev = dev;
- if (IS_ENABLED(CONFIG_PINCTRL))
+ if (IS_ENABLED(CONFIG_PINCTRL) && dev->device_node)
ret = imx_pinctrl_dt(dev, iomuxv3_base);
return ret;
diff --git a/drivers/pinctrl/pinctrl-tegra20.c b/drivers/pinctrl/pinctrl-tegra20.c
new file mode 100644
index 0000000000..053981f44c
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-tegra20.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2013 Lucas Stach <l.stach@pengutronix.de>
+ *
+ * Partly based on code
+ * Copyright (C) 2011-2012 NVIDIA Corporation <www.nvidia.com>
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file
+ * @brief Device driver for the Tegra 20 pincontrol hardware module.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <io.h>
+#include <malloc.h>
+#include <pinctrl.h>
+
+struct pinctrl_tegra20 {
+ struct {
+ u32 __iomem *tri;
+ u32 __iomem *mux;
+ u32 __iomem *pull;
+ } regs;
+ struct pinctrl_device pinctrl;
+};
+
+struct tegra20_pingroup {
+ const char *name;
+ const char *funcs[4];
+ s16 trictrl_id;
+ s16 muxctrl_id;
+ s16 pullctrl_id;
+};
+
+#define PG(pg_name, f0, f1, f2, f3, tri, mux, pull) \
+ { \
+ .name = #pg_name, \
+ .funcs = { #f0, #f1, #f2, #f3, }, \
+ .trictrl_id = tri, \
+ .muxctrl_id = mux, \
+ .pullctrl_id = pull \
+ }
+
+static const struct tegra20_pingroup tegra20_groups[] = {
+ /* name, f0, f1, f2, f3, tri, mux, pull */
+ PG(ata, ide, nand, gmi, rsvd4, 0, 12, 0 ),
+ PG(atb, ide, nand, gmi, sdio4, 1, 8, 1 ),
+ PG(atc, ide, nand, gmi, sdio4, 2, 11, 2 ),
+ PG(atd, ide, nand, gmi, sdio4, 3, 10, 3 ),
+ PG(ate, ide, nand, gmi, rsvd4, 57, 6, 4 ),
+ PG(cdev1, osc, plla_out, pllm_out1, audio_sync, 4, 33, 32 ),
+ PG(cdev2, osc, ahb_clk, apb_clk, pllp_out4, 5, 34, 33 ),
+ PG(crtp, crt, rsvd2, rsvd3, rsvd4, 110, 105, 28 ),
+ PG(csus, pllc_out1, pllp_out2, pllp_out3, vi_sensor_clk, 6, 35, 60 ),
+ PG(dap1, dap1, rsvd2, gmi, sdio2, 7, 42, 5 ),
+ PG(dap2, dap2, twc, rsvd3, gmi, 8, 43, 6 ),
+ PG(dap3, dap3, rsvd2, rsvd3, rsvd4, 9, 44, 7 ),
+ PG(dap4, dap4, rsvd2, gmi, rsvd4, 10, 45, 8 ),
+ PG(ddc, i2c2, rsvd2, rsvd3, rsvd4, 63, 32, 78 ),
+ PG(dta, rsvd1, sdio2, vi, rsvd4, 11, 26, 9 ),
+ PG(dtb, rsvd1, rsvd2, vi, spi1, 12, 27, 10 ),
+ PG(dtc, rsvd1, rsvd2, vi, rsvd4, 13, 29, 11 ),
+ PG(dtd, rsvd1, sdio2, vi, rsvd4, 14, 30, 12 ),
+ PG(dte, rsvd1, rsvd2, vi, spi1, 15, 31, 13 ),
+ PG(dtf, i2c3, rsvd2, vi, rsvd4, 108, 110, 14 ),
+ PG(gma, uarte, spi3, gmi, sdio4, 28, 16, 74 ),
+ PG(gmb, ide, nand, gmi, gmi_int, 61, 46, 75 ),
+ PG(gmc, uartd, spi4, gmi, sflash, 29, 17, 76 ),
+ PG(gmd, rsvd1, nand, gmi, sflash, 62, 47, 77 ),
+ PG(gme, rsvd1, dap5, gmi, sdio4, 32, 48, 44 ),
+ PG(gpu, pwm, uarta, gmi, rsvd4, 16, 50, 26 ),
+ PG(gpu7, rtck, rsvd2, rsvd3, rsvd4, 107, 109, 19 ),
+ PG(gpv, pcie, rsvd2, rsvd3, rsvd4, 17, 49, 15 ),
+ PG(hdint, hdmi, rsvd2, rsvd3, rsvd4, 87, 18, -1 ),
+ PG(i2cp, i2cp, rsvd2, rsvd3, rsvd4, 18, 36, 17 ),
+ PG(irrx, uarta, uartb, gmi, spi4, 20, 41, 43 ),
+ PG(irtx, uarta, uartb, gmi, spi4, 19, 40, 42 ),
+ PG(kbca, kbc, nand, sdio2, emc_test0_dll, 22, 37, 20 ),
+ PG(kbcb, kbc, nand, sdio2, mio, 21, 38, 21 ),
+ PG(kbcc, kbc, nand, trace, emc_test1_dll, 58, 39, 22 ),
+ PG(kbcd, kbc, nand, sdio2, mio, 106, 108, 23 ),
+ PG(kbce, kbc, nand, owr, rsvd4, 26, 14, 65 ),
+ PG(kbcf, kbc, nand, trace, mio, 27, 13, 64 ),
+ PG(lcsn, displaya, displayb, spi3, rsvd4, 95, 70, -1 ),
+ PG(ld0, displaya, displayb, xio, rsvd4, 64, 80, -1 ),
+ PG(ld1, displaya, displayb, xio, rsvd4, 65, 81, -1 ),
+ PG(ld2, displaya, displayb, xio, rsvd4, 66, 82, -1 ),
+ PG(ld3, displaya, displayb, xio, rsvd4, 67, 83, -1 ),
+ PG(ld4, displaya, displayb, xio, rsvd4, 68, 84, -1 ),
+ PG(ld5, displaya, displayb, xio, rsvd4, 69, 85, -1 ),
+ PG(ld6, displaya, displayb, xio, rsvd4, 70, 86, -1 ),
+ PG(ld7, displaya, displayb, xio, rsvd4, 71, 87, -1 ),
+ PG(ld8, displaya, displayb, xio, rsvd4, 72, 88, -1 ),
+ PG(ld9, displaya, displayb, xio, rsvd4, 73, 89, -1 ),
+ PG(ld10, displaya, displayb, xio, rsvd4, 74, 90, -1 ),
+ PG(ld11, displaya, displayb, xio, rsvd4, 75, 91, -1 ),
+ PG(ld12, displaya, displayb, xio, rsvd4, 76, 92, -1 ),
+ PG(ld13, displaya, displayb, xio, rsvd4, 77, 93, -1 ),
+ PG(ld14, displaya, displayb, xio, rsvd4, 78, 94, -1 ),
+ PG(ld15, displaya, displayb, xio, rsvd4, 79, 95, -1 ),
+ PG(ld16, displaya, displayb, xio, rsvd4, 80, 96, -1 ),
+ PG(ld17, displaya, displayb, rsvd3, rsvd4, 81, 97, -1 ),
+ PG(ldc, displaya, displayb, rsvd3, rsvd4, 94, 71, -1 ),
+ PG(ldi, displaya, displayb, rsvd3, rsvd4, 102, 104, -1 ),
+ PG(lhp0, displaya, displayb, rsvd3, rsvd4, 82, 101, -1 ),
+ PG(lhp1, displaya, displayb, rsvd3, rsvd4, 83, 98, -1 ),
+ PG(lhp2, displaya, displayb, rsvd3, rsvd4, 84, 99, -1 ),
+ PG(lhs, displaya, displayb, xio, rsvd4, 103, 75, -1 ),
+ PG(lm0, displaya, displayb, spi3, rsvd4, 88, 77, -1 ),
+ PG(lm1, displaya, displayb, rsvd3, CRT, 89, 78, -1 ),
+ PG(lpp, displaya, displayb, rsvd3, rsvd4, 104, 103, -1 ),
+ PG(lpw0, displaya, displayb, spi3, hdmi, 99, 64, -1 ),
+ PG(lpw1, displaya, displayb, rsvd3, rsvd4, 100, 65, -1 ),
+ PG(lpw2, displaya, displayb, spi3, hdmi, 101, 66, -1 ),
+ PG(lsc0, displaya, displayb, xio, rsvd4, 91, 73, -1 ),
+ PG(lsc1, displaya, displayb, spi3, hdmi, 92, 74, -1 ),
+ PG(lsck, displaya, displayb, spi3, hdmi, 93, 72, -1 ),
+ PG(lsda, displaya, displayb, spi3, hdmi, 97, 68, -1 ),
+ PG(lsdi, displaya, displayb, spi3, rsvd4, 98, 67, -1 ),
+ PG(lspi, displaya, displayb, xio, hdmi, 96, 69, -1 ),
+ PG(lvp0, displaya, displayb, rsvd3, rsvd4, 85, 79, -1 ),
+ PG(lvp1, displaya, displayb, rsvd3, rsvd4, 86, 100, -1 ),
+ PG(lvs, displaya, displayb, xio, rsvd4, 90, 76, -1 ),
+ PG(owc, owr, rsvd2, rsvd3, rsvd4, 31, 20, 79 ),
+ PG(pmc, pwr_on, pwr_intr, rsvd3, rsvd4, 23, 105, -1 ),
+ PG(pta, i2c2, hdmi, gmi, rsvd4, 24, 107, 18 ),
+ PG(rm, i2c1, rsvd2, rsvd3, rsvd4, 25, 7, 16 ),
+ PG(sdb, uarta, pwm, sdio3, spi2, 111, 53, -1 ),
+ PG(sdc, pwm, twc, sdio3, spi3, 33, 54, 62 ),
+ PG(sdd, uarta, pwm, sdio3, spi3, 34, 55, 63 ),
+ PG(sdio1, sdio1, rsvd2, uarte, uarta, 30, 15, 73 ),
+ PG(slxa, pcie, spi4, sdio3, spi2, 36, 19, 27 ),
+ PG(slxc, spdif, spi4, sdio3, spi2, 37, 21, 29 ),
+ PG(slxd, spdif, spi4, sdio3, spi2, 38, 22, 30 ),
+ PG(slxk, pcie, spi4, sdio3, spi2, 39, 23, 31 ),
+ PG(spdi, spdif, rsvd2, i2c1, sdio2, 40, 52, 24 ),
+ PG(spdo, spdif, rsvd2, i2c1, sdio2, 41, 51, 25 ),
+ PG(spia, spi1, spi2, spi3, gmi, 42, 63, 34 ),
+ PG(spib, spi1, spi2, spi3, gmi, 43, 62, 35 ),
+ PG(spic, spi1, spi2, spi3, gmi, 44, 61, 36 ),
+ PG(spid, spi2, spi1, spi2_alt, gmi, 45, 60, 37 ),
+ PG(spie, spi2, spi1, spi2_alt, gmi, 46, 59, 38 ),
+ PG(spif, spi3, spi1, spi2, rsvd4, 47, 58, 39 ),
+ PG(spig, spi3, spi2, spi2_alt, i2c1, 48, 57, 40 ),
+ PG(spih, spi3, spi2, spi2_alt, i2c1, 49, 56, 41 ),
+ PG(uaa, spi3, mipi_hs, uarta, ulpi, 50, 0, 48 ),
+ PG(uab, spi2, mipi_hs, uarta, ulpi, 51, 1, 49 ),
+ PG(uac, owr, rsvd2, rsvd3, rsvd4, 52, 2, 50 ),
+ PG(uad, irda, spdif, uarta, spi4, 53, 3, 51 ),
+ PG(uca, uartc, rsvd2, gmi, rsvd4, 54, 24, 52 ),
+ PG(ucb, uartc, pwm, gmi, rsvd4, 55, 25, 53 ),
+ PG(uda, spi1, rsvd2, uartd, ulpi, 109, 4, 72 ),
+};
+
+static void pinctrl_tegra20_set_func(struct pinctrl_tegra20 *ctrl,
+ int muxctrl_id, int func)
+{
+ u32 __iomem *regaddr = ctrl->regs.mux;
+ u32 reg;
+ int maskbit;
+
+ regaddr += muxctrl_id >> 4;
+ maskbit = (muxctrl_id << 1) & 0x1f;
+
+ reg = readl(regaddr);
+ reg &= ~(0x3 << maskbit);
+ reg |= func << maskbit;
+ writel(reg, regaddr);
+}
+
+static void pinctrl_tegra20_set_pull(struct pinctrl_tegra20 *ctrl,
+ int pullctrl_id, int pull)
+{
+ u32 __iomem *regaddr = ctrl->regs.pull;
+ u32 reg;
+ int maskbit;
+
+ regaddr += pullctrl_id >> 4;
+ maskbit = (pullctrl_id << 1) & 0x1f;
+
+ reg = readl(regaddr);
+ reg &= ~(0x3 << maskbit);
+ reg |= pull << maskbit;
+ writel(reg, regaddr);
+}
+
+static void pinctrl_tegra20_set_tristate(struct pinctrl_tegra20 *ctrl,
+ int trictrl_id, int tristate)
+{
+ u32 __iomem *regaddr = ctrl->regs.tri;
+ u32 reg;
+ int maskbit;
+
+ regaddr += trictrl_id >> 5;
+ maskbit = trictrl_id & 0x1f;
+
+ reg = readl(regaddr);
+ reg &= ~(1 << maskbit);
+ reg |= tristate << maskbit;
+ writel(reg, regaddr);
+}
+
+static int pinctrl_tegra20_set_state(struct pinctrl_device *pdev,
+ struct device_node *np)
+{
+ struct pinctrl_tegra20 *ctrl =
+ container_of(pdev, struct pinctrl_tegra20, pinctrl);
+ struct device_node *childnode;
+ int pull = -1, tri = -1, i, j, k;
+ const char *pins, *func = NULL;
+ const struct tegra20_pingroup *group;
+
+ /*
+ * At first look if the node we are pointed at has children,
+ * which we may want to visit.
+ */
+ list_for_each_entry(childnode, &np->children, parent_list)
+ pinctrl_tegra20_set_state(pdev, childnode);
+
+ /* read relevant state from devicetree */
+ of_property_read_string(np, "nvidia,function", &func);
+ of_property_read_u32_array(np, "nvidia,pull", &pull, 1);
+ of_property_read_u32_array(np, "nvidia,tristate", &tri, 1);
+
+ /* iterate over all pingroups referenced in the dt node */
+ for (i = 0; ; i++) {
+ if (of_property_read_string_index(np, "nvidia,pins", i, &pins))
+ break;
+
+ for (j = 0; j < ARRAY_SIZE(tegra20_groups); j++) {
+ if (!strcmp(pins, tegra20_groups[j].name)) {
+ group = &tegra20_groups[j];
+ break;
+ }
+ }
+ /* if no matching pingroup is found bail out */
+ if (j == ARRAY_SIZE(tegra20_groups)) {
+ dev_warn(ctrl->pinctrl.dev,
+ "invalid pingroup %s referenced in node %s\n",
+ pins, np->name);
+ continue;
+ }
+
+ if (func) {
+ for (k = 0; k < 4; k++) {
+ if (!strcmp(func, group->funcs[k]))
+ break;
+ }
+ if (k < 4)
+ pinctrl_tegra20_set_func(ctrl,
+ group->muxctrl_id, k);
+ else
+ dev_warn(ctrl->pinctrl.dev,
+ "invalid function %s for pingroup %s in node %s\n",
+ func, group->name, np->name);
+ }
+
+ if (pull >= 0) {
+ if (group->pullctrl_id >= 0)
+ pinctrl_tegra20_set_pull(ctrl,
+ group->pullctrl_id,
+ pull);
+ else
+ dev_warn(ctrl->pinctrl.dev,
+ "pingroup %s in node %s doesn't support pull configuration\n",
+ group->name, np->name);
+ }
+
+ if (tri >= 0)
+ pinctrl_tegra20_set_tristate(ctrl,
+ group->trictrl_id, tri);
+ }
+
+ return 0;
+}
+
+static struct pinctrl_ops pinctrl_tegra20_ops = {
+ .set_state = pinctrl_tegra20_set_state,
+};
+
+static int pinctrl_tegra20_probe(struct device_d *dev)
+{
+ struct pinctrl_tegra20 *ctrl;
+ int i, ret;
+ u32 **regs;
+
+ ctrl = xzalloc(sizeof(*ctrl));
+
+ /*
+ * Tegra pincontrol is split out into four independent memory ranges:
+ * tristate control, function mux, pullup/down control, pad control
+ * (from lowest to highest hardware address).
+ * We are only interested in the first three for now.
+ */
+ regs = (u32 **)&ctrl->regs;
+ for (i = 0; i <= 2; i++) {
+ regs[i] = dev_request_mem_region(dev, i);
+ if (!regs[i]) {
+ dev_err(dev, "Could not get iomem region %d\n", i);
+ return -ENODEV;
+ }
+ }
+
+ ctrl->pinctrl.dev = dev;
+ ctrl->pinctrl.ops = &pinctrl_tegra20_ops;
+
+ ret = pinctrl_register(&ctrl->pinctrl);
+ if (ret)
+ free(ctrl);
+
+ return ret;
+}
+
+static __maybe_unused struct of_device_id pinctrl_tegra20_dt_ids[] = {
+ {
+ .compatible = "nvidia,tegra20-pinmux",
+ }, {
+ /* sentinel */
+ }
+};
+
+static struct driver_d pinctrl_tegra20_driver = {
+ .name = "pinctrl-tegra20",
+ .probe = pinctrl_tegra20_probe,
+ .of_compatible = DRV_OF_COMPAT(pinctrl_tegra20_dt_ids),
+};
+
+static int pinctrl_tegra20_init(void)
+{
+ return platform_driver_register(&pinctrl_tegra20_driver);
+}
+postcore_initcall(pinctrl_tegra20_init);
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index d58b6646b5..f460a7a690 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -108,9 +108,20 @@ void spi_of_register_slaves(struct spi_master *master, struct device_node *node)
struct property *reg;
device_node_for_nach_child(node, n) {
- chip.name = n->name;
+ memset(&chip, 0, sizeof(chip));
+ chip.name = xstrdup(n->name);
chip.bus_num = master->bus_num;
- chip.max_speed_hz = 300000; /* FIXME */
+ /* Mode (clock phase/polarity/etc.) */
+ if (of_find_property(n, "spi-cpha"))
+ chip.mode |= SPI_CPHA;
+ if (of_find_property(n, "spi-cpol"))
+ chip.mode |= SPI_CPOL;
+ if (of_find_property(n, "spi-cs-high"))
+ chip.mode |= SPI_CS_HIGH;
+ if (of_find_property(n, "spi-3wire"))
+ chip.mode |= SPI_3WIRE;
+ of_property_read_u32(n, "spi-max-frequency",
+ &chip.max_speed_hz);
reg = of_find_property(n, "reg");
if (!reg)
continue;
diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index 0e00cb7675..a4a8b00966 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -144,7 +144,6 @@ static void fb_info(struct device_d *dev)
static struct driver_d fb_driver = {
.name = "fb",
- .info = fb_info,
};
static int fb_match(struct device_d *dev, struct driver_d *drv)
@@ -165,6 +164,8 @@ static int fb_probe(struct device_d *dev)
dev_set_param(dev, "mode_name", info->mode_list[0].name);
}
+ dev->info = fb_info;
+
return devfs_create(&info->cdev);
}
diff --git a/drivers/video/s3c24xx.c b/drivers/video/s3c24xx.c
index d641cfaa27..c3e05c6cd7 100644
--- a/drivers/video/s3c24xx.c
+++ b/drivers/video/s3c24xx.c
@@ -321,7 +321,6 @@ static int s3cfb_activate_var(struct fb_info *fb_info)
* Print some information about the current hardware state
* @param hw_dev S3C video device
*/
-#ifdef CONFIG_DRIVER_VIDEO_S3C_VERBOSE
static void s3cfb_info(struct device_d *hw_dev)
{
uint32_t con1, addr1, addr2, addr3;
@@ -340,7 +339,6 @@ static void s3cfb_info(struct device_d *hw_dev)
printf(" Virtual screen offset size: %u half words\n", GET_OFFSIZE(addr3));
printf(" Virtual screen page width: %u half words\n", GET_PAGE_WIDTH(addr3));
}
-#endif
/*
* There is only one video hardware instance available.
@@ -390,6 +388,9 @@ static int s3cfb_probe(struct device_d *hw_dev)
fbi.passive_display = pdata->passive_display;
fbi.enable = pdata->enable;
+ if (IS_ENABLED(CONFIG_DRIVER_VIDEO_S3C_VERBOSE))
+ hw_dev->info = s3cfb_info;
+
ret = register_framebuffer(&fbi.info);
if (ret != 0) {
dev_err(hw_dev, "Failed to register framebuffer\n");
@@ -402,9 +403,6 @@ static int s3cfb_probe(struct device_d *hw_dev)
static struct driver_d s3cfb_driver = {
.name = "s3c_fb",
.probe = s3cfb_probe,
-#ifdef CONFIG_DRIVER_VIDEO_S3C_VERBOSE
- .info = s3cfb_info,
-#endif
};
device_platform_driver(s3cfb_driver);
diff --git a/drivers/video/stm.c b/drivers/video/stm.c
index cefdef2ab5..606e39a253 100644
--- a/drivers/video/stm.c
+++ b/drivers/video/stm.c
@@ -502,6 +502,8 @@ static int stmfb_probe(struct device_d *hw_dev)
else
fbi.info.bits_per_pixel = 16;
+ hw_dev->info = stmfb_info;
+
ret = register_framebuffer(&fbi.info);
if (ret != 0) {
dev_err(hw_dev, "Failed to register framebuffer\n");
@@ -514,7 +516,6 @@ static int stmfb_probe(struct device_d *hw_dev)
static struct driver_d stmfb_driver = {
.name = "stmfb",
.probe = stmfb_probe,
- .info = stmfb_info,
};
device_platform_driver(stmfb_driver);
diff --git a/include/block.h b/include/block.h
index cfa4cb9ef1..eb31aca4db 100644
--- a/include/block.h
+++ b/include/block.h
@@ -8,8 +8,6 @@ struct block_device;
struct block_device_ops {
int (*read)(struct block_device *, void *buf, int block, int num_blocks);
int (*write)(struct block_device *, const void *buf, int block, int num_blocks);
- int (*read_start)(struct block_device *, void *buf, int block, int num_blocks);
- int (*read_done)(struct block_device *);
};
struct chunk;
@@ -31,4 +29,12 @@ struct block_device {
int blockdevice_register(struct block_device *blk);
int blockdevice_unregister(struct block_device *blk);
+int block_read(struct block_device *blk, void *buf, int block, int num_blocks);
+int block_write(struct block_device *blk, void *buf, int block, int num_blocks);
+
+static inline int block_flush(struct block_device *blk)
+{
+ return cdev_flush(&blk->cdev);
+}
+
#endif /* __BLOCK_H */
diff --git a/include/driver.h b/include/driver.h
index 716f792afe..8b3af4de26 100644
--- a/include/driver.h
+++ b/include/driver.h
@@ -106,7 +106,14 @@ struct device_d {
struct platform_device_id *id_entry;
struct device_node *device_node;
- struct of_device_id *of_id_entry;
+ const struct of_device_id *of_id_entry;
+
+ void (*info) (struct device_d *);
+ /*
+ * For devices which take longer to probe this is called
+ * when the driver should actually detect client devices
+ */
+ int (*detect) (struct device_d *);
};
/** @brief Describes a driver present in the system */
@@ -124,9 +131,6 @@ struct driver_d {
/*! Called if an instance of a device is gone. */
void (*remove)(struct device_d *);
- void (*info) (struct device_d *);
- void (*shortinfo) (struct device_d *);
-
struct bus_type *bus;
struct platform_device_id *id_table;
@@ -153,6 +157,9 @@ int register_device(struct device_d *);
*/
int device_probe(struct device_d *dev);
+/* detect devices attached to this device (cards, disks,...) */
+int device_detect(struct device_d *dev);
+
/* Unregister a device. This function can fail, e.g. when the device
* has children.
*/
diff --git a/include/environment.h b/include/environment.h
index 7bdd213a52..ae1ecf5bd6 100644
--- a/include/environment.h
+++ b/include/environment.h
@@ -20,6 +20,8 @@
#ifndef _ENVIRONMENT_H_
#define _ENVIRONMENT_H_
+#include <linux/list.h>
+
/**
* Managment of a environment variable
*/
diff --git a/include/fb.h b/include/fb.h
index 23d6c6d025..df4ba8ebe7 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -3,6 +3,7 @@
#include <ioctl.h>
#include <param.h>
+#include <driver.h>
#define FB_VISUAL_TRUECOLOR 2 /* True color */
#define FB_VISUAL_PSEUDOCOLOR 3 /* Pseudo color (like atari) */
diff --git a/include/filetype.h b/include/filetype.h
index ee777acf99..c73c64aa60 100644
--- a/include/filetype.h
+++ b/include/filetype.h
@@ -1,6 +1,8 @@
#ifndef __FILE_TYPE_H
#define __FILE_TYPE_H
+#include <linux/string.h>
+
/*
* List of file types we know
*/
diff --git a/include/globalvar.h b/include/globalvar.h
index ddf885f18e..e3098bc403 100644
--- a/include/globalvar.h
+++ b/include/globalvar.h
@@ -8,7 +8,7 @@ int globalvar_add(const char *name,
int (*set)(struct device_d *dev, struct param_d *p, const char *val),
const char *(*get)(struct device_d *, struct param_d *p),
unsigned long flags);
-char *globalvar_get_match(const char *match, const char *seperator);
+char *globalvar_get_match(const char *match, const char *separator);
void globalvar_set_match(const char *match, const char *val);
#else
static inline int globalvar_add_simple(const char *name)
@@ -24,7 +24,7 @@ static inline int globalvar_add(const char *name,
return 0;
}
-static inline char *globalvar_get_match(const char *match, const char *seperator)
+static inline char *globalvar_get_match(const char *match, const char *separator)
{
return NULL;
}
diff --git a/include/i2c/i2c.h b/include/i2c/i2c.h
index 7b59a5102d..46185ac921 100644
--- a/include/i2c/i2c.h
+++ b/include/i2c/i2c.h
@@ -16,6 +16,9 @@
#ifndef I2C_I2C_H
#define I2C_I2C_H
+#include <driver.h>
+#include <linux/types.h>
+
#ifndef DOXYGEN_SHOULD_SKIP_THIS
/*
@@ -102,6 +105,7 @@ struct i2c_board_info {
char type[I2C_NAME_SIZE]; /**< name of device */
unsigned short addr; /**< stored in i2c_client.addr */
void *platform_data; /**< platform data for device */
+ struct device_node *of_node;
};
/**
diff --git a/include/image.h b/include/image.h
index 219419b12b..0c8a4b138d 100644
--- a/include/image.h
+++ b/include/image.h
@@ -89,7 +89,7 @@
#define IH_ARCH IH_ARCH_PPC
#elif defined(__ARM__)
#define IH_ARCH IH_ARCH_ARM
-#elif defined(__I386__) || defined(__x86_64__)
+#elif defined(__I386__) || defined(__x86_64__) || defined(__i386__)
#define IH_ARCH IH_ARCH_I386
#elif defined(__mips__)
#define IH_ARCH IH_ARCH_MIPS
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 99c96390c7..8e60758ca3 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -15,6 +15,7 @@
#ifndef __PHY_H
#define __PHY_H
+#include <driver.h>
#include <linux/list.h>
#include <linux/ethtool.h>
#include <linux/mii.h>
diff --git a/include/mci.h b/include/mci.h
index eca48a52f4..bca374a8bf 100644
--- a/include/mci.h
+++ b/include/mci.h
@@ -185,6 +185,8 @@
/*
* EXT_CSD field definitions
*/
+#define EXT_CSD_PART_CONFIG_ACC_MASK (0x7)
+#define EXT_CSD_PART_CONFIG_ACC_BOOT0 (0x1)
#define EXT_CSD_CMD_SET_NORMAL (1<<0)
#define EXT_CSD_CMD_SET_SECURE (1<<1)
@@ -283,9 +285,12 @@ struct mci_ios {
#define MMC_1_8V_SDR_MODE 4
};
+struct mci;
+
/** host information */
struct mci_host {
struct device_d *hw_dev; /**< the host MCI hardware device */
+ struct mci *mci;
char *devname; /**< the devicename for the card, defaults to disk%d */
unsigned voltages;
unsigned host_caps; /**< Host's interface capabilities, refer MMC_VDD_* */
@@ -306,11 +311,27 @@ struct mci_host {
int (*card_write_protected)(struct mci_host *);
};
+#define MMC_NUM_BOOT_PARTITION 2
+#define MMC_NUM_GP_PARTITION 4
+#define MMC_NUM_PHY_PARTITION 6
+
+struct mci_part {
+ struct block_device blk; /**< the blockdevice for the card */
+ struct mci *mci;
+ uint64_t size; /* partition size (in bytes) */
+ unsigned int part_cfg; /* partition type */
+ char *name;
+ unsigned int area_type;
+#define MMC_BLK_DATA_AREA_MAIN (1<<0)
+#define MMC_BLK_DATA_AREA_BOOT (1<<1)
+#define MMC_BLK_DATA_AREA_GP (1<<2)
+#define MMC_BLK_DATA_AREA_RPMB (1<<3)
+};
+
/** MMC/SD and interface instance information */
struct mci {
struct mci_host *host; /**< the host for this card */
- struct block_device blk; /**< the blockdevice for the card */
- struct device_d *mci_dev; /**< the device for our disk (mcix) */
+ struct device_d dev; /**< the device for our disk (mcix) */
unsigned version;
/** != 0 when a high capacity card is connected (OCR -> OCR_HCS) */
int high_capacity;
@@ -330,8 +351,19 @@ struct mci {
char *ext_csd;
int probe;
struct param_d *param_probe;
+ struct param_d *param_boot;
+ int bootpart;
+
+ struct mci_part part[MMC_NUM_PHY_PARTITION];
+ int nr_parts;
+ char *cdevname;
+
+ struct mci_part *part_curr;
+ u8 ext_csd_part_config;
};
int mci_register(struct mci_host*);
+void mci_of_parse(struct mci_host *host);
+int mci_detect_card(struct mci_host *);
#endif /* _MCI_H_ */
diff --git a/include/mci/twl6030.h b/include/mci/twl6030.h
deleted file mode 100644
index 0ca828c117..0000000000
--- a/include/mci/twl6030.h
+++ /dev/null
@@ -1,10 +0,0 @@
-/*
- * TWL6030 header file.
- */
-
-#ifndef __MCI_TWL6030_H__
-#define __MCI_TWL6030_H__
-
-void twl6030_mci_power_init(void);
-
-#endif
diff --git a/include/mfd/mc13xxx.h b/include/mfd/mc13xxx.h
index 59042ebee6..cba85890c1 100644
--- a/include/mfd/mc13xxx.h
+++ b/include/mfd/mc13xxx.h
@@ -12,6 +12,8 @@
#ifndef __MFD_MC13XXX_H
#define __MFD_MC13XXX_H
+#include <linux/types.h>
+
#define MC13XXX_REG_IDENTIFICATION 0x07
#define MC13783_REG_INT_STATUS0 0x00
diff --git a/include/net.h b/include/net.h
index bb6b8fa281..fa3c05a987 100644
--- a/include/net.h
+++ b/include/net.h
@@ -19,7 +19,9 @@
#include <stdlib.h>
#include <clock.h>
#include <led.h>
+#include <xfuncs.h>
#include <linux/phy.h>
+#include <linux/string.h> /* memcpy */
#include <asm/byteorder.h> /* for nton* / ntoh* stuff */
/* How often do we retry to send packages */
@@ -76,8 +78,13 @@ int eth_rx(void); /* Check for received packets */
static inline void eth_register_ethaddr(int ethid, const char *ethaddr)
{
}
+static inline void of_eth_register_ethaddr(struct device_node *node,
+ const char *ethaddr)
+{
+}
#else
void eth_register_ethaddr(int ethid, const char *ethaddr);
+void of_eth_register_ethaddr(struct device_node *node, const char *ethaddr);
#endif
/*
* Ethernet header
diff --git a/include/notifier.h b/include/notifier.h
index cb2be5f548..c83e28b156 100644
--- a/include/notifier.h
+++ b/include/notifier.h
@@ -1,6 +1,8 @@
#ifndef __NOTIFIER_H
#define __NOTIFIER_H
+#include <linux/list.h>
+
/*
* Notifer chains loosely based on the according Linux framework
*/
diff --git a/include/of.h b/include/of.h
index 4dcf37e140..300b7069c0 100644
--- a/include/of.h
+++ b/include/of.h
@@ -72,6 +72,8 @@ struct fdt_header *fdt_get_tree(void);
struct fdt_header *of_get_fixed_tree(struct device_node *node);
+int of_modalias_node(struct device_node *node, char *modalias, int len);
+
#define device_node_for_nach_child(node, child) \
list_for_each_entry(child, &node->children, parent_list)
@@ -138,6 +140,7 @@ int of_get_named_gpio(struct device_node *np,
struct device_node *of_find_node_by_phandle(phandle phandle);
void of_print_property(const void *data, int len);
+void of_print_cmdline(struct device_node *root);
int of_device_is_compatible(const struct device_node *device,
const char *compat);
@@ -167,19 +170,25 @@ int of_set_property(struct device_node *node, const char *p, const void *val, in
int create);
struct device_node *of_create_node(struct device_node *root, const char *path);
-struct device_node *of_get_root_node(void);
int of_set_root_node(struct device_node *);
+const struct of_device_id *of_match_node(const struct of_device_id *matches,
+ const struct device_node *node);
+
struct cdev;
#ifdef CONFIG_OFTREE
int of_parse_partitions(struct cdev *cdev, struct device_node *node);
int of_alias_get_id(struct device_node *np, const char *stem);
+const char *of_alias_get(struct device_node *np);
int of_device_is_stdout_path(struct device_d *dev);
const char *of_get_model(void);
void *of_flatten_dtb(struct device_node *node);
int of_add_memory(struct device_node *node, bool dump);
+void of_add_memory_bank(struct device_node *node, bool dump, int r,
+ u64 base, u64 size);
+struct device_node *of_get_root_node(void);
#else
static inline int of_parse_partitions(struct cdev *cdev,
struct device_node *node)
@@ -192,6 +201,11 @@ static inline int of_alias_get_id(struct device_node *np, const char *stem)
return -ENOENT;
}
+static inline const char *of_alias_get(struct device_node *np)
+{
+ return NULL;
+}
+
static inline int of_device_is_stdout_path(struct device_d *dev)
{
return 0;
@@ -211,6 +225,11 @@ static inline int of_add_memory(struct device_node *node, bool dump)
{
return -EINVAL;
}
+
+static inline struct device_node *of_get_root_node(void)
+{
+ return NULL;
+}
#endif
#endif /* __OF_H */
diff --git a/include/param.h b/include/param.h
index 4af2d09c4c..7830f6f159 100644
--- a/include/param.h
+++ b/include/param.h
@@ -12,6 +12,7 @@ typedef unsigned long IPaddr_t;
struct param_d {
const char* (*get)(struct device_d *, struct param_d *param);
int (*set)(struct device_d *, struct param_d *param, const char *val);
+ void (*info)(struct param_d *param);
unsigned int flags;
char *name;
char *value;
@@ -40,6 +41,11 @@ struct param_d *dev_add_param_bool(struct device_d *dev, const char *name,
int (*get)(struct param_d *p, void *priv),
int *value, void *priv);
+struct param_d *dev_add_param_enum(struct device_d *dev, const char *name,
+ int (*set)(struct param_d *p, void *priv),
+ int (*get)(struct param_d *p, void *priv),
+ int *value, const char **names, int max, void *priv);
+
struct param_d *dev_add_param_int_ro(struct device_d *dev, const char *name,
int value, const char *format);
@@ -89,6 +95,15 @@ static inline struct param_d *dev_add_param_int(struct device_d *dev, const char
return NULL;
}
+static inline struct param_d *dev_add_param_enum(struct device_d *dev, const char *name,
+ int (*set)(struct param_d *p, void *priv),
+ int (*get)(struct param_d *p, void *priv),
+ int *value, const char **names, int max, void *priv)
+
+{
+ return NULL;
+}
+
static inline struct param_d *dev_add_param_bool(struct device_d *dev, const char *name,
int (*set)(struct param_d *p, void *priv),
int (*get)(struct param_d *p, void *priv),
diff --git a/include/partition.h b/include/partition.h
index 8ad7490d85..32570530eb 100644
--- a/include/partition.h
+++ b/include/partition.h
@@ -1,7 +1,7 @@
#ifndef __PARTITION_H
#define __PARTITION_H
-struct device_d;
+#include <driver.h>
struct partition {
int num;
@@ -18,4 +18,3 @@ struct partition {
};
#endif /* __PARTITION_H */
-
diff --git a/include/spi/spi.h b/include/spi/spi.h
index 3da13e85ec..45fd22ce26 100644
--- a/include/spi/spi.h
+++ b/include/spi/spi.h
@@ -4,6 +4,7 @@
#ifndef DOXYGEN_SHOULD_SKIP_THIS
#include <driver.h>
+#include <linux/string.h>
struct spi_board_info {
char *name;
diff --git a/lib/parameter.c b/lib/parameter.c
index e47e8b9148..c5c6426bb2 100644
--- a/lib/parameter.c
+++ b/lib/parameter.c
@@ -299,6 +299,110 @@ struct param_d *dev_add_param_int(struct device_d *dev, const char *name,
return &pi->param;
}
+struct param_enum {
+ struct param_d param;
+ int *value;
+ const char **names;
+ int num_names;
+ int (*set)(struct param_d *p, void *priv);
+ int (*get)(struct param_d *p, void *priv);
+};
+
+static inline struct param_enum *to_param_enum(struct param_d *p)
+{
+ return container_of(p, struct param_enum, param);
+}
+
+static int param_enum_set(struct device_d *dev, struct param_d *p, const char *val)
+{
+ struct param_enum *pe = to_param_enum(p);
+ int value_save = *pe->value;
+ int i, ret;
+
+ if (!val)
+ return -EINVAL;
+
+ for (i = 0; i < pe->num_names; i++)
+ if (pe->names[i] && !strcmp(val, pe->names[i]))
+ break;
+
+ if (i == pe->num_names)
+ return -EINVAL;
+
+ *pe->value = i;
+
+ if (!pe->set)
+ return 0;
+
+ ret = pe->set(p, p->driver_priv);
+ if (ret)
+ *pe->value = value_save;
+
+ return ret;
+}
+
+static const char *param_enum_get(struct device_d *dev, struct param_d *p)
+{
+ struct param_enum *pe = to_param_enum(p);
+ int ret;
+
+ if (pe->get) {
+ ret = pe->get(p, p->driver_priv);
+ if (ret)
+ return NULL;
+ }
+
+ free(p->value);
+ p->value = strdup(pe->names[*pe->value]);
+
+ return p->value;
+}
+
+static void param_enum_info(struct param_d *p)
+{
+ struct param_enum *pe = to_param_enum(p);
+ int i;
+
+ printf(" (");
+
+ for (i = 0; i < pe->num_names; i++) {
+ if (!pe->names[i] || !*pe->names[i])
+ continue;
+ printf("\"%s\"%s", pe->names[i],
+ i == pe->num_names - 1 ? ")" : ", ");
+ }
+}
+
+struct param_d *dev_add_param_enum(struct device_d *dev, const char *name,
+ int (*set)(struct param_d *p, void *priv),
+ int (*get)(struct param_d *p, void *priv),
+ int *value, const char **names, int num_names, void *priv)
+{
+ struct param_enum *pe;
+ struct param_d *p;
+ int ret;
+
+ pe = xzalloc(sizeof(*pe));
+
+ pe->value = value;
+ pe->set = set;
+ pe->get = get;
+ pe->names = names;
+ pe->num_names = num_names;
+ p = &pe->param;
+ p->driver_priv = priv;
+
+ ret = __dev_add_param(p, dev, name, param_enum_set, param_enum_get, 0);
+ if (ret) {
+ free(pe);
+ return ERR_PTR(ret);
+ }
+
+ p->info = param_enum_info;
+
+ return &pe->param;
+}
+
/**
* dev_add_param_bool - add an boolean parameter to a device
* @param dev The device
diff --git a/net/eth.c b/net/eth.c
index 4646dd8b89..bea7b12b41 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -36,16 +36,34 @@ struct eth_ethaddr {
struct list_head list;
u8 ethaddr[6];
int ethid;
+ struct device_node *node;
};
static LIST_HEAD(ethaddr_list);
-static int eth_get_registered_ethaddr(int ethid, void *buf)
+static void register_preset_mac_address(struct eth_device *edev, const char *ethaddr)
+{
+ unsigned char ethaddr_str[sizeof("xx:xx:xx:xx:xx:xx")];
+
+ ethaddr_to_string(ethaddr, ethaddr_str);
+
+ if (is_valid_ether_addr(ethaddr)) {
+ dev_info(&edev->dev, "got preset MAC address: %s\n", ethaddr_str);
+ dev_set_param(&edev->dev, "ethaddr", ethaddr_str);
+ }
+}
+
+static int eth_get_registered_ethaddr(struct eth_device *edev, void *buf)
{
struct eth_ethaddr *addr;
+ struct device_node *node = NULL;
+
+ if (edev->parent)
+ node = edev->parent->device_node;
list_for_each_entry(addr, &ethaddr_list, list) {
- if (addr->ethid == ethid) {
+ if ((node && node == addr->node) ||
+ addr->ethid == edev->dev.id) {
memcpy(buf, addr->ethaddr, 6);
return 0;
}
@@ -78,6 +96,38 @@ void eth_register_ethaddr(int ethid, const char *ethaddr)
list_add_tail(&addr->list, &ethaddr_list);
}
+static struct eth_device *eth_get_by_node(struct device_node *node)
+{
+ struct eth_device *edev;
+
+ list_for_each_entry(edev, &netdev_list, list) {
+ if (!edev->parent)
+ continue;
+ if (!edev->parent->device_node)
+ continue;
+ if (edev->parent->device_node == node)
+ return edev;
+ }
+ return NULL;
+}
+
+void of_eth_register_ethaddr(struct device_node *node, const char *ethaddr)
+{
+ struct eth_ethaddr *addr;
+ struct eth_device *edev;
+
+ edev = eth_get_by_node(node);
+ if (edev) {
+ register_preset_mac_address(edev, ethaddr);
+ return;
+ }
+
+ addr = xzalloc(sizeof(*addr));
+ addr->node = node;
+ memcpy(addr->ethaddr, ethaddr, 6);
+ list_add_tail(&addr->list, &ethaddr_list);
+}
+
void eth_set_current(struct eth_device *eth)
{
if (eth_current && eth_current->active) {
@@ -225,8 +275,7 @@ static int eth_set_ethaddr(struct device_d *dev, struct param_d *param, const ch
int eth_register(struct eth_device *edev)
{
- struct device_d *dev = &edev->dev;
- unsigned char ethaddr_str[20];
+ struct device_d *dev = &edev->dev;
unsigned char ethaddr[6];
int ret, found = 0;
@@ -254,7 +303,7 @@ int eth_register(struct eth_device *edev)
list_add_tail(&edev->list, &netdev_list);
- ret = eth_get_registered_ethaddr(dev->id, ethaddr);
+ ret = eth_get_registered_ethaddr(edev, ethaddr);
if (!ret)
found = 1;
@@ -264,13 +313,8 @@ int eth_register(struct eth_device *edev)
found = 1;
}
- if (found) {
- ethaddr_to_string(ethaddr, ethaddr_str);
- if (is_valid_ether_addr(ethaddr)) {
- dev_info(dev, "got preset MAC address: %s\n", ethaddr_str);
- dev_set_param(dev, "ethaddr", ethaddr_str);
- }
- }
+ if (found)
+ register_preset_mac_address(edev, ethaddr);
if (!eth_current)
eth_current = edev;
diff --git a/scripts/.gitignore b/scripts/.gitignore
index bff805ddf8..6518c0f076 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -2,6 +2,8 @@ bareboxenv
bin2c
gen_netx_image
kallsyms
+kwbimage
+kwboot
mk-am35xx-spi-image
mkimage
mkublheader
diff --git a/scripts/Makefile b/scripts/Makefile
index f062fc011b..307dc3d1a4 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -8,11 +8,13 @@ hostprogs-$(CONFIG_KALLSYMS) += kallsyms
hostprogs-y += bin2c
hostprogs-y += mkimage
hostprogs-y += bareboxenv
+hostprogs-$(CONFIG_ARCH_MVEBU) += kwbimage kwboot
hostprogs-$(CONFIG_ARCH_NETX) += gen_netx_image
hostprogs-$(CONFIG_ARCH_OMAP) += omap_signGP mk-am35xx-spi-image
hostprogs-$(CONFIG_ARCH_S5PCxx) += s5p_cksum
hostprogs-$(CONFIG_ARCH_DAVINCI) += mkublheader
hostprogs-$(CONFIG_ARCH_ZYNQ) += zynq_mkimage
+subdir-$(CONFIG_ARCH_IMX) += imx
HOSTLOADLIBES_omap4_usbboot = -lpthread
omap4_usbboot-objs := usb_linux.o omap4_usbboot.o
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index bbfd4cd2de..0b56dcc218 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -141,10 +141,10 @@ cpp_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(__cpp_flags)
ld_flags = $(LDFLAGS) $(EXTRA_LDFLAGS)
-dtc_cpp_flags = -Wp,-MD,$(depfile) -nostdinc \
- -I$(srctree)/arch/$(SRCARCH)/dts \
- -I$(srctree)/arch/$(SRCARCH)/include/dts \
- -undef -D__DTS__
+dtc_cpp_flags = -Wp,-MD,$(depfile).pre -nostdinc \
+ -I$(srctree)/arch/$(SRCARCH)/dts \
+ -I$(srctree)/arch/$(SRCARCH)/dts/include \
+ -undef -D__DTS__
# Finds the multi-part object the current object will be linked into
modname-multi = $(sort $(foreach m,$(multi-used),\
@@ -212,20 +212,17 @@ $(obj)/%.dtb.S: $(obj)/%.dtb
$(call cmd,dt_S_dtb)
quiet_cmd_dtc = DTC $@
-cmd_dtc = $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 $(DTC_FLAGS) -d $(depfile) $<
+cmd_dtc = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
+ $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 \
+ -i $(srctree)/arch/$(SRCARCH)/dts $(DTC_FLAGS) \
+ -d $(depfile).dtc $(dtc-tmp) ; \
+ cat $(depfile).pre $(depfile).dtc > $(depfile)
$(obj)/%.dtb: $(src)/%.dts FORCE
$(call if_changed_dep,dtc)
dtc-tmp = $(subst $(comma),_,$(dot-target).dts)
-quiet_cmd_dtc_cpp = DTC+CPP $@
-cmd_dtc_cpp = $(CPP) $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
- $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 $(DTC_FLAGS) $(dtc-tmp)
-
-$(obj)/%.dtb: $(src)/%.dtsp FORCE
- $(call if_changed_dep,dtc_cpp)
-
# Bzip2
# ---------------------------------------------------------------------------
@@ -308,3 +305,28 @@ quiet_cmd_check_file_size = CHKSIZE $@
echo "$@ size $$size > of the maximum size $$max_size" >&2; \
exit 1 ; \
fi;
+
+quiet_cmd_imximage__S_dcd= DCD_S $@
+cmd_imximage_S_dcd= \
+( \
+ echo '\#include <asm-generic/barebox.lds.h>'; \
+ echo '.balign STRUCT_ALIGNMENT'; \
+ echo '.global $(subst -,_,$(*F))_start'; \
+ echo '$(subst -,_,$(*F))_start:'; \
+ echo '.incbin "$<" '; \
+ echo '$(subst -,_,$(*F))_end:'; \
+ echo '.global $(subst -,_,$(*F))_end'; \
+ echo '.balign STRUCT_ALIGNMENT'; \
+) > $@
+
+quiet_cmd_dcd = DCD $@
+ cmd_dcd = $(objtree)/scripts/imx/imx-image -d -o $@ -c $<
+
+$(obj)/%.dcd: $(obj)/%.imxcfg FORCE
+ $(call if_changed,dcd)
+
+$(obj)/%.S: $(obj)/%.dcd
+ $(call cmd,imximage_S_dcd)
+
+quiet_cmd_imx_image = IMX-IMG $@
+ cmd_imx_image = $(obj)/scripts/imx/imx-image -b -c $(CFG_$(@F)) -f $< -o $@
diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c
index ea26b23de0..078fe1d64e 100644
--- a/scripts/basic/fixdep.c
+++ b/scripts/basic/fixdep.c
@@ -138,38 +138,36 @@ static void print_cmdline(void)
printf("cmd_%s := %s\n\n", target, cmdline);
}
-char * str_config = NULL;
-int size_config = 0;
-int len_config = 0;
+struct item {
+ struct item *next;
+ unsigned int len;
+ unsigned int hash;
+ char name[0];
+};
-/*
- * Grow the configuration string to a desired length.
- * Usually the first growth is plenty.
- */
-static void grow_config(int len)
-{
- while (len_config + len > size_config) {
- if (size_config == 0)
- size_config = 2048;
- str_config = realloc(str_config, size_config *= 2);
- if (str_config == NULL)
- { perror("fixdep:malloc"); exit(1); }
- }
-}
+#define HASHSZ 256
+static struct item *hashtab[HASHSZ];
+static unsigned int strhash(const char *str, unsigned int sz)
+{
+ /* fnv32 hash */
+ unsigned int i, hash = 2166136261U;
+ for (i = 0; i < sz; i++)
+ hash = (hash ^ str[i]) * 0x01000193;
+ return hash;
+}
/*
* Lookup a value in the configuration string.
*/
-static int is_defined_config(const char * name, int len)
+static int is_defined_config(const char *name, int len, unsigned int hash)
{
- const char * pconfig;
- const char * plast = str_config + len_config - len;
- for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) {
- if (pconfig[ -1] == '\n'
- && pconfig[len] == '\n'
- && !memcmp(pconfig, name, len))
+ struct item *aux;
+
+ for (aux = hashtab[hash % HASHSZ]; aux; aux = aux->next) {
+ if (aux->hash == hash && aux->len == len &&
+ memcmp(aux->name, name, len) == 0)
return 1;
}
return 0;
@@ -178,13 +176,19 @@ static int is_defined_config(const char * name, int len)
/*
* Add a new value to the configuration string.
*/
-static void define_config(const char * name, int len)
+static void define_config(const char *name, int len, unsigned int hash)
{
- grow_config(len + 1);
+ struct item *aux = malloc(sizeof(*aux) + len);
- memcpy(str_config+len_config, name, len);
- len_config += len;
- str_config[len_config++] = '\n';
+ if (!aux) {
+ perror("fixdep:malloc");
+ exit(1);
+ }
+ memcpy(aux->name, name, len);
+ aux->len = len;
+ aux->hash = hash;
+ aux->next = hashtab[hash % HASHSZ];
+ hashtab[hash % HASHSZ] = aux;
}
/*
@@ -192,40 +196,49 @@ static void define_config(const char * name, int len)
*/
static void clear_config(void)
{
- len_config = 0;
- define_config("", 0);
+ struct item *aux, *next;
+ unsigned int i;
+
+ for (i = 0; i < HASHSZ; i++) {
+ for (aux = hashtab[i]; aux; aux = next) {
+ next = aux->next;
+ free(aux);
+ }
+ hashtab[i] = NULL;
+ }
}
/*
* Record the use of a CONFIG_* word.
*/
-static void use_config(char *m, int slen)
+static void use_config(const char *m, int slen)
{
- char s[PATH_MAX];
- char *p;
+ unsigned int hash = strhash(m, slen);
+ int c, i;
- if (is_defined_config(m, slen))
+ if (is_defined_config(m, slen, hash))
return;
- define_config(m, slen);
-
- memcpy(s, m, slen); s[slen] = 0;
+ define_config(m, slen, hash);
- for (p = s; p < s + slen; p++) {
- if (*p == '_')
- *p = '/';
+ printf(" $(wildcard include/config/");
+ for (i = 0; i < slen; i++) {
+ c = m[i];
+ if (c == '_')
+ c = '/';
else
- *p = tolower((int)*p);
+ c = tolower(c);
+ putchar(c);
}
- printf(" $(wildcard include/config/%s.h) \\\n", s);
+ printf(".h) \\\n");
}
-static void parse_config_file(char *map, size_t len)
+static void parse_config_file(const char *map, size_t len)
{
- int *end = (int *) (map + len);
+ const int *end = (const int *) (map + len);
/* start at +1, so that p can never be < map */
- int *m = (int *) map + 1;
- char *p, *q;
+ const int *m = (const int *) map + 1;
+ const char *p, *q;
for (; m < end; m++) {
if (*m == INT_CONF) { p = (char *) m ; goto conf; }
@@ -265,7 +278,7 @@ static int strrcmp(char *s, char *sub)
return memcmp(s + slen - sublen, sub, sublen);
}
-static void do_config_file(char *filename)
+static void do_config_file(const char *filename)
{
struct stat st;
int fd;
@@ -273,7 +286,7 @@ static void do_config_file(char *filename)
fd = open(filename, O_RDONLY);
if (fd < 0) {
- fprintf(stderr, "fixdep: ");
+ fprintf(stderr, "fixdep: error opening config file: ");
perror(filename);
exit(2);
}
@@ -296,42 +309,89 @@ static void do_config_file(char *filename)
close(fd);
}
+/*
+ * Important: The below generated source_foo.o and deps_foo.o variable
+ * assignments are parsed not only by make, but also by the rather simple
+ * parser in scripts/mod/sumversion.c.
+ */
static void parse_dep_file(void *map, size_t len)
{
char *m = map;
char *end = m + len;
char *p;
char s[PATH_MAX];
-
- p = strchr(m, ':');
- if (!p) {
- fprintf(stderr, "fixdep: parse error\n");
- exit(1);
- }
- memcpy(s, m, p-m); s[p-m] = 0;
- printf("deps_%s := \\\n", target);
- m = p+1;
+ int is_target;
+ int saw_any_target = 0;
+ int is_first_dep = 0;
clear_config();
while (m < end) {
+ /* Skip any "white space" */
while (m < end && (*m == ' ' || *m == '\\' || *m == '\n'))
m++;
+ /* Find next "white space" */
p = m;
- while (p < end && *p != ' ') p++;
- if (p == end) {
- do p--; while (!isalnum(*p));
+ while (p < end && *p != ' ' && *p != '\\' && *p != '\n')
p++;
+ /* Is the token we found a target name? */
+ is_target = (*(p-1) == ':');
+ /* Don't write any target names into the dependency file */
+ if (is_target) {
+ /* The /next/ file is the first dependency */
+ is_first_dep = 1;
+ } else {
+ /* Save this token/filename */
+ memcpy(s, m, p-m);
+ s[p - m] = 0;
+
+ /* Ignore certain dependencies */
+ if (strrcmp(s, "include/generated/autoconf.h") &&
+ strrcmp(s, "arch/um/include/uml-config.h") &&
+ strrcmp(s, "include/linux/kconfig.h") &&
+ strrcmp(s, ".ver")) {
+ /*
+ * Do not list the source file as dependency,
+ * so that kbuild is not confused if a .c file
+ * is rewritten into .S or vice versa. Storing
+ * it in source_* is needed for modpost to
+ * compute srcversions.
+ */
+ if (is_first_dep) {
+ /*
+ * If processing the concatenation of
+ * multiple dependency files, only
+ * process the first target name, which
+ * will be the original source name,
+ * and ignore any other target names,
+ * which will be intermediate temporary
+ * files.
+ */
+ if (!saw_any_target) {
+ saw_any_target = 1;
+ printf("source_%s := %s\n\n",
+ target, s);
+ printf("deps_%s := \\\n",
+ target);
+ }
+ is_first_dep = 0;
+ } else
+ printf(" %s \\\n", s);
+ do_config_file(s);
+ }
}
- memcpy(s, m, p-m); s[p-m] = 0;
- if (strrcmp(s, "include/generated/autoconf.h") &&
- strrcmp(s, "arch/um/include/uml-config.h") &&
- strrcmp(s, ".ver")) {
- printf(" %s \\\n", s);
- do_config_file(s);
- }
+ /*
+ * Start searching for next token immediately after the first
+ * "whitespace" character that follows this token.
+ */
m = p + 1;
}
+
+ if (!saw_any_target) {
+ fprintf(stderr, "fixdep: parse error; no targets found\n");
+ exit(1);
+ }
+
printf("\n%s: $(deps_%s)\n\n", target, target);
printf("$(deps_%s):\n", target);
}
@@ -344,11 +404,15 @@ static void print_deps(void)
fd = open(depfile, O_RDONLY);
if (fd < 0) {
- fprintf(stderr, "fixdep: ");
+ fprintf(stderr, "fixdep: error opening depfile: ");
perror(depfile);
exit(2);
}
- fstat(fd, &st);
+ if (fstat(fd, &st) < 0) {
+ fprintf(stderr, "fixdep: error fstat'ing depfile: ");
+ perror(depfile);
+ exit(2);
+ }
if (st.st_size == 0) {
fprintf(stderr,"fixdep: %s is empty\n",depfile);
close(fd);
@@ -374,7 +438,7 @@ static void traps(void)
int *p = (int *)test;
if (*p != INT_CONF) {
- fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianess? %#x\n",
+ fprintf(stderr, "fixdep: sizeof(int) != 4 or wrong endianness? %#x\n",
*p);
exit(2);
}
diff --git a/scripts/imx/.gitignore b/scripts/imx/.gitignore
new file mode 100644
index 0000000000..84e6f2b406
--- /dev/null
+++ b/scripts/imx/.gitignore
@@ -0,0 +1,2 @@
+imx-usb-loader
+imx-image
diff --git a/scripts/imx/Makefile b/scripts/imx/Makefile
new file mode 100644
index 0000000000..be0b490108
--- /dev/null
+++ b/scripts/imx/Makefile
@@ -0,0 +1,10 @@
+hostprogs-$(CONFIG_ARCH_IMX_IMXIMAGE) += imx-image
+hostprogs-$(CONFIG_ARCH_IMX_USBLOADER) += imx-usb-loader
+
+always := $(hostprogs-y)
+
+HOSTCFLAGS_imx-usb-loader.o = `pkg-config --cflags libusb-1.0`
+HOSTLOADLIBES_imx-usb-loader = `pkg-config --libs libusb-1.0`
+
+imx-usb-loader-objs := imx-usb-loader.o
+imx-image-objs := imx-image.o
diff --git a/scripts/imx/README b/scripts/imx/README
new file mode 100644
index 0000000000..0d6d0d03a8
--- /dev/null
+++ b/scripts/imx/README
@@ -0,0 +1,89 @@
+imx-usb-loader Tools
+
+The Freescale i.MX SoCs support bootstrapping from USB. These are host
+side utilities handling this bootstrap process.
+
+The imx-usb-loader tool is used to upload and start i.MX images. These
+are images containing a DCD (Device Configuration Data) table. To generate
+these images from raw binaries use the imx-image tool.
+
+imx-image
+---------
+
+The imx-image tool can be used to generate imximages from raw binaries.
+It requires an configuration file describing how to setup the SDRAM on
+a particular board. This mainly consists of a poke table. The recognized
+options in this file are:
+
+soc <soctype> soctype can be one of imx35, imx51, imx53, imx6
+loadaddr <adr> The address the binary is uploaded to
+dcdofs <ofs> The offset of the image header in the image. This should be:
+ 0x400 - MMC/SD, NAND, serial ROM, PATA, SATA
+ 0x1000 - NOR Flash
+ 0x100 - OneNAND
+wm 8 <adr> <value> do a byte memory write
+wm 16 <adr> <value> do a short memory write
+wm 32 <adr> <value> do a word memory write
+check <width> <cond> <addr> <mask> Poll until condition becomes true.
+ with <cond> being one of:
+ while_all_bits_clear,
+ while_all_bits_set,
+ while_any_bit_clear,
+ while_any_bit_set
+
+the i.MX SoCs support a wide range of fancy things doing with the flash header.
+We limit ourselves to a very simple case, that is the flash header has a fixed
+size of 0x1000 bytes. The application is expected right thereafter, so if you
+specify a loadaddr of 0x80000000 in the config file, the first 0x1000 bytes
+are occupied by the flash header. The raw image inside the imximage will then
+end up at 0x80001000 from where it is then executed.
+
+Example config file, suitable for an Eukra cpuimx35:
+
+soc imx35
+dcdofs 0x400
+loadaddr 0x80000000
+wm 32 0x53F80004 0x00821000
+wm 32 0x53F80004 0x00821000
+wm 32 0xb8001010 0x00000004
+wm 32 0xB8001010 0x0000000C
+wm 32 0xb8001004 0x0009572B
+wm 32 0xb8001000 0x92220000
+wm 8 0x80000400 0xda
+wm 32 0xb8001000 0xa2220000
+wm 32 0x80000000 0x12344321
+wm 32 0x80000000 0x12344321
+wm 32 0xb8001000 0xb2220000
+wm 8 0x80000033 0xda
+wm 8 0x82000000 0xda
+wm 32 0xb8001000 0x82224080
+wm 32 0xb8001010 0x00000004
+
+example call:
+
+imx-image -c cpuimx35.cfg -f raw.bin -o imximage.bin
+
+imx-usb-loader
+--------------
+
+This utility is used to upload an imximage to a board. Some bootloaders directly
+generate this file format, with others you can generate such an image with the
+imx-image tool. The only required argument is the image file to upload. imx-usb-loader
+will then look for a supported device, upload the file and execute it.
+
+example usage:
+
+imx-usb-loader imximage.bin
+
+Some technical notes: The i.MX SoCs USB ROM boot mode supports doing register writes
+and file uploads. The files are usually uploaded to SDRAM. For this to work the SDRAM
+has to be initialized first. The information necessary to do this is contained in the
+imximage itself, more exactly in the DCD table. The imx-usb-loader parses this table
+and translates the DCD into register writes, basically it resembles what the i.MX would
+do in ROM code when the same image would be loaded from another bootsource like SD/MMC
+cards. Still the i.MX needs the DCD table to be uploaded. The i.MX would execute the DCD
+data again, which would result in corrupting the just configured SDRAM. The imx-usb-loader
+prevents this by setting the DCD length to 0x0 before uploading the image.
+The i.MX Boot ROM supports different types of images to upload. The imx-usb-loader currently
+only handles the simple case of uploading a single image which is executed right after
+downloading.
diff --git a/scripts/imx/imx-image.c b/scripts/imx/imx-image.c
new file mode 100644
index 0000000000..2f52015ae1
--- /dev/null
+++ b/scripts/imx/imx-image.c
@@ -0,0 +1,744 @@
+/*
+ * (C) Copyright 2013 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ *
+ */
+#include <stdio.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <endian.h>
+
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
+
+#define MAX_DCD 1024
+
+static uint32_t image_load_addr;
+static uint32_t image_dcd_offset;
+static uint32_t dcdtable[MAX_DCD];
+static int curdcd;
+static int header_version;
+static int add_barebox_header;
+
+/*
+ * ============================================================================
+ * i.MX flash header v1 handling. Found on i.MX35 and i.MX51
+ * ============================================================================
+ */
+struct imx_flash_header {
+ uint32_t app_code_jump_vector;
+ uint32_t app_code_barker;
+ uint32_t app_code_csf;
+ uint32_t dcd_ptr_ptr;
+ uint32_t super_root_key;
+ uint32_t dcd;
+ uint32_t app_dest;
+ uint32_t dcd_barker;
+ uint32_t dcd_block_len;
+} __attribute__((packed));
+
+#define FLASH_HEADER_OFFSET 0x400
+#define DCD_BARKER 0xb17219e9
+
+static uint32_t bb_header[] = {
+ 0xea0003fe, /* b 0x1000 */
+ 0xeafffffe, /* 1: b 1b */
+ 0xeafffffe, /* 1: b 1b */
+ 0xeafffffe, /* 1: b 1b */
+ 0xeafffffe, /* 1: b 1b */
+ 0xeafffffe, /* 1: b 1b */
+ 0xeafffffe, /* 1: b 1b */
+ 0xeafffffe, /* 1: b 1b */
+ 0x65726162, /* 'bare' */
+ 0x00786f62, /* 'box\0' */
+ 0x00000000,
+ 0x00000000,
+ 0x55555555,
+ 0x55555555,
+ 0x55555555,
+ 0x55555555,
+ 0x55555555,
+ 0x55555555,
+ 0x55555555,
+ 0x55555555,
+};
+
+static int add_header_v1(void *buf, int offset, uint32_t loadaddr, uint32_t imagesize)
+{
+ struct imx_flash_header *hdr;
+ int dcdsize = curdcd * sizeof(uint32_t);
+
+ if (add_barebox_header)
+ memcpy(buf, bb_header, sizeof(bb_header));
+
+ buf += offset;
+ hdr = buf;
+
+ hdr->app_code_jump_vector = loadaddr + 0x1000;
+ hdr->app_code_barker = 0x000000b1;
+ hdr->app_code_csf = 0x0;
+ hdr->dcd_ptr_ptr = loadaddr + offset + offsetof(struct imx_flash_header, dcd);
+ hdr->super_root_key = 0x0;
+ hdr->dcd = loadaddr + offset + offsetof(struct imx_flash_header, dcd_barker);
+ hdr->app_dest = loadaddr;
+ hdr->dcd_barker = DCD_BARKER;
+ hdr->dcd_block_len = dcdsize;
+
+ buf += sizeof(struct imx_flash_header);
+
+ memcpy(buf, dcdtable, dcdsize);
+
+ buf += dcdsize;
+
+ *(uint32_t *)buf = imagesize;
+
+ return 0;
+}
+
+static int write_mem_v1(uint32_t addr, uint32_t val, int width)
+{
+ if (curdcd > MAX_DCD - 3) {
+ fprintf(stderr, "At maximum %d dcd entried are allowed\n", MAX_DCD);
+ return -ENOMEM;
+ }
+
+ dcdtable[curdcd++] = width;
+ dcdtable[curdcd++] = addr;
+ dcdtable[curdcd++] = val;
+
+ return 0;
+}
+
+/*
+ * ============================================================================
+ * i.MX flash header v2 handling. Found on i.MX53 and i.MX6
+ * ============================================================================
+ */
+
+struct imx_boot_data {
+ uint32_t start;
+ uint32_t size;
+ uint32_t plugin;
+} __attribute__((packed));
+
+#define TAG_IVT_HEADER 0xd1
+#define IVT_VERSION 0x40
+#define TAG_DCD_HEADER 0xd2
+#define DCD_VERSION 0x40
+#define TAG_WRITE 0xcc
+#define TAG_CHECK 0xcf
+
+struct imx_ivt_header {
+ uint8_t tag;
+ uint16_t length;
+ uint8_t version;
+} __attribute__((packed));
+
+struct imx_flash_header_v2 {
+ struct imx_ivt_header header;
+
+ uint32_t entry;
+ uint32_t reserved1;
+ uint32_t dcd_ptr;
+ uint32_t boot_data_ptr;
+ uint32_t self;
+ uint32_t csf;
+ uint32_t reserved2;
+
+ struct imx_boot_data boot_data;
+ struct imx_ivt_header dcd_header;
+} __attribute__((packed));
+
+static int add_header_v2(void *buf, int offset, uint32_t loadaddr, uint32_t imagesize)
+{
+ struct imx_flash_header_v2 *hdr;
+ int dcdsize = curdcd * sizeof(uint32_t);
+
+ if (add_barebox_header)
+ memcpy(buf, bb_header, sizeof(bb_header));
+
+ buf += offset;
+ hdr = buf;
+
+ hdr->header.tag = TAG_IVT_HEADER;
+ hdr->header.length = htobe16(32);
+ hdr->header.version = IVT_VERSION;
+
+ hdr->entry = loadaddr + 0x1000;
+ hdr->dcd_ptr = loadaddr + 0x400 + offsetof(struct imx_flash_header_v2, dcd_header);
+ hdr->boot_data_ptr = loadaddr + 0x400 + offsetof(struct imx_flash_header_v2, boot_data);
+ hdr->self = loadaddr + 0x400;
+
+ hdr->boot_data.start = loadaddr;
+ hdr->boot_data.size = imagesize;
+
+ hdr->dcd_header.tag = TAG_DCD_HEADER;
+ hdr->dcd_header.length = htobe16(sizeof(uint32_t) + dcdsize);
+ hdr->dcd_header.version = DCD_VERSION;
+
+ buf += sizeof(*hdr);
+
+ memcpy(buf, dcdtable, dcdsize);
+
+ return 0;
+}
+
+static void usage(const char *prgname)
+{
+ fprintf(stderr, "usage: %s [OPTIONS]\n\n"
+ "-c <config> specify configuration file\n"
+ "-f <input> input image file\n"
+ "-o <output> output file\n"
+ "-b add barebox header to image. If used, barebox recognizes\n"
+ " the image as regular barebox image which can be used as\n"
+ " second stage image\n"
+ "-h this help\n", prgname);
+ exit(1);
+}
+
+#define MAXARGS 5
+
+static int parse_line(char *line, char *argv[])
+{
+ int nargs = 0;
+
+ while (nargs < MAXARGS) {
+
+ /* skip any white space */
+ while ((*line == ' ') || (*line == '\t'))
+ ++line;
+
+ if (*line == '\0') /* end of line, no more args */
+ argv[nargs] = NULL;
+
+ if (*line == '\0') { /* end of line, no more args */
+ argv[nargs] = NULL;
+ return nargs;
+ }
+
+ argv[nargs++] = line; /* begin of argument string */
+
+ /* find end of string */
+ while (*line && (*line != ' ') && (*line != '\t'))
+ ++line;
+
+ if (*line == '\0') { /* end of line, no more args */
+ argv[nargs] = NULL;
+ return nargs;
+ }
+
+ *line++ = '\0'; /* terminate current arg */
+ }
+
+ printf("** Too many args (max. %d) **\n", MAXARGS);
+
+ return nargs;
+}
+
+struct command {
+ const char *name;
+ int (*parse)(int argc, char *argv[]);
+};
+
+static uint32_t last_cmd;
+static int last_cmd_len;
+static uint32_t *last_dcd;
+
+static void check_last_dcd(uint32_t cmd)
+{
+ if (last_dcd) {
+ if (last_cmd == cmd) {
+ return;
+ } else {
+ uint32_t l = be32toh(*last_dcd);
+
+ l |= last_cmd_len << 8;
+
+ *last_dcd = htobe32(l);
+
+ last_dcd = NULL;
+ }
+ }
+
+ if (!cmd)
+ return;
+
+ if (!last_dcd) {
+ last_dcd = &dcdtable[curdcd++];
+ *last_dcd = htobe32(cmd);
+ last_cmd_len = sizeof(uint32_t);
+ last_cmd = cmd;
+ }
+}
+
+static int write_mem_v2(uint32_t addr, uint32_t val, int width)
+{
+ uint32_t cmd;
+
+ cmd = (TAG_WRITE << 24) | width;
+
+ if (curdcd > MAX_DCD - 3) {
+ fprintf(stderr, "At maximum %d dcd entried are allowed\n", MAX_DCD);
+ return -ENOMEM;
+ }
+
+ check_last_dcd(cmd);
+
+ last_cmd_len += sizeof(uint32_t) * 2;
+ dcdtable[curdcd++] = htobe32(addr);
+ dcdtable[curdcd++] = htobe32(val);
+
+ return 0;
+}
+
+static const char *check_cmds[] = {
+ "while_all_bits_clear", /* while ((*address & mask) == 0); */
+ "while_all_bits_set" , /* while ((*address & mask) == mask); */
+ "while_any_bit_clear", /* while ((*address & mask) != mask); */
+ "while_any_bit_set", /* while ((*address & mask) != 0); */
+};
+
+static void do_cmd_check_usage(void)
+{
+ fprintf(stderr,
+ "usage: check <width> <cmd> <addr> <mask>\n"
+ "<width> access width in bytes [1|2|4]\n"
+ "with <cmd> one of:\n"
+ "while_all_bits_clear: while ((*addr & mask) == 0)\n"
+ "while_all_bits_set: while ((*addr & mask) == mask)\n"
+ "while_any_bit_clear: while ((*addr & mask) != mask)\n"
+ "while_any_bit_set: while ((*addr & mask) != 0)\n");
+}
+
+static int do_cmd_check(int argc, char *argv[])
+{
+ uint32_t addr, mask, cmd;
+ int i, width;
+ const char *scmd;
+
+ if (argc < 5) {
+ do_cmd_check_usage();
+ return -EINVAL;
+ }
+
+ width = strtoul(argv[1], NULL, 0) >> 3;
+ scmd = argv[2];
+ addr = strtoul(argv[3], NULL, 0);
+ mask = strtoul(argv[4], NULL, 0);
+
+ switch (width) {
+ case 1:
+ case 2:
+ case 4:
+ break;
+ default:
+ fprintf(stderr, "illegal width %d\n", width);
+ return -EINVAL;
+ };
+
+ if (curdcd > MAX_DCD - 3) {
+ fprintf(stderr, "At maximum %d dcd entried are allowed\n", MAX_DCD);
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < ARRAY_SIZE(check_cmds); i++) {
+ if (!strcmp(scmd, check_cmds[i]))
+ break;
+ }
+
+ if (i == ARRAY_SIZE(check_cmds)) {
+ do_cmd_check_usage();
+ return -EINVAL;
+ }
+
+ cmd = (TAG_CHECK << 24) | (i << 3) | width;
+
+ check_last_dcd(cmd);
+
+ last_cmd_len += sizeof(uint32_t) * 2;
+ dcdtable[curdcd++] = htobe32(addr);
+ dcdtable[curdcd++] = htobe32(mask);
+
+ return 0;
+}
+
+static int do_cmd_write_mem(int argc, char *argv[])
+{
+ uint32_t addr, val, width;
+
+ if (argc != 4) {
+ fprintf(stderr, "usage: wm [8|16|32] <addr> <val>\n");
+ return -EINVAL;
+ }
+
+ width = strtoul(argv[1], NULL, 0);
+ addr = strtoul(argv[2], NULL, 0);
+ val = strtoul(argv[3], NULL, 0);
+
+ width >>= 3;
+
+ switch (width) {
+ case 1:
+ case 2:
+ case 4:
+ break;
+ default:
+ fprintf(stderr, "illegal width %d\n", width);
+ return -EINVAL;
+ };
+
+ switch (header_version) {
+ case 1:
+ return write_mem_v1(addr, val, width);
+ case 2:
+ return write_mem_v2(addr, val, width);
+ default:
+ return -EINVAL;
+ }
+}
+
+static int do_loadaddr(int argc, char *argv[])
+{
+ if (argc < 2)
+ return -EINVAL;
+
+ image_load_addr = strtoul(argv[1], NULL, 0);
+
+ return 0;
+}
+
+static int do_dcd_offset(int argc, char *argv[])
+{
+ if (argc < 2)
+ return -EINVAL;
+
+ image_dcd_offset = strtoul(argv[1], NULL, 0);
+
+ return 0;
+}
+
+struct soc_type {
+ char *name;
+ int header_version;
+};
+
+static struct soc_type socs[] = {
+ { .name = "imx35", .header_version = 1, },
+ { .name = "imx51", .header_version = 1, },
+ { .name = "imx53", .header_version = 2, },
+ { .name = "imx6", .header_version = 2, },
+};
+
+static int do_soc(int argc, char *argv[])
+{
+ char *soc;
+ int i;
+
+ if (argc < 2)
+ return -EINVAL;
+
+ soc = argv[1];
+
+ for (i = 0; i < ARRAY_SIZE(socs); i++) {
+ if (!strcmp(socs[i].name, soc)) {
+ header_version = socs[i].header_version;
+ return 0;
+ }
+ }
+
+ fprintf(stderr, "unkown SoC type \"%s\". Known SoCs are:\n", soc);
+ for (i = 0; i < ARRAY_SIZE(socs); i++)
+ fprintf(stderr, "%s ", socs[i].name);
+ fprintf(stderr, "\n");
+
+ return -EINVAL;
+}
+
+struct command cmds[] = {
+ {
+ .name = "wm",
+ .parse = do_cmd_write_mem,
+ }, {
+ .name = "check",
+ .parse = do_cmd_check,
+ }, {
+ .name = "loadaddr",
+ .parse = do_loadaddr,
+ }, {
+ .name = "dcdofs",
+ .parse = do_dcd_offset,
+ }, {
+ .name = "soc",
+ .parse = do_soc,
+ },
+};
+
+static int parse_config(const char *filename)
+{
+ FILE *f;
+ int lineno = 0;
+ char *line = NULL, *tmp;
+ size_t len;
+ char *argv[MAXARGS];
+ int nargs, i, ret;
+
+ f = fopen(filename, "r");
+ if (!f) {
+ fprintf(stderr, "Error: %s - Can't open DCD file\n", filename);
+ exit(1);
+ }
+
+ while ((getline(&line, &len, f)) > 0) {
+ lineno++;
+
+ tmp = strchr(line, '#');
+ if (tmp)
+ *tmp = 0;
+ tmp = strrchr(line, '\n');
+ if (tmp)
+ *tmp = 0;
+
+ nargs = parse_line(line, argv);
+ if (!nargs)
+ continue;
+
+ ret = -ENOENT;
+
+ for (i = 0; i < ARRAY_SIZE(cmds); i++) {
+ if (!strcmp(cmds[i].name, argv[0])) {
+ ret = cmds[i].parse(nargs, argv);
+ if (ret) {
+ fprintf(stderr, "error in line %d: %s\n",
+ lineno, strerror(-ret));
+ return ret;
+ }
+ break;
+ }
+ }
+
+ if (ret == -ENOENT) {
+ fprintf(stderr, "no such command: %s\n", argv[0]);
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+static int xread(int fd, void *buf, int len)
+{
+ int ret;
+
+ while (len) {
+ ret = read(fd, buf, len);
+ if (ret < 0)
+ return ret;
+ if (!ret)
+ return EOF;
+ buf += ret;
+ len -= ret;
+ }
+
+ return 0;
+}
+
+static int xwrite(int fd, void *buf, int len)
+{
+ int ret;
+
+ while (len) {
+ ret = write(fd, buf, len);
+ if (ret < 0)
+ return ret;
+ buf += ret;
+ len -= ret;
+ }
+
+ return 0;
+}
+
+static int write_dcd(const char *outfile)
+{
+ int outfd, ret;
+ int dcdsize = curdcd * sizeof(uint32_t);
+
+ outfd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+ if (outfd < 0) {
+ perror("open");
+ exit(1);
+ }
+
+ ret = xwrite(outfd, dcdtable, dcdsize);
+ if (ret < 0) {
+ perror("write");
+ exit(1);
+ }
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ int opt, ret;
+ char *configfile = NULL;
+ char *imagename = NULL;
+ char *outfile = NULL;
+ void *buf;
+ size_t image_size = 0;
+ struct stat s;
+ int infd, outfd;
+ int dcd_only = 0;
+
+ while ((opt = getopt(argc, argv, "c:hf:o:bd")) != -1) {
+ switch (opt) {
+ case 'c':
+ configfile = optarg;
+ break;
+ case 'f':
+ imagename = optarg;
+ break;
+ case 'o':
+ outfile = optarg;
+ break;
+ case 'b':
+ add_barebox_header = 1;
+ break;
+ case 'd':
+ dcd_only = 1;
+ break;
+ case 'h':
+ usage(argv[0]);
+ default:
+ exit(1);
+ }
+ }
+
+ if (!imagename && !dcd_only) {
+ fprintf(stderr, "image name not given\n");
+ exit(1);
+ }
+
+ if (!configfile) {
+ fprintf(stderr, "config file not given\n");
+ exit(1);
+ }
+
+ if (!outfile) {
+ fprintf(stderr, "output file not given\n");
+ exit(1);
+ }
+
+ if (!dcd_only) {
+ ret = stat(imagename, &s);
+ if (ret) {
+ perror("stat");
+ exit(1);
+ }
+
+ image_size = s.st_size;
+ }
+
+ ret = parse_config(configfile);
+ if (ret)
+ exit(1);
+
+ buf = calloc(4096, 1);
+ if (!buf)
+ exit(1);
+
+ if (!image_dcd_offset) {
+ fprintf(stderr, "no dcd offset given ('dcdofs'). Defaulting to 0x400\n");
+ image_dcd_offset = 0x400;
+ }
+
+ if (!header_version) {
+ fprintf(stderr, "no SoC given. (missing 'soc' in config)\n");
+ exit(1);
+ }
+
+ if (header_version == 2)
+ check_last_dcd(0);
+
+ if (dcd_only) {
+ ret = write_dcd(outfile);
+ if (ret)
+ exit(1);
+ exit (0);
+ }
+
+ switch (header_version) {
+ case 1:
+ add_header_v1(buf, image_dcd_offset, image_load_addr, image_size + 0x1000);
+ break;
+ case 2:
+ add_header_v2(buf, image_dcd_offset, image_load_addr, image_size + 0x1000);
+ break;
+ default:
+ fprintf(stderr, "Congratulations! You're welcome to implement header version %d\n",
+ header_version);
+ exit(1);
+ }
+
+ outfd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+ if (outfd < 0) {
+ perror("open");
+ exit(1);
+ }
+
+ ret = xwrite(outfd, buf, 4096);
+ if (ret < 0) {
+ perror("write");
+ exit(1);
+ }
+
+ infd = open(imagename, O_RDONLY);
+ if (infd < 0) {
+ perror("open");
+ exit(1);
+ }
+
+ while (image_size) {
+ int now = image_size < 4096 ? image_size : 4096;
+
+ ret = xread(infd, buf, now);
+ if (ret) {
+ perror("read");
+ exit(1);
+ }
+
+ ret = xwrite(outfd, buf, now);
+ if (ret) {
+ perror("write");
+ exit(1);
+ }
+
+ image_size -= now;
+ }
+
+ ret = close(outfd);
+ if (ret) {
+ perror("close");
+ exit(1);
+ }
+
+ exit(0);
+}
diff --git a/scripts/imx/imx-usb-loader.c b/scripts/imx/imx-usb-loader.c
new file mode 100644
index 0000000000..d58b1da3bd
--- /dev/null
+++ b/scripts/imx/imx-usb-loader.c
@@ -0,0 +1,1427 @@
+/*
+ * imx_usb:
+ *
+ * Program to download and execute an image over the USB boot protocol
+ * on i.MX series processors.
+ *
+ * Code originally written by Eric Nelson.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <time.h>
+
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/io.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <libusb.h>
+#include <getopt.h>
+
+#define get_min(a, b) (((a) < (b)) ? (a) : (b))
+
+int verbose;
+
+struct mach_id {
+ struct mach_id * next;
+ unsigned short vid;
+ unsigned short pid;
+ char file_name[256];
+ char *name;
+#define MODE_HID 0
+#define MODE_BULK 1
+ unsigned char mode;
+#define HDR_NONE 0
+#define HDR_MX51 1
+#define HDR_MX53 2
+ unsigned char header_type;
+ unsigned short max_transfer;
+};
+
+#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
+#endif
+
+struct usb_work {
+ char filename[256];
+ unsigned char dcd;
+ unsigned char clear_dcd;
+ unsigned char plug;
+#define J_ADDR 1
+#define J_HEADER 2
+#define J_HEADER2 3
+ unsigned char jump_mode;
+ unsigned jump_addr;
+};
+
+struct usb_id {
+ struct mach_id *mach_id;
+ struct usb_work *work;
+};
+
+struct mach_id imx_ids[] = {
+ {
+ .vid = 0x066f,
+ .pid = 0x3780,
+ .name = "i.MX23",
+ .mode = MODE_BULK,
+ }, {
+ .vid = 0x15a2,
+ .pid = 0x004f,
+ .name = "i.MX28",
+ }, {
+ .vid = 0x15a2,
+ .pid = 0x0052,
+ .name = "i.MX50",
+ }, {
+ .vid = 0x15a2,
+ .pid = 0x0054,
+ .name = "i.MX6",
+ .header_type = HDR_MX53,
+ .mode = MODE_HID,
+ .max_transfer = 1024,
+ }, {
+ .vid = 0x15a2,
+ .pid = 0x0041,
+ .name = "i.MX51",
+ .header_type = HDR_MX51,
+ .mode = MODE_BULK,
+ .max_transfer = 64,
+ }, {
+ .vid = 0x15a2,
+ .pid = 0x004e,
+ .name = "i.MX53",
+ .header_type = HDR_MX53,
+ .mode = MODE_BULK,
+ .max_transfer = 512,
+ }, {
+ .vid = 0x15a2,
+ .pid = 0x0030,
+ .name = "i.MX35",
+ .header_type = HDR_MX51,
+ .mode = MODE_BULK,
+ .max_transfer = 64,
+ },
+};
+
+static struct mach_id *imx_device(unsigned short vid, unsigned short pid)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(imx_ids); i++) {
+ struct mach_id *id = &imx_ids[i];
+ if (id->vid == vid && id->pid == pid) {
+ fprintf(stderr, "found %s USB device [%04x:%04x]\n",
+ id->name, vid, pid);
+ return id;
+ }
+ }
+
+ return NULL;
+}
+
+static libusb_device *find_imx_dev(libusb_device **devs, struct mach_id **pp_id)
+{
+ int i = 0;
+ struct mach_id *p;
+
+ for (;;) {
+ struct libusb_device_descriptor desc;
+ int r;
+
+ libusb_device *dev = devs[i++];
+ if (!dev)
+ break;
+
+ r = libusb_get_device_descriptor(dev, &desc);
+ if (r < 0) {
+ fprintf(stderr, "failed to get device descriptor");
+ return NULL;
+ }
+
+ p = imx_device(desc.idVendor, desc.idProduct);
+ if (p) {
+ *pp_id = p;
+ return dev;
+ }
+ }
+ *pp_id = NULL;
+
+ return NULL;
+}
+
+static void dump_long(unsigned char *src, unsigned cnt, unsigned addr)
+{
+ unsigned *p = (unsigned *)src;
+ while (cnt >= 32) {
+ printf("%08x: %08x %08x %08x %08x %08x %08x %08x %08x\n",
+ addr, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+ p += 8;
+ cnt -= 32;
+ addr += 32;
+ }
+ if (cnt) {
+ printf("%08x:", addr);
+ while (cnt >= 4) {
+ printf(" %08x", p[0]);
+ p++;
+ cnt -= 4;
+ }
+ printf("\n");
+ }
+}
+
+static void dump_bytes(unsigned char *src, unsigned cnt, unsigned addr)
+{
+ unsigned char *p = src;
+ int i;
+
+ while (cnt >= 16) {
+ printf("%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
+ addr,
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], p[9], p[10],
+ p[11], p[12], p[13], p[14], p[15]);
+ p += 16;
+ cnt -= 16;
+ addr += 16;
+ }
+
+ if (cnt) {
+ printf("%08x:", addr);
+ i = 0;
+ while (cnt) {
+ printf(" %02x", p[0]);
+ p++;
+ cnt--;
+ i++;
+ if (cnt) if (i == 4) {
+ i = 0;
+ printf(" ");
+ }
+ }
+ printf("\n");
+ }
+}
+
+static long get_file_size(FILE *xfile)
+{
+ long size;
+ fseek(xfile, 0, SEEK_END);
+ size = ftell(xfile);
+ rewind(xfile);
+
+ return size;
+}
+
+/*
+ * HID Class-Specific Requests values. See section 7.2 of the HID specifications
+ */
+#define HID_GET_REPORT 0x01
+#define HID_GET_IDLE 0x02
+#define HID_GET_PROTOCOL 0x03
+#define HID_SET_REPORT 0x09
+#define HID_SET_IDLE 0x0A
+#define HID_SET_PROTOCOL 0x0B
+#define HID_REPORT_TYPE_INPUT 0x01
+#define HID_REPORT_TYPE_OUTPUT 0x02
+#define HID_REPORT_TYPE_FEATURE 0x03
+#define CTRL_IN LIBUSB_ENDPOINT_IN |LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE
+#define CTRL_OUT LIBUSB_ENDPOINT_OUT|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE
+
+#define EP_IN 0x80
+
+/*
+ * For HID class drivers, 4 reports are used to implement
+ * Serial Download protocol(SDP)
+ * Report 1 (control out endpoint) 16 byte SDP comand
+ * (total of 17 bytes with 1st byte report id of 0x01
+ * Report 2 (control out endpoint) data associated with report 1 commands
+ * (max size of 1025 with 1st byte of 0x02)
+ * Report 3 (interrupt in endpoint) HAB security state
+ * (max size of 5 bytes with 1st byte of 0x03)
+ * (0x12343412 production)
+ * (0x56787856 engineering)
+ * Report 4 (interrupt in endpoint) date associated with report 1 commands
+ * (max size of 65 bytes with 1st byte of 0x04)
+ *
+ */
+/*
+ * For Bulk class drivers, the device is configured as
+ * EP0IN, EP0OUT control transfer
+ * EP1OUT - bulk out
+ * (max packet size of 512 bytes)
+ * EP2IN - bulk in
+ * (max packet size of 512 bytes)
+ */
+static int transfer(struct libusb_device_handle *h, int report, unsigned char *p, unsigned cnt,
+ int* last_trans, struct usb_id *p_id)
+{
+ int err;
+ if (cnt > p_id->mach_id->max_transfer)
+ cnt = p_id->mach_id->max_transfer;
+
+ if (verbose > 4) {
+ printf("report=%i\n", report);
+ if (report < 3)
+ dump_bytes(p, cnt, 0);
+ }
+
+ if (p_id->mach_id->mode == MODE_BULK) {
+ *last_trans = 0;
+ err = libusb_bulk_transfer(h, (report < 3) ? 1 : 2 + EP_IN, p, cnt, last_trans, 1000);
+ } else {
+ unsigned char tmp[1028];
+
+ tmp[0] = (unsigned char)report;
+
+ if (report < 3) {
+ memcpy(&tmp[1], p, cnt);
+ err = libusb_control_transfer(h,
+ CTRL_OUT,
+ HID_SET_REPORT,
+ (HID_REPORT_TYPE_OUTPUT << 8) | report,
+ 0,
+ tmp, cnt + 1, 1000);
+ *last_trans = (err > 0) ? err - 1 : 0;
+ if (err > 0)
+ err = 0;
+ } else {
+ *last_trans = 0;
+ memset(&tmp[1], 0, cnt);
+ err = libusb_interrupt_transfer(h, 1 + EP_IN, tmp, cnt + 1, last_trans, 1000);
+ if (err >= 0) {
+ if (tmp[0] == (unsigned char)report) {
+ if (*last_trans > 1) {
+ *last_trans -= 1;
+ memcpy(p, &tmp[1], *last_trans);
+ }
+ } else {
+ printf("Unexpected report %i err=%i, cnt=%i, last_trans=%i, %02x %02x %02x %02x\n",
+ tmp[0], err, cnt, *last_trans, tmp[0], tmp[1], tmp[2], tmp[3]);
+ err = 0;
+ }
+ }
+ }
+ }
+
+ if (verbose > 4 && report >= 3)
+ dump_bytes(p, cnt, 0);
+
+ return err;
+}
+
+int do_status(libusb_device_handle *h, struct usb_id *p_id)
+{
+ int last_trans;
+ unsigned char tmp[64];
+ int retry = 0;
+ int err;
+ const unsigned char status_command[] = {
+ 5, 5, 0, 0, 0, 0,
+ 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0
+ };
+
+ for (;;) {
+ err = transfer(h, 1, (unsigned char*)status_command, 16, &last_trans, p_id);
+
+ if (verbose > 2)
+ printf("report 1, wrote %i bytes, err=%i\n", last_trans, err);
+
+ memset(tmp, 0, sizeof(tmp));
+
+ err = transfer(h, 3, tmp, 64, &last_trans, p_id);
+
+ if (verbose > 2) {
+ printf("report 3, read %i bytes, err=%i\n", last_trans, err);
+ printf("read=%02x %02x %02x %02x\n", tmp[0], tmp[1], tmp[2], tmp[3]);
+ }
+
+ if (!err)
+ break;
+
+ retry++;
+
+ if (retry > 5)
+ break;
+ }
+
+ if (p_id->mach_id->mode == MODE_HID) {
+ err = transfer(h, 4, tmp, sizeof(tmp), &last_trans, p_id);
+ if (err)
+ printf("4 in err=%i, last_trans=%i %02x %02x %02x %02x\n",
+ err, last_trans, tmp[0], tmp[1], tmp[2], tmp[3]);
+ }
+
+ return err;
+}
+
+struct boot_data {
+ uint32_t dest;
+ uint32_t image_len;
+ uint32_t plugin;
+};
+
+struct imx_flash_header_v2 {
+#define IVT_BARKER 0x402000d1
+ uint32_t barker;
+ uint32_t start_addr;
+ uint32_t reserv1;
+ uint32_t dcd_ptr;
+ uint32_t boot_data_ptr; /* struct boot_data * */
+ uint32_t self_ptr; /* struct imx_flash_header_v2 *, this - boot_data.start = offset linked at */
+ uint32_t app_code_csf;
+ uint32_t reserv2;
+};
+
+/*
+ * MX51 header type
+ */
+struct imx_flash_header_v1 {
+ uint32_t app_start_addr;
+#define APP_BARKER 0xb1
+#define DCD_BARKER 0xb17219e9
+ uint32_t app_barker;
+ uint32_t csf_ptr;
+ uint32_t dcd_ptr_ptr;
+ uint32_t srk_ptr;
+ uint32_t dcd_ptr;
+ uint32_t app_dest_ptr;
+};
+
+#define V(a) (((a) >> 24) & 0xff), (((a) >> 16) & 0xff), (((a) >> 8) & 0xff), ((a) & 0xff)
+
+static int read_memory(struct libusb_device_handle *h, struct usb_id *p_id,
+ unsigned addr, unsigned char *dest, unsigned cnt)
+{
+ static unsigned char read_reg_command[] = {
+ 1,
+ 1,
+ V(0), /* address */
+ 0x20, /* format */
+ V(0x00000004), /* data count */
+ V(0), /* data */
+ 0x00, /* type */
+ };
+
+ int retry = 0;
+ int last_trans;
+ int err;
+ int rem;
+ unsigned char tmp[64];
+ read_reg_command[2] = (unsigned char)(addr >> 24);
+ read_reg_command[3] = (unsigned char)(addr >> 16);
+ read_reg_command[4] = (unsigned char)(addr >> 8);
+ read_reg_command[5] = (unsigned char)(addr);
+
+ read_reg_command[7] = (unsigned char)(cnt >> 24);
+ read_reg_command[8] = (unsigned char)(cnt >> 16);
+ read_reg_command[9] = (unsigned char)(cnt >> 8);
+ read_reg_command[10] = (unsigned char)(cnt);
+
+ for (;;) {
+ err = transfer(h, 1, read_reg_command, 16, &last_trans, p_id);
+ if (!err)
+ break;
+ printf("read_reg_command err=%i, last_trans=%i\n", err, last_trans);
+ if (retry > 5) {
+ return -4;
+ }
+ retry++;
+ }
+
+ err = transfer(h, 3, tmp, 4, &last_trans, p_id);
+ if (err) {
+ printf("r3 in err=%i, last_trans=%i %02x %02x %02x %02x\n",
+ err, last_trans, tmp[0], tmp[1], tmp[2], tmp[3]);
+ return err;
+ }
+
+ rem = cnt;
+
+ while (rem) {
+ tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0;
+ err = transfer(h, 4, tmp, 64, &last_trans, p_id);
+ if (err) {
+ printf("r4 in err=%i, last_trans=%i %02x %02x %02x %02x cnt=%d rem=%d\n",
+ err, last_trans, tmp[0], tmp[1], tmp[2], tmp[3], cnt, rem);
+ break;
+ }
+ if ((last_trans > rem) || (last_trans > 64)) {
+ if ((last_trans == 64) && (cnt == rem)) {
+ /* Last transfer is expected to be too large for HID */
+ } else {
+ printf("err: %02x %02x %02x %02x cnt=%d rem=%d last_trans=%i\n",
+ tmp[0], tmp[1], tmp[2], tmp[3], cnt, rem, last_trans);
+ }
+ last_trans = rem;
+ if (last_trans > 64)
+ last_trans = 64;
+ }
+ memcpy(dest, tmp, last_trans);
+ dest += last_trans;
+ rem -= last_trans;
+ }
+ return err;
+}
+
+static int write_memory(struct libusb_device_handle *h, struct usb_id *p_id,
+ unsigned addr, unsigned val, int width)
+{
+ int retry = 0;
+ int last_trans;
+ int err = 0;
+ unsigned char tmp[64];
+ unsigned char ds;
+ unsigned char write_reg_command[] = {
+ 2,
+ 2,
+ V(0), /* address */
+ 0x0, /* format */
+ V(0x00000004), /* data count */
+ V(0), /* data */
+ 0x00, /* type */
+ };
+ write_reg_command[2] = (unsigned char)(addr >> 24);
+ write_reg_command[3] = (unsigned char)(addr >> 16);
+ write_reg_command[4] = (unsigned char)(addr >> 8);
+ write_reg_command[5] = (unsigned char)(addr);
+
+ switch (width) {
+ case 1:
+ ds = 0x8;
+ break;
+ case 2:
+ ds = 0x10;
+ break;
+ case 4:
+ ds = 0x20;
+ break;
+ default:
+ return -1;
+ }
+
+ write_reg_command[6] = ds;
+
+ write_reg_command[11] = (unsigned char)(val >> 24);
+ write_reg_command[12] = (unsigned char)(val >> 16);
+ write_reg_command[13] = (unsigned char)(val >> 8);
+ write_reg_command[14] = (unsigned char)(val);
+
+ for (;;) {
+ err = transfer(h, 1, write_reg_command, 16, &last_trans, p_id);
+ if (!err)
+ break;
+ printf("write_reg_command err=%i, last_trans=%i\n", err, last_trans);
+ if (retry > 5) {
+ return -4;
+ }
+ retry++;
+ }
+
+ memset(tmp, 0, sizeof(tmp));
+
+ err = transfer(h, 3, tmp, sizeof(tmp), &last_trans, p_id);
+ if (err) {
+ printf("w3 in err=%i, last_trans=%i %02x %02x %02x %02x\n",
+ err, last_trans, tmp[0], tmp[1], tmp[2], tmp[3]);
+ printf("addr=0x%08x, val=0x%08x\n", addr, val);
+ }
+
+ memset(tmp, 0, sizeof(tmp));
+
+ err = transfer(h, 4, tmp, sizeof(tmp), &last_trans, p_id);
+ if (err)
+ printf("w4 in err=%i, last_trans=%i %02x %02x %02x %02x\n",
+ err, last_trans, tmp[0], tmp[1], tmp[2], tmp[3]);
+ return err;
+}
+
+static int write_dcd_table_ivt(struct libusb_device_handle *h, struct usb_id *p_id,
+ struct imx_flash_header_v2 *hdr, unsigned char *file_start, unsigned cnt)
+{
+ unsigned char *dcd_end;
+ unsigned m_length;
+#define cvt_dest_to_src (((unsigned char *)hdr) - hdr->self_ptr)
+ unsigned char* dcd;
+ unsigned char* file_end = file_start + cnt;
+ int err = 0;
+
+ if (!hdr->dcd_ptr) {
+ printf("No dcd table, barker=%x\n", hdr->barker);
+ return 0; /* nothing to do */
+ }
+
+ dcd = hdr->dcd_ptr + cvt_dest_to_src;
+
+ if ((dcd < file_start) || ((dcd + 4) > file_end)) {
+ printf("bad dcd_ptr %08x\n", hdr->dcd_ptr);
+ return -1;
+ }
+
+ m_length = (dcd[1] << 8) + dcd[2];
+
+ printf("main dcd length %x\n", m_length);
+
+ if ((dcd[0] != 0xd2) || (dcd[3] != 0x40)) {
+ printf("Unknown tag\n");
+ return -1;
+ }
+
+ dcd_end = dcd + m_length;
+
+ if (dcd_end > file_end) {
+ printf("bad dcd length %08x\n", m_length);
+ return -1;
+ }
+ dcd += 4;
+
+ while (dcd < dcd_end) {
+ unsigned s_length = (dcd[1] << 8) + dcd[2];
+ unsigned char *s_end = dcd + s_length;
+
+ printf("sub dcd length %x\n", s_length);
+
+ if ((dcd[0] != 0xcc) || (dcd[3] != 0x04)) {
+ printf("Unknown sub tag\n");
+ return -1;
+ }
+ dcd += 4;
+
+ if (s_end > dcd_end) {
+ printf("error s_end(%p) > dcd_end(%p)\n", s_end, dcd_end);
+ return -1;
+ }
+
+ while (dcd < s_end) {
+ unsigned addr = (dcd[0] << 24) | (dcd[1] << 16) | (dcd[2] << 8) | dcd[3];
+ unsigned val = (dcd[4] << 24) | (dcd[5] << 16) | (dcd[6] << 8) | dcd[7];
+
+ dcd += 8;
+ err = write_memory(h, p_id, addr, val, 4);
+ if (err < 0)
+ return err;
+ }
+ }
+ return err;
+}
+
+static int get_dcd_range_old(struct imx_flash_header_v1 *hdr,
+ unsigned char *file_start, unsigned cnt,
+ unsigned char **pstart, unsigned char **pend)
+{
+ unsigned char *dcd_end;
+ unsigned m_length;
+#define cvt_dest_to_src_old (((unsigned char *)&hdr->dcd_ptr) - hdr->dcd_ptr_ptr)
+ unsigned char* dcd;
+ unsigned val;
+ unsigned char* file_end = file_start + cnt;
+
+ if (!hdr->dcd_ptr) {
+ printf("No dcd table, barker=%x\n", hdr->app_barker);
+ *pstart = *pend = ((unsigned char *)hdr) + sizeof(struct imx_flash_header_v1);
+ return 0; /* nothing to do */
+ }
+
+ dcd = hdr->dcd_ptr + cvt_dest_to_src_old;
+
+ if ((dcd < file_start) || ((dcd + 8) > file_end)) {
+ printf("bad dcd_ptr %08x\n", hdr->dcd_ptr);
+ return -1;
+ }
+
+ val = (dcd[0] << 0) | (dcd[1] << 8) | (dcd[2] << 16) | (dcd[3] << 24);
+
+ if (val != DCD_BARKER) {
+ printf("Unknown tag\n");
+ return -1;
+ }
+
+ dcd += 4;
+ m_length = (dcd[0] << 0) | (dcd[1] << 8) | (dcd[2] << 16) | (dcd[3] << 24);
+ dcd += 4;
+ dcd_end = dcd + m_length;
+
+ if (dcd_end > file_end) {
+ printf("bad dcd length %08x\n", m_length);
+ return -1;
+ }
+
+ *pstart = dcd;
+ *pend = dcd_end;
+
+ return 0;
+}
+
+static int write_dcd_table_old(struct libusb_device_handle *h, struct usb_id *p_id,
+ struct imx_flash_header_v1 *hdr, unsigned char *file_start, unsigned cnt)
+{
+ unsigned val;
+ unsigned char *dcd_end;
+ unsigned char* dcd;
+ int err = get_dcd_range_old(hdr, file_start, cnt, &dcd, &dcd_end);
+ if (err < 0)
+ return err;
+
+ printf("writing DCD table...\n");
+
+ while (dcd < dcd_end) {
+ unsigned type = (dcd[0] << 0) | (dcd[1] << 8) | (dcd[2] << 16) | (dcd[3] << 24);
+ unsigned addr = (dcd[4] << 0) | (dcd[5] << 8) | (dcd[6] << 16) | (dcd[7] << 24);
+ val = (dcd[8] << 0) | (dcd[9] << 8) | (dcd[10] << 16) | (dcd[11] << 24);
+ dcd += 12;
+
+ switch (type) {
+ case 1:
+ if (verbose > 1)
+ printf("type=%08x *0x%08x = 0x%08x\n", type, addr, val);
+ err = write_memory(h, p_id, addr, val, 1);
+ if (err < 0)
+ return err;
+ break;
+ case 4:
+ if (verbose > 1)
+ printf("type=%08x *0x%08x = 0x%08x\n", type, addr, val);
+ err = write_memory(h, p_id, addr, val, 4);
+ if (err < 0)
+ return err;
+ break;
+ default:
+ printf("!!!unknown type=%08x *0x%08x = 0x%08x\n", type, addr, val);
+ }
+ }
+
+ if (err)
+ fprintf(stderr, "writing DCD table failed with %d\n", err);
+ else
+ printf("DCD table successfully written\n");
+
+ return err;
+}
+
+static int verify_memory(struct libusb_device_handle *h, struct usb_id *p_id,
+ FILE *xfile, unsigned offset, unsigned addr, unsigned size,
+ unsigned char *verify_buffer, unsigned verify_cnt)
+{
+ int mismatch = 0;
+ unsigned char file_buf[1024];
+ fseek(xfile, offset + verify_cnt, SEEK_SET);
+
+ while (size) {
+ unsigned char mem_buf[64];
+ unsigned char *p = file_buf;
+ int cnt = addr & 0x3f;
+ int request = get_min(size, sizeof(file_buf));
+
+ if (cnt) {
+ cnt = 64 - cnt;
+ if (request > cnt)
+ request = cnt;
+ }
+
+ if (verify_cnt) {
+ p = verify_buffer;
+ cnt = get_min(request, verify_cnt);
+ verify_buffer += cnt;
+ verify_cnt -= cnt;
+ } else {
+ cnt = fread(p, 1, request, xfile);
+ if (cnt <= 0) {
+ printf("Unexpected end of file, request=0x%0x, size=0x%x, cnt=%i\n",
+ request, size, cnt);
+ return -1;
+ }
+ }
+
+ size -= cnt;
+
+ while (cnt) {
+ int ret;
+
+ request = get_min(cnt, sizeof(mem_buf));
+
+ ret = read_memory(h, p_id, addr, mem_buf, request);
+ if (ret < 0)
+ return ret;
+
+ if (memcmp(p, mem_buf, request)) {
+ unsigned char * m = mem_buf;
+ if (!mismatch)
+ printf("!!!!mismatch\n");
+ mismatch++;
+
+ while (request) {
+ unsigned req = get_min(request, 32);
+ if (memcmp(p, m, req)) {
+ dump_long(p, req, offset);
+ dump_long(m, req, addr);
+ printf("\n");
+ }
+ p += req;
+ m+= req;
+ offset += req;
+ addr += req;
+ cnt -= req;
+ request -= req;
+ }
+ if (mismatch >= 5)
+ return -1;
+ }
+ p += request;
+ offset += request;
+ addr += request;
+ cnt -= request;
+ }
+ }
+
+ return mismatch ? -1 : 0;
+}
+
+static int is_header(struct usb_id *p_id, unsigned char *p)
+{
+ struct imx_flash_header_v1 *ohdr = (struct imx_flash_header_v1 *)p;
+ struct imx_flash_header_v2 *hdr = (struct imx_flash_header_v2 *)p;
+
+ switch (p_id->mach_id->header_type) {
+ case HDR_MX51:
+ if (ohdr->app_barker == 0xb1)
+ return 1;
+ break;
+ case HDR_MX53:
+ if (hdr->barker == IVT_BARKER)
+ return 1;
+ }
+
+ return 0;
+}
+
+static int perform_dcd(struct libusb_device_handle *h, struct usb_id *p_id, unsigned char *p,
+ unsigned char *file_start, unsigned cnt)
+{
+ struct imx_flash_header_v1 *ohdr = (struct imx_flash_header_v1 *)p;
+ struct imx_flash_header_v2 *hdr = (struct imx_flash_header_v2 *)p;
+ int ret = 0;
+
+ switch (p_id->mach_id->header_type) {
+ case HDR_MX51:
+ ret = write_dcd_table_old(h, p_id, ohdr, file_start, cnt);
+ ohdr->dcd_ptr = 0;
+
+ break;
+ case HDR_MX53:
+ ret = write_dcd_table_ivt(h, p_id, hdr, file_start, cnt);
+ hdr->dcd_ptr = 0;
+
+ break;
+ }
+
+ return ret;
+}
+
+static int clear_dcd_ptr(struct libusb_device_handle *h, struct usb_id *p_id,
+ unsigned char *p, unsigned char *file_start, unsigned cnt)
+{
+ struct imx_flash_header_v1 *ohdr = (struct imx_flash_header_v1 *)p;
+ struct imx_flash_header_v2 *hdr = (struct imx_flash_header_v2 *)p;
+
+ switch (p_id->mach_id->header_type) {
+ case HDR_MX51:
+ printf("clear dcd_ptr=0x%08x\n", ohdr->dcd_ptr);
+ ohdr->dcd_ptr = 0;
+ break;
+ case HDR_MX53:
+ printf("clear dcd_ptr=0x%08x\n", hdr->dcd_ptr);
+ hdr->dcd_ptr = 0;
+ break;
+ }
+ return 0;
+}
+
+static int get_dl_start(struct usb_id *p_id, unsigned char *p, unsigned char *file_start,
+ unsigned cnt, unsigned *dladdr, unsigned *max_length, unsigned *plugin,
+ unsigned *header_addr)
+{
+ unsigned char* file_end = file_start + cnt;
+ switch (p_id->mach_id->header_type) {
+ case HDR_MX51:
+ {
+ struct imx_flash_header_v1 *ohdr = (struct imx_flash_header_v1 *)p;
+ unsigned char *dcd_end;
+ unsigned char* dcd;
+ int err = get_dcd_range_old(ohdr, file_start, cnt, &dcd, &dcd_end);
+
+ *dladdr = ohdr->app_dest_ptr;
+ *header_addr = ohdr->dcd_ptr_ptr - offsetof(struct imx_flash_header_v1, dcd_ptr);
+ *plugin = 0;
+ if (err >= 0)
+ *max_length = dcd_end[0] | (dcd_end[1] << 8) | (dcd_end[2] << 16) | (dcd_end[3] << 24);
+
+ break;
+ }
+ case HDR_MX53:
+ {
+ unsigned char *bd;
+ struct imx_flash_header_v2 *hdr = (struct imx_flash_header_v2 *)p;
+
+ *dladdr = hdr->self_ptr;
+ *header_addr = hdr->self_ptr;
+ bd = hdr->boot_data_ptr + cvt_dest_to_src;
+ if ((bd < file_start) || ((bd + 4) > file_end)) {
+ printf("bad boot_data_ptr %08x\n", hdr->boot_data_ptr);
+ return -1;
+ }
+
+ *dladdr = ((struct boot_data *)bd)->dest;
+ *max_length = ((struct boot_data *)bd)->image_len;
+ *plugin = ((struct boot_data *)bd)->plugin;
+ ((struct boot_data *)bd)->plugin = 0;
+
+ hdr->boot_data_ptr = 0;
+
+ break;
+ }
+ }
+ return 0;
+}
+
+static int process_header(struct libusb_device_handle *h, struct usb_id *p_id,
+ struct usb_work *curr, unsigned char *buf, int cnt,
+ unsigned *p_dladdr, unsigned *p_max_length, unsigned *p_plugin,
+ unsigned *p_header_addr)
+{
+ int ret;
+ unsigned header_max = 0x800;
+ unsigned header_inc = 0x400;
+ unsigned header_offset = 0;
+ int header_cnt = 0;
+ unsigned char *p = buf;
+
+ for (header_offset = 0; header_offset < header_max; header_offset += header_inc, p += header_inc) {
+
+ if (!is_header(p_id, p))
+ continue;
+
+ ret = get_dl_start(p_id, p, buf, cnt, p_dladdr, p_max_length, p_plugin, p_header_addr);
+ if (ret < 0) {
+ printf("!!get_dl_start returned %i\n", ret);
+ return ret;
+ }
+
+ if (curr->dcd) {
+ ret = perform_dcd(h, p_id, p, buf, cnt);
+ if (ret < 0) {
+ printf("!!perform_dcd returned %i\n", ret);
+ return ret;
+ }
+ curr->dcd = 0;
+ if ((!curr->jump_mode) && (!curr->plug)) {
+ printf("!!dcd done, nothing else requested\n");
+ return 0;
+ }
+ }
+
+ if (curr->clear_dcd) {
+ ret = clear_dcd_ptr(h, p_id, p, buf, cnt);
+ if (ret < 0) {
+ printf("!!clear_dcd returned %i\n", ret);
+ return ret;
+ }
+ }
+
+ if (*p_plugin && (!curr->plug) && (!header_cnt)) {
+ header_cnt++;
+ header_max = header_offset + *p_max_length + 0x400;
+ if (header_max > cnt - 32)
+ header_max = cnt - 32;
+ printf("header_max=%x\n", header_max);
+ header_inc = 4;
+ } else {
+ if (!*p_plugin)
+ curr->plug = 0;
+ return header_offset;
+ }
+ }
+
+ fprintf(stderr, "no DCD header found in image, run imx-image first\n");
+
+ return -ENODEV;
+}
+
+static int load_file(struct libusb_device_handle *h, struct usb_id *p_id,
+ unsigned char *p, int cnt, unsigned char *buf, unsigned buf_cnt,
+ unsigned dladdr, unsigned fsize, unsigned char type, FILE* xfile)
+{
+ static unsigned char dl_command[] = {
+ 0x04,
+ 0x04,
+ V(0), /* address */
+ 0x00, /* format */
+ V(0x00000020), /* data count */
+ V(0), /* data */
+ 0xaa, /* type */
+ };
+ int last_trans, err;
+ int retry = 0;
+ unsigned transfer_size = 0;
+ int max = p_id->mach_id->max_transfer;
+ unsigned char tmp[64];
+
+ dl_command[2] = (unsigned char)(dladdr >> 24);
+ dl_command[3] = (unsigned char)(dladdr >> 16);
+ dl_command[4] = (unsigned char)(dladdr >> 8);
+ dl_command[5] = (unsigned char)(dladdr);
+
+ dl_command[7] = (unsigned char)(fsize >> 24);
+ dl_command[8] = (unsigned char)(fsize >> 16);
+ dl_command[9] = (unsigned char)(fsize >> 8);
+ dl_command[10] = (unsigned char)(fsize);
+ dl_command[15] = type;
+
+ for (;;) {
+ err = transfer(h, 1, dl_command, 16, &last_trans, p_id);
+ if (!err)
+ break;
+
+ printf("dl_command err=%i, last_trans=%i\n", err, last_trans);
+
+ if (retry > 5)
+ return -4;
+ retry++;
+ }
+
+ retry = 0;
+
+ if (p_id->mach_id->mode == MODE_BULK) {
+ err = transfer(h, 3, tmp, sizeof(tmp), &last_trans, p_id);
+ if (err)
+ printf("in err=%i, last_trans=%i %02x %02x %02x %02x\n",
+ err, last_trans, tmp[0], tmp[1], tmp[2], tmp[3]);
+ }
+
+ while (1) {
+ int retry;
+
+ if (cnt > (int)(fsize - transfer_size))
+ cnt = (fsize - transfer_size);
+
+ if (cnt <= 0)
+ break;
+
+ retry = 0;
+
+ while (cnt) {
+ err = transfer(h, 2, p, get_min(cnt, max), &last_trans, p_id);
+ if (err) {
+ printf("out err=%i, last_trans=%i cnt=0x%x max=0x%x transfer_size=0x%X retry=%i\n",
+ err, last_trans, cnt, max, transfer_size, retry);
+ if (retry >= 10) {
+ printf("Giving up\n");
+ return err;
+ }
+ if (max >= 16)
+ max >>= 1;
+ else
+ max <<= 1;
+ usleep(10000);
+ retry++;
+ continue;
+ }
+ max = p_id->mach_id->max_transfer;
+ retry = 0;
+ if (cnt < last_trans) {
+ printf("error: last_trans=0x%x, attempted only=0%x\n", last_trans, cnt);
+ cnt = last_trans;
+ }
+ if (!last_trans) {
+ printf("Nothing last_trans, err=%i\n", err);
+ break;
+ }
+ p += last_trans;
+ cnt -= last_trans;
+ transfer_size += last_trans;
+ }
+
+ if (!last_trans)
+ break;
+
+ if (feof(xfile))
+ break;
+
+ cnt = fsize - transfer_size;
+ if (cnt <= 0)
+ break;
+
+ cnt = fread(buf, 1 , get_min(cnt, buf_cnt), xfile);
+ p = buf;
+ }
+
+ if (p_id->mach_id->mode == MODE_HID) {
+ err = transfer(h, 3, tmp, sizeof(tmp), &last_trans, p_id);
+ if (err)
+ printf("3 in err=%i, last_trans=%i %02x %02x %02x %02x\n",
+ err, last_trans, tmp[0], tmp[1], tmp[2], tmp[3]);
+ err = transfer(h, 4, tmp, sizeof(tmp), &last_trans, p_id);
+ if (err)
+ printf("4 in err=%i, last_trans=%i %02x %02x %02x %02x\n",
+ err, last_trans, tmp[0], tmp[1], tmp[2], tmp[3]);
+ } else {
+ do_status(h, p_id);
+ }
+
+ return transfer_size;
+}
+
+#define FT_APP 0xaa
+#define FT_CSF 0xcc
+#define FT_DCD 0xee
+#define FT_LOAD_ONLY 0x00
+
+static int do_irom_download(struct libusb_device_handle *h, struct usb_id *p_id,
+ struct usb_work *curr, int verify)
+{
+ static unsigned char jump_command[] = {0x0b,0x0b, V(0), 0x00, V(0x00000000), V(0), 0x00};
+
+ int ret;
+ FILE* xfile;
+ unsigned char type;
+ unsigned fsize;
+ unsigned header_offset;
+ int cnt;
+ unsigned file_base;
+ int last_trans, err;
+#define BUF_SIZE (1024*16)
+ unsigned char *buf = NULL;
+ unsigned char *verify_buffer = NULL;
+ unsigned verify_cnt;
+ unsigned char *p;
+ unsigned char tmp[64];
+ unsigned dladdr = 0;
+ unsigned max_length;
+ unsigned plugin = 0;
+ unsigned header_addr = 0;
+
+ unsigned skip = 0;
+ unsigned transfer_size=0;
+ int retry = 0;
+
+ xfile = fopen(curr->filename, "rb" );
+ if (!xfile) {
+ printf("error, can not open input file: %s\n", curr->filename);
+ return -5;
+ }
+
+ buf = malloc(BUF_SIZE);
+ if (!buf) {
+ printf("error, out of memory\n");
+ ret = -2;
+ goto cleanup;
+ }
+
+ fsize = get_file_size(xfile);
+
+ cnt = fread(buf, 1 , BUF_SIZE, xfile);
+
+ if (cnt < 0x20) {
+ printf("error, file: %s is too small\n", curr->filename);
+ ret = -2;
+ goto cleanup;
+ }
+
+ max_length = fsize;
+
+ ret = process_header(h, p_id, curr, buf, cnt,
+ &dladdr, &max_length, &plugin, &header_addr);
+ if (ret < 0)
+ goto cleanup;
+
+ header_offset = ret;
+
+ if ((!curr->jump_mode) && (!curr->plug)) {
+ /* nothing else requested */
+ ret = 0;
+ goto cleanup;
+ }
+
+ if (plugin && (!curr->plug)) {
+ printf("Only plugin header found\n");
+ ret = -1;
+ goto cleanup;
+ }
+
+ if (!dladdr) {
+ printf("unknown load address\n");
+ ret = -3;
+ goto cleanup;
+ }
+
+ file_base = header_addr - header_offset;
+
+ type = (curr->plug || curr->jump_mode) ? FT_APP : FT_LOAD_ONLY;
+
+ if (p_id->mach_id->mode == MODE_BULK && type == FT_APP) {
+ /* No jump command, dladdr should point to header */
+ dladdr = header_addr;
+ }
+
+ if (file_base > dladdr) {
+ max_length -= (file_base - dladdr);
+ dladdr = file_base;
+ }
+
+ skip = dladdr - file_base;
+
+ if (skip > cnt) {
+ if (skip > fsize) {
+ printf("skip(0x%08x) > fsize(0x%08x) file_base=0x%08x, header_offset=0x%x\n",
+ skip, fsize, file_base, header_offset);
+ ret = -4;
+ goto cleanup;
+ }
+
+ fseek(xfile, skip, SEEK_SET);
+ cnt -= skip;
+ fsize -= skip;
+ skip = 0;
+ cnt = fread(buf, 1 , BUF_SIZE, xfile);
+ }
+
+ p = &buf[skip];
+ cnt -= skip;
+ fsize -= skip;
+
+ if (fsize > max_length)
+ fsize = max_length;
+
+ if (verify) {
+ /*
+ * we need to save header for verification
+ * because some of the file is changed
+ * before download
+ */
+ verify_buffer = malloc(cnt);
+ verify_cnt = cnt;
+
+ if (!verify_buffer) {
+ printf("error, out of memory\n");
+ ret = -2;
+ goto cleanup;
+ }
+
+ memcpy(verify_buffer, p, cnt);
+
+ if ((type == FT_APP) && (p_id->mach_id->mode != MODE_HID)) {
+ type = FT_LOAD_ONLY;
+ verify = 2;
+ }
+ }
+
+ printf("loading binary file(%s) to %08x, skip=0x%x, fsize=%d type=%d...\n",
+ curr->filename, dladdr, skip, fsize, type);
+
+ ret = load_file(h, p_id, p, cnt, buf, BUF_SIZE,
+ dladdr, fsize, type, xfile);
+ if (ret < 0)
+ goto cleanup;
+
+ printf("binary file successfully loaded\n");
+
+ transfer_size = ret;
+
+ if (verify) {
+ printf("verifying file...\n");
+
+ ret = verify_memory(h, p_id, xfile, skip, dladdr, fsize, verify_buffer, verify_cnt);
+ if (ret < 0) {
+ printf("verifying failed\n");
+ goto cleanup;
+ }
+
+ printf("file successfully verified\n");
+
+ if (verify == 2) {
+ if (verify_cnt > 64)
+ verify_cnt = 64;
+ ret = load_file(h, p_id, verify_buffer, verify_cnt,
+ buf, BUF_SIZE, dladdr, verify_cnt,
+ FT_APP, xfile);
+ if (ret < 0)
+ goto cleanup;
+
+ }
+ }
+
+ if (p_id->mach_id->mode == MODE_HID && type == FT_APP) {
+ printf("jumping to 0x%08x\n", header_addr);
+
+ jump_command[2] = (unsigned char)(header_addr >> 24);
+ jump_command[3] = (unsigned char)(header_addr >> 16);
+ jump_command[4] = (unsigned char)(header_addr >> 8);
+ jump_command[5] = (unsigned char)(header_addr);
+
+ /* Any command will initiate jump for mx51, jump address is ignored by mx51 */
+ retry = 0;
+
+ for (;;) {
+ err = transfer(h, 1, jump_command, 16, &last_trans, p_id);
+ if (!err)
+ break;
+
+ printf("jump_command err=%i, last_trans=%i\n", err, last_trans);
+
+ if (retry > 5)
+ return -4;
+
+ retry++;
+ }
+
+ memset(tmp, 0, sizeof(tmp));
+ err = transfer(h, 3, tmp, sizeof(tmp), &last_trans, p_id);
+
+ if (err)
+ printf("j3 in err=%i, last_trans=%i %02x %02x %02x %02x\n",
+ err, last_trans, tmp[0], tmp[1], tmp[2], tmp[3]);
+ }
+
+ ret = (fsize == transfer_size) ? 0 : -16;
+cleanup:
+ fclose(xfile);
+ free(verify_buffer);
+ free(buf);
+
+ return ret;
+}
+
+static void usage(const char *prgname)
+{
+ fprintf(stderr, "usage: %s [OPTIONS] [FILENAME]\n\n"
+ "-c check correctness of flashed image\n"
+ "-v verbose (give multiple times to increase)\n"
+ "-h this help\n", prgname);
+ exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+ struct usb_id *p_id;
+ struct mach_id *mach;
+ libusb_device **devs;
+ libusb_device *dev;
+ int r;
+ int err;
+ int ret = 1;
+ ssize_t cnt;
+ libusb_device_handle *h = NULL;
+ int config = 0;
+ int verify = 0;
+ struct usb_work w = {};
+ int opt;
+
+ while ((opt = getopt(argc, argv, "cvh")) != -1) {
+ switch (opt) {
+ case 'c':
+ verify = 1;
+ break;
+ case 'v':
+ verbose++;
+ break;
+ case 'h':
+ usage(argv[0]);
+ default:
+ exit(1);
+ }
+ }
+
+ if (optind == argc) {
+ fprintf(stderr, "no filename given\n");
+ usage(argv[0]);
+ exit(1);
+ }
+
+ w.plug = 1;
+ w.dcd = 1;
+ w.jump_mode = J_HEADER;
+ strncpy(w.filename, argv[optind], sizeof(w.filename) - 1);
+
+ r = libusb_init(NULL);
+ if (r < 0)
+ goto out;
+
+ cnt = libusb_get_device_list(NULL, &devs);
+ if (cnt < 0) {
+ fprintf(stderr, "no supported device found\n");
+ goto out;
+ }
+
+ dev = find_imx_dev(devs, &mach);
+ if (!dev) {
+ fprintf(stderr, "no supported device found\n");
+ goto out;
+ }
+
+ err = libusb_open(dev, &h);
+ if (err) {
+ fprintf(stderr, "Could not open device vid=0x%x pid=0x%x err=%d\n",
+ mach->vid, mach->pid, err);
+ goto out;
+ }
+
+ libusb_free_device_list(devs, 1);
+
+ libusb_get_configuration(h, &config);
+
+ if (libusb_kernel_driver_active(h, 0))
+ libusb_detach_kernel_driver(h, 0);
+
+ err = libusb_claim_interface(h, 0);
+ if (err) {
+ printf("Claim failed\n");
+ goto out;
+ }
+
+ p_id = malloc(sizeof(*p_id));
+ if (!p_id) {
+ perror("malloc");
+ exit(1);
+ }
+
+ p_id->mach_id = mach;
+
+ err = do_status(h, p_id);
+ if (err) {
+ printf("status failed\n");
+ goto out;
+ }
+
+ err = do_irom_download(h, p_id, &w, verify);
+ if (err) {
+ err = do_status(h, p_id);
+ goto out;
+ }
+
+ ret = 0;
+out:
+ if (h)
+ libusb_close(h);
+
+ libusb_exit(NULL);
+
+ return ret;
+}
diff --git a/scripts/kwbimage.c b/scripts/kwbimage.c
new file mode 100644
index 0000000000..4ebb07fe22
--- /dev/null
+++ b/scripts/kwbimage.c
@@ -0,0 +1,1496 @@
+/*
+ * Image manipulator for Marvell SoCs
+ * supports Kirkwood, Dove, Armada 370, and Armada XP
+ *
+ * (C) Copyright 2013 Thomas Petazzoni
+ * <thomas.petazzoni@free-electrons.com>
+ *
+ * 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.
+ *
+ * This tool allows to extract and create bootable images for Marvell
+ * Kirkwood, Dove, Armada 370, and Armada XP SoCs. It supports two
+ * versions of the bootable image format: version 0 (used on Marvell
+ * Kirkwood and Dove) and version 1 (used on Marvell Armada 370/XP).
+ *
+ * To extract an image, run:
+ * ./scripts/kwbimage -x -i <image-file> -o <some-directory>
+ *
+ * In <some-directory>, kwbimage will output 'kwbimage.cfg', the
+ * configuration file that describes the image, 'payload', which is
+ * the bootloader code itself, and it may output a 'binary.0' file
+ * that corresponds to a binary blob (only possible in version 1
+ * images).
+ *
+ * To create an image, run:
+ * ./scripts/kwbimage -c -i <image-cfg-file> -o <image-file>
+ *
+ * The given configuration file is in the format of the 'kwbimage.cfg'
+ * file, and should reference the payload file (generally the
+ * bootloader code) and optionally a binary blob.
+ *
+ * Not implemented: support for the register headers and secure
+ * headers in v1 images
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define ALIGN_SUP(x, a) (((x) + (a - 1)) & ~(a - 1))
+
+/* Structure of the main header, version 0 (Kirkwood, Dove) */
+struct main_hdr_v0 {
+ uint8_t blockid; /*0 */
+ uint8_t nandeccmode; /*1 */
+ uint16_t nandpagesize; /*2-3 */
+ uint32_t blocksize; /*4-7 */
+ uint32_t rsvd1; /*8-11 */
+ uint32_t srcaddr; /*12-15 */
+ uint32_t destaddr; /*16-19 */
+ uint32_t execaddr; /*20-23 */
+ uint8_t satapiomode; /*24 */
+ uint8_t rsvd3; /*25 */
+ uint16_t ddrinitdelay; /*26-27 */
+ uint16_t rsvd2; /*28-29 */
+ uint8_t ext; /*30 */
+ uint8_t checksum; /*31 */
+};
+
+struct ext_hdr_v0_reg {
+ uint32_t raddr;
+ uint32_t rdata;
+};
+
+#define EXT_HDR_V0_REG_COUNT ((0x1dc - 0x20)/sizeof(struct ext_hdr_v0_reg))
+
+struct ext_hdr_v0 {
+ uint32_t offset;
+ uint8_t reserved[0x20 - sizeof(uint32_t)];
+ struct ext_hdr_v0_reg rcfg[EXT_HDR_V0_REG_COUNT];
+ uint8_t reserved2[7];
+ uint8_t checksum;
+};
+
+/* Structure of the main header, version 1 (Armada 370, Armada XP) */
+struct main_hdr_v1 {
+ uint8_t blockid; /* 0 */
+ uint8_t reserved1; /* 1 */
+ uint16_t reserved2; /* 2-3 */
+ uint32_t blocksize; /* 4-7 */
+ uint8_t version; /* 8 */
+ uint8_t headersz_msb; /* 9 */
+ uint16_t headersz_lsb; /* A-B */
+ uint32_t srcaddr; /* C-F */
+ uint32_t destaddr; /* 10-13 */
+ uint32_t execaddr; /* 14-17 */
+ uint8_t reserved3; /* 18 */
+ uint8_t nandblocksize; /* 19 */
+ uint8_t nandbadblklocation; /* 1A */
+ uint8_t reserved4; /* 1B */
+ uint16_t reserved5; /* 1C-1D */
+ uint8_t ext; /* 1E */
+ uint8_t checksum; /* 1F */
+};
+
+/*
+ * Header for the optional headers, version 1 (Armada 370, Armada XP)
+ */
+struct opt_hdr_v1 {
+ uint8_t headertype;
+ uint8_t headersz_msb;
+ uint16_t headersz_lsb;
+ char data[0];
+};
+
+/*
+ * Various values for the opt_hdr_v1->headertype field, describing the
+ * different types of optional headers. The "secure" header contains
+ * informations related to secure boot (encryption keys, etc.). The
+ * "binary" header contains ARM binary code to be executed prior to
+ * executing the main payload (usually the bootloader). This is
+ * typically used to execute DDR3 training code. The "register" header
+ * allows to describe a set of (address, value) tuples that are
+ * generally used to configure the DRAM controller.
+ */
+#define OPT_HDR_V1_SECURE_TYPE 0x1
+#define OPT_HDR_V1_BINARY_TYPE 0x2
+#define OPT_HDR_V1_REGISTER_TYPE 0x3
+
+#define KWBHEADER_V1_SIZE(hdr) \
+ (((hdr)->headersz_msb << 16) | (hdr)->headersz_lsb)
+
+struct boot_mode {
+ unsigned int id;
+ const char *name;
+};
+
+struct boot_mode boot_modes[] = {
+ { 0x4D, "i2c" },
+ { 0x5A, "spi" },
+ { 0x8B, "nand" },
+ { 0x78, "sata" },
+ { 0x9C, "pex" },
+ { 0x69, "uart" },
+ {},
+};
+
+struct nand_ecc_mode {
+ unsigned int id;
+ const char *name;
+};
+
+struct nand_ecc_mode nand_ecc_modes[] = {
+ { 0x00, "default" },
+ { 0x01, "hamming" },
+ { 0x02, "rs" },
+ { 0x03, "disabled" },
+ {},
+};
+
+/* Used to identify an undefined execution or destination address */
+#define ADDR_INVALID ((uint32_t)-1)
+
+#define BINARY_MAX_ARGS 8
+
+/* In-memory representation of a line of the configuration file */
+struct image_cfg_element {
+ enum {
+ IMAGE_CFG_VERSION = 0x1,
+ IMAGE_CFG_BOOT_FROM,
+ IMAGE_CFG_DEST_ADDR,
+ IMAGE_CFG_EXEC_ADDR,
+ IMAGE_CFG_NAND_BLKSZ,
+ IMAGE_CFG_NAND_BADBLK_LOCATION,
+ IMAGE_CFG_NAND_ECC_MODE,
+ IMAGE_CFG_NAND_PAGESZ,
+ IMAGE_CFG_BINARY,
+ IMAGE_CFG_PAYLOAD,
+ IMAGE_CFG_DATA,
+ } type;
+ union {
+ unsigned int version;
+ unsigned int bootfrom;
+ struct {
+ const char *file;
+ unsigned int args[BINARY_MAX_ARGS];
+ unsigned int nargs;
+ } binary;
+ const char *payload;
+ unsigned int dstaddr;
+ unsigned int execaddr;
+ unsigned int nandblksz;
+ unsigned int nandbadblklocation;
+ unsigned int nandeccmode;
+ unsigned int nandpagesz;
+ struct ext_hdr_v0_reg regdata;
+ };
+};
+
+#define IMAGE_CFG_ELEMENT_MAX 256
+
+/*
+ * Byte 8 of the image header contains the version number. In the v0
+ * header, byte 8 was reserved, and always set to 0. In the v1 header,
+ * byte 8 has been changed to a proper field, set to 1.
+ */
+static unsigned int image_version(void *header)
+{
+ unsigned char *ptr = header;
+ return ptr[8];
+}
+
+/*
+ * Utility functions to manipulate boot mode and ecc modes (convert
+ * them back and forth between description strings and the
+ * corresponding numerical identifiers).
+ */
+
+static const char *image_boot_mode_name(unsigned int id)
+{
+ int i;
+ for (i = 0; boot_modes[i].name; i++)
+ if (boot_modes[i].id == id)
+ return boot_modes[i].name;
+ return NULL;
+}
+
+int image_boot_mode_id(const char *boot_mode_name)
+{
+ int i;
+ for (i = 0; boot_modes[i].name; i++)
+ if (!strcmp(boot_modes[i].name, boot_mode_name))
+ return boot_modes[i].id;
+
+ return -1;
+}
+
+static const char *image_nand_ecc_mode_name(unsigned int id)
+{
+ int i;
+ for (i = 0; nand_ecc_modes[i].name; i++)
+ if (nand_ecc_modes[i].id == id)
+ return nand_ecc_modes[i].name;
+ return NULL;
+}
+
+int image_nand_ecc_mode_id(const char *nand_ecc_mode_name)
+{
+ int i;
+ for (i = 0; nand_ecc_modes[i].name; i++)
+ if (!strcmp(nand_ecc_modes[i].name, nand_ecc_mode_name))
+ return nand_ecc_modes[i].id;
+ return -1;
+}
+
+static struct image_cfg_element *
+image_find_option(struct image_cfg_element *image_cfg,
+ int cfgn, unsigned int optiontype)
+{
+ int i;
+
+ for (i = 0; i < cfgn; i++) {
+ if (image_cfg[i].type == optiontype)
+ return &image_cfg[i];
+ }
+
+ return NULL;
+}
+
+static unsigned int
+image_count_options(struct image_cfg_element *image_cfg,
+ int cfgn, unsigned int optiontype)
+{
+ int i;
+ unsigned int count = 0;
+
+ for (i = 0; i < cfgn; i++)
+ if (image_cfg[i].type == optiontype)
+ count++;
+
+ return count;
+}
+
+/*
+ * Compute a 8-bit checksum of a memory area. This algorithm follows
+ * the requirements of the Marvell SoC BootROM specifications.
+ */
+static uint8_t image_checksum8(void *start, uint32_t len)
+{
+ uint8_t csum = 0;
+ uint8_t *p = start;
+
+ /* check len and return zero checksum if invalid */
+ if (!len)
+ return 0;
+
+ do {
+ csum += *p;
+ p++;
+ } while (--len);
+
+ return csum;
+}
+
+static uint32_t image_checksum32 (void *start, uint32_t len)
+{
+ uint32_t csum = 0;
+ uint32_t *p = start;
+
+ /* check len and return zero checksum if invalid */
+ if (!len)
+ return 0;
+
+ if (len % sizeof(uint32_t)) {
+ fprintf (stderr, "Length %d is not in multiple of %zu\n",
+ len, sizeof(uint32_t));
+ return 0;
+ }
+
+ do {
+ csum += *p;
+ p++;
+ len -= sizeof(uint32_t);
+ } while (len > 0);
+
+ return csum;
+}
+
+static void usage(const char *prog)
+{
+ printf("Usage: %s [-c | -x] -i <input> -o <output>\n", prog);
+ printf(" -c: create a new image\n");
+ printf(" -x: extract an existing image\n");
+ printf(" -i: input file\n");
+ printf(" when used with -c, should point to a kwbimage.cfg file\n");
+ printf(" when used with -x, should point to the image to be extracted\n");
+ printf(" -o: output file/directory\n");
+ printf(" when used with -c, should point to the image file to create\n");
+ printf(" when used with -x, should point to a directory when the image will be extracted\n");
+ printf(" -v: verbose\n");
+ printf(" -h: this help text\n");
+ printf(" Options specific to image creation:\n");
+ printf(" -p: path to payload image. Overrides the PAYLOAD line from kwbimage.cfg\n");
+ printf(" -m: boot media. Overrides the BOOT_FROM line from kwbimage.cfg\n");
+ printf(" -d: load address. Overrides the DEST_ADDR line from kwbimage.cfg\n");
+ printf(" -e: exec address. Overrides the EXEC_ADDR line from kwbimage.cfg\n");
+}
+
+static int image_extract_payload(void *payload, size_t sz, const char *output)
+{
+ char *imageoutname;
+ FILE *imageout;
+ int ret;
+
+ ret = asprintf(&imageoutname, "%s/payload", output);
+ if (ret < 0) {
+ fprintf(stderr, "Cannot allocate memory\n");
+ return -1;
+ }
+
+ imageout = fopen(imageoutname, "w+");
+ if (!imageout) {
+ fprintf(stderr, "Could not open output file %s\n",
+ imageoutname);
+ free(imageoutname);
+ return -1;
+ }
+
+ ret = fwrite(payload, sz, 1, imageout);
+ if (ret != 1) {
+ fprintf(stderr, "Could not write to open file %s\n",
+ imageoutname);
+ fclose(imageout);
+ free(imageoutname);
+ return -1;
+ }
+
+ fclose(imageout);
+ free(imageoutname);
+ return 0;
+}
+
+static int image_extract_v0(void *fdimap, const char *output, FILE *focfg)
+{
+ struct main_hdr_v0 *main_hdr = fdimap;
+ struct ext_hdr_v0 *ext_hdr;
+ const char *boot_mode_name;
+ uint32_t *img_checksum;
+ size_t payloadsz;
+ int cksum, i;
+
+ /*
+ * Verify checksum. When calculating the header, discard the
+ * last byte of the header, which itself contains the
+ * checksum.
+ */
+ cksum = image_checksum8(main_hdr, sizeof(struct main_hdr_v0)-1);
+ if (cksum != main_hdr->checksum) {
+ fprintf(stderr,
+ "Invalid main header checksum: 0x%08x vs. 0x%08x\n",
+ cksum, main_hdr->checksum);
+ return -1;
+ }
+
+ boot_mode_name = image_boot_mode_name(main_hdr->blockid);
+ if (!boot_mode_name) {
+ fprintf(stderr, "Invalid boot ID: 0x%x\n",
+ main_hdr->blockid);
+ return -1;
+ }
+
+ fprintf(focfg, "VERSION 0\n");
+ fprintf(focfg, "BOOT_FROM %s\n", boot_mode_name);
+ fprintf(focfg, "DESTADDR %08x\n", main_hdr->destaddr);
+ fprintf(focfg, "EXECADDR %08x\n", main_hdr->execaddr);
+
+ if (!strcmp(boot_mode_name, "nand")) {
+ const char *nand_ecc_mode =
+ image_nand_ecc_mode_name(main_hdr->nandeccmode);
+ fprintf(focfg, "NAND_ECCMODE %s\n",
+ nand_ecc_mode);
+ fprintf(focfg, "NAND_PAGESZ %08x\n",
+ main_hdr->nandpagesize);
+ }
+
+ /* No extension header, we're done */
+ if (!main_hdr->ext)
+ return 0;
+
+ ext_hdr = fdimap + sizeof(struct main_hdr_v0);
+
+ for (i = 0; i < EXT_HDR_V0_REG_COUNT; i++) {
+ if (ext_hdr->rcfg[i].raddr == 0 &&
+ ext_hdr->rcfg[i].rdata == 0)
+ break;
+
+ fprintf(focfg, "DATA %08x %08x\n",
+ ext_hdr->rcfg[i].raddr,
+ ext_hdr->rcfg[i].rdata);
+ }
+
+ /* The image is concatenated with a 32 bits checksum */
+ payloadsz = main_hdr->blocksize - sizeof(uint32_t);
+ img_checksum = (uint32_t *) (fdimap + main_hdr->srcaddr + payloadsz);
+
+ if (*img_checksum != image_checksum32(fdimap + main_hdr->srcaddr,
+ payloadsz)) {
+ fprintf(stderr, "The image checksum does not match\n");
+ return -1;
+ }
+
+ /* Finally, handle the image itself */
+ fprintf(focfg, "PAYLOAD %s/payload\n", output);
+ return image_extract_payload(fdimap + main_hdr->srcaddr,
+ payloadsz, output);
+}
+
+static int image_extract_binary_hdr_v1(const void *binary, const char *output,
+ FILE *focfg, int hdrnum, size_t binsz)
+{
+ char *binaryoutname;
+ FILE *binaryout;
+ const unsigned int *args;
+ unsigned int nargs;
+ int ret, i;
+
+ args = binary;
+ nargs = args[0];
+ args++;
+
+ ret = asprintf(&binaryoutname, "%s/binary.%d", output,
+ hdrnum);
+ if (ret < 0) {
+ fprintf(stderr, "Couldn't not allocate memory\n");
+ return ret;
+ }
+
+ binaryout = fopen(binaryoutname, "w+");
+ if (!binaryout) {
+ fprintf(stderr, "Couldn't open output file %s\n",
+ binaryoutname);
+ free(binaryoutname);
+ return -1;
+ }
+
+ ret = fwrite(binary + (nargs + 1) * sizeof(unsigned int),
+ binsz - (nargs + 1) * sizeof(unsigned int), 1,
+ binaryout);
+ if (ret != 1) {
+ fprintf(stderr, "Could not write to output file %s\n",
+ binaryoutname);
+ fclose(binaryout);
+ free(binaryoutname);
+ return -1;
+ }
+
+ fclose(binaryout);
+
+ fprintf(focfg, "BINARY %s", binaryoutname);
+ for (i = 0; i < nargs; i++)
+ fprintf(focfg, " %08x", args[i]);
+ fprintf(focfg, "\n");
+
+ free(binaryoutname);
+
+ return 0;
+}
+
+static int image_extract_v1(void *fdimap, const char *output, FILE *focfg)
+{
+ struct main_hdr_v1 *main_hdr = fdimap;
+ struct opt_hdr_v1 *opt_hdr;
+ const char *boot_mode_name;
+ int headersz = KWBHEADER_V1_SIZE(main_hdr);
+ int hasheaders;
+ uint8_t cksum;
+ int opthdrid;
+
+ /*
+ * Verify the checkum. We have to substract the checksum
+ * itself, because when the checksum is calculated, the
+ * checksum field is 0.
+ */
+ cksum = image_checksum8(main_hdr, headersz);
+ cksum -= main_hdr->checksum;
+
+ if (cksum != main_hdr->checksum) {
+ fprintf(stderr,
+ "Invalid main header checksum: 0x%08x vs. 0x%08x\n",
+ cksum, main_hdr->checksum);
+ return -1;
+ }
+
+ /* First, take care of the main header */
+ boot_mode_name = image_boot_mode_name(main_hdr->blockid);
+ if (!boot_mode_name) {
+ fprintf(stderr, "Invalid boot ID: 0x%x\n",
+ main_hdr->blockid);
+ return -1;
+ }
+
+ fprintf(focfg, "VERSION 1\n");
+ fprintf(focfg, "BOOT_FROM %s\n", boot_mode_name);
+ fprintf(focfg, "DESTADDR %08x\n", main_hdr->destaddr);
+ fprintf(focfg, "EXECADDR %08x\n", main_hdr->execaddr);
+ fprintf(focfg, "NAND_BLKSZ %08x\n",
+ main_hdr->nandblocksize * 64 * 1024);
+ fprintf(focfg, "NAND_BADBLK_LOCATION %02x\n",
+ main_hdr->nandbadblklocation);
+
+ hasheaders = main_hdr->ext;
+ opt_hdr = fdimap + sizeof(struct main_hdr_v1);
+ opthdrid = 0;
+
+ /* Then, go through all the extension headers */
+ while (hasheaders) {
+ int opthdrsz = KWBHEADER_V1_SIZE(opt_hdr);
+
+ switch (opt_hdr->headertype) {
+ case OPT_HDR_V1_BINARY_TYPE:
+ image_extract_binary_hdr_v1(opt_hdr->data, output,
+ focfg, opthdrid,
+ opthdrsz -
+ sizeof(struct opt_hdr_v1));
+ break;
+ case OPT_HDR_V1_SECURE_TYPE:
+ case OPT_HDR_V1_REGISTER_TYPE:
+ fprintf(stderr,
+ "Support for header type 0x%x not implemented\n",
+ opt_hdr->headertype);
+ exit(1);
+ break;
+ default:
+ fprintf(stderr, "Invalid header type 0x%x\n",
+ opt_hdr->headertype);
+ exit(1);
+ }
+
+ /*
+ * The first byte of the last double word of the
+ * current header indicates whether there is a next
+ * header or not.
+ */
+ hasheaders = ((char *)opt_hdr)[opthdrsz - 4];
+
+ /* Move to the next header */
+ opt_hdr = ((void *)opt_hdr) + opthdrsz;
+ opthdrid++;
+ }
+
+ /* Finally, handle the image itself */
+ fprintf(focfg, "PAYLOAD %s/payload\n", output);
+ return image_extract_payload(fdimap + main_hdr->srcaddr,
+ main_hdr->blocksize - 4,
+ output);
+}
+
+static int image_extract(const char *input, const char *output)
+{
+ int fdi, ret;
+ struct stat fdistat, fdostat;
+ void *fdimap;
+ char *focfgname;
+ FILE *focfg;
+
+ fdi = open(input, O_RDONLY);
+ if (fdi < 0) {
+ fprintf(stderr, "Cannot open input file %s: %m\n",
+ input);
+ return -1;
+ }
+
+ ret = fstat(fdi, &fdistat);
+ if (ret < 0) {
+ fprintf(stderr, "Cannot stat input file %s: %m\n",
+ input);
+ close(fdi);
+ return -1;
+ }
+
+ fdimap = mmap(NULL, fdistat.st_size, PROT_READ, MAP_PRIVATE, fdi, 0);
+ if (fdimap == MAP_FAILED) {
+ fprintf(stderr, "Cannot map input file %s: %m\n",
+ input);
+ close(fdi);
+ return -1;
+ }
+
+ close(fdi);
+
+ ret = stat(output, &fdostat);
+ if (ret < 0) {
+ fprintf(stderr, "Cannot stat output directory %s: %m\n",
+ output);
+ munmap(fdimap, fdistat.st_size);
+ return -1;
+ }
+
+ if (!S_ISDIR(fdostat.st_mode)) {
+ fprintf(stderr, "Output %s should be a directory\n",
+ output);
+ munmap(fdimap, fdistat.st_size);
+ return -1;
+ }
+
+ ret = asprintf(&focfgname, "%s/kwbimage.cfg", output);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to allocate memory\n");
+ munmap(fdimap, fdistat.st_size);
+ return -1;
+ }
+
+ focfg = fopen(focfgname, "w+");
+ if (!focfg) {
+ fprintf(stderr, "Output file %s could not be created\n",
+ focfgname);
+ free(focfgname);
+ munmap(fdimap, fdistat.st_size);
+ return -1;
+ }
+
+ free(focfgname);
+
+ if (image_version(fdimap) == 0)
+ ret = image_extract_v0(fdimap, output, focfg);
+ else if (image_version(fdimap) == 1)
+ ret = image_extract_v1(fdimap, output, focfg);
+ else {
+ fprintf(stderr, "Invalid image version %d\n",
+ image_version(fdimap));
+ ret = -1;
+ }
+
+ fclose(focfg);
+ munmap(fdimap, fdistat.st_size);
+ return ret;
+}
+
+static int image_create_payload(void *payload_start, size_t payloadsz,
+ const char *payload_filename)
+{
+ FILE *payload;
+ uint32_t *payload_checksum =
+ (uint32_t *) (payload_start + payloadsz);
+ int ret;
+
+ payload = fopen(payload_filename, "r");
+ if (!payload) {
+ fprintf(stderr, "Cannot open payload file %s\n",
+ payload_filename);
+ return -1;
+ }
+
+ ret = fread(payload_start, payloadsz, 1, payload);
+ if (ret != 1) {
+ fprintf(stderr, "Cannot read payload file %s\n",
+ payload_filename);
+ return -1;
+ }
+
+ fclose(payload);
+
+ *payload_checksum = image_checksum32(payload_start, payloadsz);
+ return 0;
+}
+
+static void *image_create_v0(struct image_cfg_element *image_cfg,
+ int cfgn, const char *output, size_t *imagesz)
+{
+ struct image_cfg_element *e, *payloade;
+ size_t headersz, payloadsz, totalsz;
+ struct main_hdr_v0 *main_hdr;
+ struct ext_hdr_v0 *ext_hdr;
+ void *image;
+ int has_ext = 0;
+ int ret;
+
+ /* Calculate the size of the header and the size of the
+ * payload */
+ headersz = sizeof(struct main_hdr_v0);
+ payloadsz = 0;
+
+ if (image_count_options(image_cfg, cfgn, IMAGE_CFG_DATA) > 0) {
+ has_ext = 1;
+ headersz += sizeof(struct ext_hdr_v0);
+ }
+
+ if (image_count_options(image_cfg, cfgn, IMAGE_CFG_PAYLOAD) > 1) {
+ fprintf(stderr, "More than one payload, not possible\n");
+ return NULL;
+ }
+
+ payloade = image_find_option(image_cfg, cfgn, IMAGE_CFG_PAYLOAD);
+ if (payloade) {
+ struct stat s;
+ int ret;
+
+ ret = stat(payloade->payload, &s);
+ if (ret < 0) {
+ fprintf(stderr, "Cannot stat payload file %s\n",
+ payloade->payload);
+ return NULL;
+ }
+
+ payloadsz = s.st_size;
+ }
+
+ /* Headers, payload and 32-bits checksum */
+ totalsz = headersz + payloadsz + sizeof(uint32_t);
+
+ image = malloc(totalsz);
+ if (!image) {
+ fprintf(stderr, "Cannot allocate memory for image\n");
+ return NULL;
+ }
+
+ memset(image, 0, totalsz);
+
+ main_hdr = image;
+
+ /* Fill in the main header */
+ main_hdr->blocksize = payloadsz + sizeof(uint32_t);
+ main_hdr->srcaddr = headersz;
+ main_hdr->ext = has_ext;
+ e = image_find_option(image_cfg, cfgn, IMAGE_CFG_BOOT_FROM);
+ if (e)
+ main_hdr->blockid = e->bootfrom;
+ e = image_find_option(image_cfg, cfgn, IMAGE_CFG_DEST_ADDR);
+ if (e)
+ main_hdr->destaddr = e->dstaddr;
+ e = image_find_option(image_cfg, cfgn, IMAGE_CFG_EXEC_ADDR);
+ if (e)
+ main_hdr->execaddr = e->execaddr;
+ e = image_find_option(image_cfg, cfgn, IMAGE_CFG_NAND_ECC_MODE);
+ if (e)
+ main_hdr->nandeccmode = e->nandeccmode;
+ e = image_find_option(image_cfg, cfgn, IMAGE_CFG_NAND_PAGESZ);
+ if (e)
+ main_hdr->nandpagesize = e->nandpagesz;
+ main_hdr->checksum = image_checksum8(image,
+ sizeof(struct main_hdr_v0));
+
+ /* Generate the ext header */
+ if (has_ext) {
+ int cfgi, datai;
+
+ ext_hdr = image + sizeof(struct main_hdr_v0);
+ ext_hdr->offset = 0x40;
+
+ for (cfgi = 0, datai = 0; cfgi < cfgn; cfgi++) {
+ e = &image_cfg[cfgi];
+
+ if (e->type != IMAGE_CFG_DATA)
+ continue;
+
+ ext_hdr->rcfg[datai].raddr = e->regdata.raddr;
+ ext_hdr->rcfg[datai].rdata = e->regdata.rdata;
+ datai++;
+ }
+
+ ext_hdr->checksum = image_checksum8(ext_hdr,
+ sizeof(struct ext_hdr_v0));
+ }
+
+ if (payloade) {
+ ret = image_create_payload(image + headersz, payloadsz,
+ payloade->payload);
+ if (ret < 0)
+ return NULL;
+ }
+
+ *imagesz = totalsz;
+ return image;
+}
+
+static void *image_create_v1(struct image_cfg_element *image_cfg,
+ int cfgn, const char *output, size_t *imagesz)
+{
+ struct image_cfg_element *e, *payloade, *binarye;
+ struct main_hdr_v1 *main_hdr;
+ size_t headersz, payloadsz, totalsz;
+ void *image, *cur;
+ int hasext = 0;
+ int ret;
+
+ /* Calculate the size of the header and the size of the
+ * payload */
+ headersz = sizeof(struct main_hdr_v1);
+ payloadsz = 0;
+
+ if (image_count_options(image_cfg, cfgn, IMAGE_CFG_BINARY) > 1) {
+ fprintf(stderr, "More than one binary blob, not supported\n");
+ return NULL;
+ }
+
+ if (image_count_options(image_cfg, cfgn, IMAGE_CFG_PAYLOAD) > 1) {
+ fprintf(stderr, "More than one payload, not possible\n");
+ return NULL;
+ }
+
+ binarye = image_find_option(image_cfg, cfgn, IMAGE_CFG_BINARY);
+ if (binarye) {
+ struct stat s;
+
+ ret = stat(binarye->binary.file, &s);
+ if (ret < 0) {
+ char *cwd = get_current_dir_name();
+ fprintf(stderr,
+ "Didn't find the file '%s' in '%s' which is mandatory to generate the image\n"
+ "This file generally contains the DDR3 training code, and should be extracted from an existing bootable\n"
+ "image for your board. See 'kwbimage -x' to extract it from an existing image.\n",
+ binarye->binary.file, cwd);
+ free(cwd);
+ return NULL;
+ }
+
+ headersz += s.st_size +
+ binarye->binary.nargs * sizeof(unsigned int);
+ hasext = 1;
+ }
+
+ payloade = image_find_option(image_cfg, cfgn, IMAGE_CFG_PAYLOAD);
+ if (payloade) {
+ struct stat s;
+
+ ret = stat(payloade->payload, &s);
+ if (ret < 0) {
+ fprintf(stderr, "Cannot stat payload file %s\n",
+ payloade->payload);
+ return NULL;
+ }
+
+ payloadsz = s.st_size;
+ }
+
+ /* The payload should be aligned on some reasonable
+ * boundary */
+ headersz = ALIGN_SUP(headersz, 4096);
+
+ /* The total size includes the headers, the payload, and the
+ * 32 bits checksum at the end of the payload */
+ totalsz = headersz + payloadsz + sizeof(uint32_t);
+
+ image = malloc(totalsz);
+ if (!image) {
+ fprintf(stderr, "Cannot allocate memory for image\n");
+ return NULL;
+ }
+
+ memset(image, 0, totalsz);
+
+ cur = main_hdr = image;
+ cur += sizeof(struct main_hdr_v1);
+
+ /* Fill the main header */
+ main_hdr->blocksize = payloadsz + sizeof(uint32_t);
+ main_hdr->headersz_lsb = headersz & 0xFFFF;
+ main_hdr->headersz_msb = (headersz & 0xFFFF0000) >> 16;
+ main_hdr->srcaddr = headersz;
+ main_hdr->ext = hasext;
+ main_hdr->version = 1;
+ e = image_find_option(image_cfg, cfgn, IMAGE_CFG_BOOT_FROM);
+ if (e)
+ main_hdr->blockid = e->bootfrom;
+ e = image_find_option(image_cfg, cfgn, IMAGE_CFG_DEST_ADDR);
+ if (e)
+ main_hdr->destaddr = e->dstaddr;
+ e = image_find_option(image_cfg, cfgn, IMAGE_CFG_EXEC_ADDR);
+ if (e)
+ main_hdr->execaddr = e->execaddr;
+ e = image_find_option(image_cfg, cfgn, IMAGE_CFG_NAND_BLKSZ);
+ if (e)
+ main_hdr->nandblocksize = e->nandblksz / (64 * 1024);
+ e = image_find_option(image_cfg, cfgn, IMAGE_CFG_NAND_BADBLK_LOCATION);
+ if (e)
+ main_hdr->nandbadblklocation = e->nandbadblklocation;
+
+ if (binarye) {
+ struct opt_hdr_v1 *hdr = cur;
+ unsigned int *args;
+ size_t binhdrsz;
+ struct stat s;
+ int argi;
+ FILE *bin;
+
+ hdr->headertype = OPT_HDR_V1_BINARY_TYPE;
+
+ bin = fopen(binarye->binary.file, "r");
+ if (!bin) {
+ fprintf(stderr, "Cannot open binary file %s\n",
+ binarye->binary.file);
+ return NULL;
+ }
+
+ fstat(fileno(bin), &s);
+
+ binhdrsz = sizeof(struct opt_hdr_v1) +
+ (binarye->binary.nargs + 1) * sizeof(unsigned int) +
+ s.st_size;
+ hdr->headersz_lsb = binhdrsz & 0xFFFF;
+ hdr->headersz_msb = (binhdrsz & 0xFFFF0000) >> 16;
+
+ cur += sizeof(struct opt_hdr_v1);
+
+ args = cur;
+ *args = binarye->binary.nargs;
+ args++;
+ for (argi = 0; argi < binarye->binary.nargs; argi++)
+ args[argi] = binarye->binary.args[argi];
+
+ cur += (binarye->binary.nargs + 1) * sizeof(unsigned int);
+
+ ret = fread(cur, s.st_size, 1, bin);
+ if (ret != 1) {
+ fprintf(stderr,
+ "Could not read binary image %s\n",
+ binarye->binary.file);
+ return NULL;
+ }
+
+ fclose(bin);
+
+ cur += s.st_size;
+
+ /*
+ * For now, we don't support more than one binary
+ * header, and no other header types are
+ * supported. So, the binary header is necessarily the
+ * last one
+ */
+ *((unsigned char *) cur) = 0;
+
+ cur += sizeof(uint32_t);
+ }
+
+ /* Calculate and set the header checksum */
+ main_hdr->checksum = image_checksum8(main_hdr, headersz);
+
+ if (payloade) {
+ ret = image_create_payload(image + headersz, payloadsz,
+ payloade->payload);
+ if (ret < 0)
+ return NULL;
+ }
+
+ *imagesz = totalsz;
+ return image;
+}
+
+static int image_create_config_parse_oneline(char *line,
+ struct image_cfg_element *el)
+{
+ char *keyword, *saveptr;
+
+ keyword = strtok_r(line, " ", &saveptr);
+ if (!strcmp(keyword, "VERSION")) {
+ char *value = strtok_r(NULL, " ", &saveptr);
+ el->type = IMAGE_CFG_VERSION;
+ el->version = atoi(value);
+ } else if (!strcmp(keyword, "BOOT_FROM")) {
+ char *value = strtok_r(NULL, " ", &saveptr);
+ el->type = IMAGE_CFG_BOOT_FROM;
+ el->bootfrom = image_boot_mode_id(value);
+ if (el->bootfrom < 0) {
+ fprintf(stderr,
+ "Invalid boot media '%s'\n", value);
+ return -1;
+ }
+ } else if (!strcmp(keyword, "DESTADDR")) {
+ char *value = strtok_r(NULL, " ", &saveptr);
+ el->type = IMAGE_CFG_DEST_ADDR;
+ el->dstaddr = strtol(value, NULL, 16);
+ } else if (!strcmp(keyword, "EXECADDR")) {
+ char *value = strtok_r(NULL, " ", &saveptr);
+ el->type = IMAGE_CFG_EXEC_ADDR;
+ el->execaddr = strtol(value, NULL, 16);
+ } else if (!strcmp(keyword, "NAND_BLKSZ")) {
+ char *value = strtok_r(NULL, " ", &saveptr);
+ el->type = IMAGE_CFG_NAND_BLKSZ;
+ el->nandblksz = strtol(value, NULL, 16);
+ } else if (!strcmp(keyword, "NAND_BADBLK_LOCATION")) {
+ char *value = strtok_r(NULL, " ", &saveptr);
+ el->type = IMAGE_CFG_NAND_BADBLK_LOCATION;
+ el->nandbadblklocation =
+ strtol(value, NULL, 16);
+ } else if (!strcmp(keyword, "NAND_ECCMODE")) {
+ char *value = strtok_r(NULL, " ", &saveptr);
+ el->type = IMAGE_CFG_NAND_ECC_MODE;
+ el->nandeccmode = image_nand_ecc_mode_id(value);
+ if (el->nandeccmode < 0) {
+ fprintf(stderr,
+ "Invalid NAND ECC mode '%s'\n", value);
+ return -1;
+ }
+ } else if (!strcmp(keyword, "NAND_PAGESZ")) {
+ char *value = strtok_r(NULL, " ", &saveptr);
+ el->type = IMAGE_CFG_NAND_PAGESZ;
+ el->nandpagesz = strtol(value, NULL, 16);
+ } else if (!strcmp(keyword, "BINARY")) {
+ char *value = strtok_r(NULL, " ", &saveptr);
+ int argi = 0;
+
+ el->type = IMAGE_CFG_BINARY;
+ el->binary.file = strdup(value);
+ while (1) {
+ value = strtok_r(NULL, " ", &saveptr);
+ if (!value)
+ break;
+ el->binary.args[argi] = strtol(value, NULL, 16);
+ argi++;
+ if (argi >= BINARY_MAX_ARGS) {
+ fprintf(stderr,
+ "Too many argument for binary\n");
+ return -1;
+ }
+ }
+ el->binary.nargs = argi;
+ } else if (!strcmp(keyword, "DATA")) {
+ char *value1 = strtok_r(NULL, " ", &saveptr);
+ char *value2 = strtok_r(NULL, " ", &saveptr);
+
+ if (!value1 || !value2) {
+ fprintf(stderr, "Invalid number of arguments for DATA\n");
+ return -1;
+ }
+
+ el->type = IMAGE_CFG_DATA;
+ el->regdata.raddr = strtol(value1, NULL, 16);
+ el->regdata.rdata = strtol(value2, NULL, 16);
+ } else if (!strcmp(keyword, "PAYLOAD")) {
+ char *value = strtok_r(NULL, " ", &saveptr);
+ el->type = IMAGE_CFG_PAYLOAD;
+ el->payload = strdup(value);
+ } else {
+ fprintf(stderr, "Ignoring unknown line '%s'\n", line);
+ }
+
+ return 0;
+}
+
+/*
+ * Parse the configuration file 'fcfg' into the array of configuration
+ * elements 'image_cfg', and return the number of configuration
+ * elements in 'cfgn'.
+ */
+static int image_create_config_parse(FILE *fcfg,
+ struct image_cfg_element *image_cfg,
+ int *cfgn)
+{
+ int ret;
+ int cfgi = 0;
+
+ /* Parse the configuration file */
+ while (!feof(fcfg)) {
+ char *line;
+ char buf[256];
+
+ /* Read the current line */
+ memset(buf, 0, sizeof(buf));
+ line = fgets(buf, sizeof(buf), fcfg);
+ if (!line)
+ break;
+
+ /* Ignore useless lines */
+ if (line[0] == '\n' || line[0] == '#')
+ continue;
+
+ /* Strip final newline */
+ if (line[strlen(line) - 1] == '\n')
+ line[strlen(line) - 1] = 0;
+
+ /* Parse the current line */
+ ret = image_create_config_parse_oneline(line,
+ &image_cfg[cfgi]);
+ if (ret)
+ return ret;
+
+ cfgi++;
+
+ if (cfgi >= IMAGE_CFG_ELEMENT_MAX) {
+ fprintf(stderr, "Too many configuration elements in .cfg file\n");
+ return -1;
+ }
+ }
+
+ *cfgn = cfgi;
+ return 0;
+}
+
+static int image_override_payload(struct image_cfg_element *image_cfg,
+ int *cfgn, const char *payload)
+{
+ struct image_cfg_element *e;
+ int cfgi = *cfgn;
+
+ if (!payload)
+ return 0;
+
+ e = image_find_option(image_cfg, *cfgn, IMAGE_CFG_PAYLOAD);
+ if (e) {
+ e->payload = payload;
+ return 0;
+ }
+
+ image_cfg[cfgi].type = IMAGE_CFG_PAYLOAD;
+ image_cfg[cfgi].payload = payload;
+ cfgi++;
+
+ *cfgn = cfgi;
+ return 0;
+}
+
+static int image_override_bootmedia(struct image_cfg_element *image_cfg,
+ int *cfgn, const char *bootmedia)
+{
+ struct image_cfg_element *e;
+ int bootfrom;
+ int cfgi = *cfgn;
+
+ if (!bootmedia)
+ return 0;
+
+ bootfrom = image_boot_mode_id(bootmedia);
+ if (!bootfrom) {
+ fprintf(stderr,
+ "Invalid boot media '%s'\n", bootmedia);
+ return -1;
+ }
+
+ e = image_find_option(image_cfg, *cfgn, IMAGE_CFG_BOOT_FROM);
+ if (e) {
+ e->bootfrom = bootfrom;
+ return 0;
+ }
+
+ image_cfg[cfgi].type = IMAGE_CFG_BOOT_FROM;
+ image_cfg[cfgi].bootfrom = bootfrom;
+ cfgi++;
+
+ *cfgn = cfgi;
+ return 0;
+}
+
+static int image_override_dstaddr(struct image_cfg_element *image_cfg,
+ int *cfgn, uint32_t dstaddr)
+{
+ struct image_cfg_element *e;
+ int cfgi = *cfgn;
+
+ if (dstaddr == ADDR_INVALID)
+ return 0;
+
+ e = image_find_option(image_cfg, *cfgn, IMAGE_CFG_DEST_ADDR);
+ if (e) {
+ e->dstaddr = dstaddr;
+ return 0;
+ }
+
+ image_cfg[cfgi].type = IMAGE_CFG_DEST_ADDR;
+ image_cfg[cfgi].dstaddr = dstaddr;
+ cfgi++;
+
+ *cfgn = cfgi;
+ return 0;
+}
+
+static int image_override_execaddr(struct image_cfg_element *image_cfg,
+ int *cfgn, uint32_t execaddr)
+{
+ struct image_cfg_element *e;
+ int cfgi = *cfgn;
+
+ if (execaddr == ADDR_INVALID)
+ return 0;
+
+ e = image_find_option(image_cfg, *cfgn, IMAGE_CFG_EXEC_ADDR);
+ if (e) {
+ e->execaddr = execaddr;
+ return 0;
+ }
+
+ image_cfg[cfgi].type = IMAGE_CFG_EXEC_ADDR;
+ image_cfg[cfgi].execaddr = execaddr;
+ cfgi++;
+
+ *cfgn = cfgi;
+ return 0;
+}
+
+static int image_get_version(struct image_cfg_element *image_cfg,
+ int cfgn)
+{
+ struct image_cfg_element *e;
+
+ e = image_find_option(image_cfg, cfgn, IMAGE_CFG_VERSION);
+ if (!e)
+ return -1;
+
+ return e->version;
+}
+
+static void image_dump_config(struct image_cfg_element *image_cfg,
+ int cfgn)
+{
+ int cfgi;
+
+ printf("== configuration dump\n");
+
+ for (cfgi = 0; cfgi < cfgn; cfgi++) {
+ struct image_cfg_element *e = &image_cfg[cfgi];
+ switch (e->type) {
+ case IMAGE_CFG_VERSION:
+ printf("VERSION %d\n", e->version);
+ break;
+ case IMAGE_CFG_BOOT_FROM:
+ printf("BOOTFROM %s\n",
+ image_boot_mode_name(e->bootfrom));
+ break;
+ case IMAGE_CFG_DEST_ADDR:
+ printf("DESTADDR 0x%x\n", e->dstaddr);
+ break;
+ case IMAGE_CFG_EXEC_ADDR:
+ printf("EXECADDR 0x%x\n", e->execaddr);
+ break;
+ case IMAGE_CFG_NAND_BLKSZ:
+ printf("NANDBLKSZ 0x%x\n", e->nandblksz);
+ break;
+ case IMAGE_CFG_NAND_BADBLK_LOCATION:
+ printf("NANDBADBLK 0x%x\n", e->nandbadblklocation);
+ break;
+ case IMAGE_CFG_NAND_ECC_MODE:
+ printf("NAND_ECCMODE 0x%x\n", e->nandeccmode);
+ break;
+ case IMAGE_CFG_NAND_PAGESZ:
+ printf("NAND_PAGESZ 0x%x\n", e->nandpagesz);
+ break;
+ case IMAGE_CFG_BINARY:
+ printf("BINARY %s (%d args)\n", e->binary.file,
+ e->binary.nargs);
+ break;
+ case IMAGE_CFG_PAYLOAD:
+ printf("PAYLOAD %s\n", e->payload);
+ break;
+ case IMAGE_CFG_DATA:
+ printf("DATA 0x%x 0x%x\n",
+ e->regdata.raddr,
+ e->regdata.rdata);
+ break;
+ default:
+ printf("Error, unknown type\n");
+ break;
+ }
+ }
+
+ printf("== end configuration dump\n");
+}
+
+static int image_create(const char *input, const char *output,
+ const char *payload, const char *bootmedia,
+ uint32_t dstaddr, uint32_t execaddr,
+ int verbose)
+{
+ struct image_cfg_element *image_cfg;
+ FILE *fcfg, *outputimg;
+ void *image = NULL;
+ int version;
+ size_t imagesz;
+ int cfgn;
+ int ret;
+
+ fcfg = fopen(input, "r");
+ if (!fcfg) {
+ fprintf(stderr, "Could not open input file %s\n",
+ input);
+ return -1;
+ }
+
+ image_cfg = malloc(IMAGE_CFG_ELEMENT_MAX *
+ sizeof(struct image_cfg_element));
+ if (!image_cfg) {
+ fprintf(stderr, "Cannot allocate memory\n");
+ fclose(fcfg);
+ return -1;
+ }
+
+ memset(image_cfg, 0,
+ IMAGE_CFG_ELEMENT_MAX * sizeof(struct image_cfg_element));
+ rewind(fcfg);
+
+ ret = image_create_config_parse(fcfg, image_cfg, &cfgn);
+ if (ret) {
+ free(image_cfg);
+ return -1;
+ }
+
+ image_override_payload(image_cfg, &cfgn, payload);
+ image_override_bootmedia(image_cfg, &cfgn, bootmedia);
+ image_override_dstaddr(image_cfg, &cfgn, dstaddr);
+ image_override_execaddr(image_cfg, &cfgn, execaddr);
+
+ if (!image_find_option(image_cfg, cfgn, IMAGE_CFG_BOOT_FROM) ||
+ !image_find_option(image_cfg, cfgn, IMAGE_CFG_DEST_ADDR) ||
+ !image_find_option(image_cfg, cfgn, IMAGE_CFG_EXEC_ADDR)) {
+ fprintf(stderr,
+ "Missing information (either boot media, exec addr or dest addr)\n");
+ free(image_cfg);
+ return -1;
+ }
+
+ if (verbose)
+ image_dump_config(image_cfg, cfgn);
+
+ version = image_get_version(image_cfg, cfgn);
+
+ if (version == 0)
+ image = image_create_v0(image_cfg, cfgn, output, &imagesz);
+ else if (version == 1)
+ image = image_create_v1(image_cfg, cfgn, output, &imagesz);
+ else if (version == -1) {
+ fprintf(stderr, "File %s does not have the VERSION field\n",
+ input);
+ free(image_cfg);
+ return -1;
+ }
+
+ if (!image) {
+ fprintf(stderr, "Could not create image\n");
+ free(image_cfg);
+ return -1;
+ }
+
+ free(image_cfg);
+
+ outputimg = fopen(output, "w");
+ if (!outputimg) {
+ fprintf(stderr, "Cannot open output image %s for writing\n",
+ output);
+ free(image);
+ return -1;
+ }
+
+ ret = fwrite(image, imagesz, 1, outputimg);
+ if (ret != 1) {
+ fprintf(stderr, "Cannot write to output image %s\n",
+ output);
+ fclose(outputimg);
+ free(image);
+ return -1;
+ }
+
+ fclose(outputimg);
+ free(image);
+
+ return 0;
+}
+
+enum {
+ ACTION_CREATE,
+ ACTION_EXTRACT,
+ ACTION_DUMP,
+ ACTION_HELP,
+};
+
+int main(int argc, char *argv[])
+{
+ int action = -1, opt, verbose = 0;
+ const char *input = NULL, *output = NULL,
+ *payload = NULL, *bootmedia = NULL;
+ uint32_t execaddr = ADDR_INVALID, dstaddr = ADDR_INVALID;
+
+ while ((opt = getopt(argc, argv, "hxci:o:p:m:e:d:v")) != -1) {
+ switch (opt) {
+ case 'x':
+ action = ACTION_EXTRACT;
+ break;
+ case 'c':
+ action = ACTION_CREATE;
+ break;
+ case 'i':
+ input = optarg;
+ break;
+ case 'o':
+ output = optarg;
+ break;
+ case 'p':
+ payload = optarg;
+ break;
+ case 'm':
+ bootmedia = optarg;
+ break;
+ case 'e':
+ execaddr = strtol(optarg, NULL, 0);
+ break;
+ case 'd':
+ dstaddr = strtol(optarg, NULL, 0);
+ break;
+ case 'v':
+ verbose = 1;
+ break;
+ case 'h':
+ action = ACTION_HELP;
+ break;
+ }
+ }
+
+ /* We should have consumed all arguments */
+ if (optind != argc) {
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (action != ACTION_HELP && !input) {
+ fprintf(stderr, "Missing input file\n");
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if ((action == ACTION_EXTRACT || action == ACTION_CREATE) &&
+ !output) {
+ fprintf(stderr, "Missing output file\n");
+ usage(argv[0]);
+ exit(1);
+ }
+
+ if (action == ACTION_EXTRACT &&
+ (bootmedia || payload ||
+ (execaddr != ADDR_INVALID) || (dstaddr != ADDR_INVALID))) {
+ fprintf(stderr,
+ "-m, -p, -e or -d do not make sense when extracting an image");
+ usage(argv[0]);
+ exit(1);
+ }
+
+ switch (action) {
+ case ACTION_EXTRACT:
+ return image_extract(input, output);
+ case ACTION_CREATE:
+ return image_create(input, output, payload,
+ bootmedia, dstaddr, execaddr,
+ verbose);
+ case ACTION_HELP:
+ usage(argv[0]);
+ return 0;
+ default:
+ fprintf(stderr, "No action specified\n");
+ usage(argv[0]);
+ exit(1);
+ }
+
+ return 0;
+}
diff --git a/scripts/kwboot.c b/scripts/kwboot.c
new file mode 100644
index 0000000000..33c94b3a8b
--- /dev/null
+++ b/scripts/kwboot.c
@@ -0,0 +1,730 @@
+/*
+ * Boot a Marvell SoC, with Xmodem over UART0.
+ * supports Kirkwood, Dove, Armada 370, Armada XP
+ *
+ * (c) 2012 Daniel Stodden <daniel.stodden@gmail.com>
+ *
+ * References: marvell.com, "88F6180, 88F6190, 88F6192, and 88F6281
+ * Integrated Controller: Functional Specifications" December 2,
+ * 2008. Chapter 24.2 "BootROM Firmware".
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <libgen.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <termios.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+/*
+ * Marvell BootROM UART Sensing
+ */
+
+static unsigned char kwboot_msg_boot[] = {
+ 0xBB, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
+};
+
+static unsigned char kwboot_msg_debug[] = {
+ 0xDD, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77
+};
+
+#define KWBOOT_MSG_REQ_DELAY 1000 /* ms */
+#define KWBOOT_MSG_RSP_TIMEO 1000 /* ms */
+
+/*
+ * Xmodem Transfers
+ */
+
+#define SOH 1 /* sender start of block header */
+#define EOT 4 /* sender end of block transfer */
+#define ACK 6 /* target block ack */
+#define NAK 21 /* target block negative ack */
+#define CAN 24 /* target/sender transfer cancellation */
+
+struct kwboot_block {
+ uint8_t soh;
+ uint8_t pnum;
+ uint8_t _pnum;
+ uint8_t data[128];
+ uint8_t csum;
+} __attribute((packed));
+
+#define KWBOOT_BLK_RSP_TIMEO 1000 /* ms */
+
+static int kwboot_verbose;
+
+static void
+kwboot_printv(const char *fmt, ...)
+{
+ va_list ap;
+
+ if (kwboot_verbose) {
+ va_start(ap, fmt);
+ vprintf(fmt, ap);
+ va_end(ap);
+ fflush(stdout);
+ }
+}
+
+static void
+__spinner(void)
+{
+ const char seq[] = { '-', '\\', '|', '/' };
+ const int div = 8;
+ static int state, bs;
+
+ if (state % div == 0) {
+ fputc(bs, stdout);
+ fputc(seq[state / div % sizeof(seq)], stdout);
+ fflush(stdout);
+ }
+
+ bs = '\b';
+ state++;
+}
+
+static void
+kwboot_spinner(void)
+{
+ if (kwboot_verbose)
+ __spinner();
+}
+
+static void
+__progress(int pct, char c)
+{
+ const int width = 70;
+ static const char *nl = "";
+ static int pos;
+
+ if (pos % width == 0)
+ printf("%s%3d %% [", nl, pct);
+
+ fputc(c, stdout);
+
+ nl = "]\n";
+ pos++;
+
+ if (pct == 100) {
+ while (pos++ < width)
+ fputc(' ', stdout);
+ fputs(nl, stdout);
+ }
+
+ fflush(stdout);
+
+}
+
+static void
+kwboot_progress(int _pct, char c)
+{
+ static int pct;
+
+ if (_pct != -1)
+ pct = _pct;
+
+ if (kwboot_verbose)
+ __progress(pct, c);
+}
+
+static int
+kwboot_tty_recv(int fd, void *buf, size_t len, int timeo)
+{
+ int rc, nfds;
+ fd_set rfds;
+ struct timeval tv;
+ ssize_t n;
+
+ rc = -1;
+
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+
+ tv.tv_sec = 0;
+ tv.tv_usec = timeo * 1000;
+ if (tv.tv_usec > 1000000) {
+ tv.tv_sec += tv.tv_usec / 1000000;
+ tv.tv_usec %= 1000000;
+ }
+
+ do {
+ nfds = select(fd + 1, &rfds, NULL, NULL, &tv);
+ if (nfds < 0)
+ goto out;
+ if (!nfds) {
+ errno = ETIMEDOUT;
+ goto out;
+ }
+
+ n = read(fd, buf, len);
+ if (n < 0)
+ goto out;
+
+ buf = (char *)buf + n;
+ len -= n;
+ } while (len > 0);
+
+ rc = 0;
+out:
+ return rc;
+}
+
+static int
+kwboot_tty_send(int fd, const void *buf, size_t len)
+{
+ int rc;
+ ssize_t n;
+
+ if (!buf)
+ return 0;
+
+ rc = -1;
+
+ do {
+ n = write(fd, buf, len);
+ if (n < 0)
+ goto out;
+
+ buf = (char *)buf + n;
+ len -= n;
+ } while (len > 0);
+
+ rc = tcdrain(fd);
+out:
+ return rc;
+}
+
+static int
+kwboot_tty_send_char(int fd, unsigned char c)
+{
+ return kwboot_tty_send(fd, &c, 1);
+}
+
+static speed_t
+kwboot_tty_speed(int baudrate)
+{
+ switch (baudrate) {
+ case 115200:
+ return B115200;
+ case 57600:
+ return B57600;
+ case 38400:
+ return B38400;
+ case 19200:
+ return B19200;
+ case 9600:
+ return B9600;
+ }
+
+ return -1;
+}
+
+static int
+kwboot_open_tty(const char *path, speed_t speed)
+{
+ int rc, fd;
+ struct termios tio;
+
+ rc = -1;
+
+ fd = open(path, O_RDWR|O_NOCTTY|O_NDELAY);
+ if (fd < 0)
+ goto out;
+
+ memset(&tio, 0, sizeof(tio));
+
+ tio.c_iflag = 0;
+ tio.c_cflag = CREAD|CLOCAL|CS8;
+
+ tio.c_cc[VMIN] = 1;
+ tio.c_cc[VTIME] = 10;
+
+ cfsetospeed(&tio, speed);
+ cfsetispeed(&tio, speed);
+
+ rc = tcsetattr(fd, TCSANOW, &tio);
+ if (rc)
+ goto out;
+
+ rc = fd;
+out:
+ if (rc < 0) {
+ if (fd >= 0)
+ close(fd);
+ }
+
+ return rc;
+}
+
+static int
+kwboot_bootmsg(int tty, void *msg)
+{
+ int rc;
+ char c;
+
+ if (msg == NULL)
+ kwboot_printv("Please reboot the target into UART boot mode...");
+ else
+ kwboot_printv("Sending boot message. Please reboot the target...");
+
+ do {
+ rc = tcflush(tty, TCIOFLUSH);
+ if (rc)
+ break;
+
+ rc = kwboot_tty_send(tty, msg, 8);
+ if (rc) {
+ usleep(KWBOOT_MSG_REQ_DELAY * 1000);
+ continue;
+ }
+
+ rc = kwboot_tty_recv(tty, &c, 1, KWBOOT_MSG_RSP_TIMEO);
+
+ kwboot_spinner();
+
+ } while (rc || c != NAK);
+
+ kwboot_printv("\n");
+
+ return rc;
+}
+
+static int
+kwboot_debugmsg(int tty, void *msg)
+{
+ int rc;
+
+ kwboot_printv("Sending debug message. Please reboot the target...");
+
+ do {
+ char buf[16];
+
+ rc = tcflush(tty, TCIOFLUSH);
+ if (rc)
+ break;
+
+ rc = kwboot_tty_send(tty, msg, 8);
+ if (rc) {
+ usleep(KWBOOT_MSG_REQ_DELAY * 1000);
+ continue;
+ }
+
+ rc = kwboot_tty_recv(tty, buf, 16, KWBOOT_MSG_RSP_TIMEO);
+
+ kwboot_spinner();
+
+ } while (rc);
+
+ kwboot_printv("\n");
+
+ return rc;
+}
+
+static int
+kwboot_xm_makeblock(struct kwboot_block *block, const void *data,
+ size_t size, int pnum)
+{
+ const size_t blksz = sizeof(block->data);
+ size_t n;
+ int i;
+
+ block->pnum = pnum;
+ block->_pnum = ~block->pnum;
+
+ n = size < blksz ? size : blksz;
+ memcpy(&block->data[0], data, n);
+ memset(&block->data[n], 0, blksz - n);
+
+ block->csum = 0;
+ for (i = 0; i < n; i++)
+ block->csum += block->data[i];
+
+ return n;
+}
+
+static int
+kwboot_xm_sendblock(int fd, struct kwboot_block *block)
+{
+ int rc, retries;
+ char c;
+
+ retries = 16;
+ do {
+ rc = kwboot_tty_send(fd, block, sizeof(*block));
+ if (rc)
+ break;
+
+ do {
+ rc = kwboot_tty_recv(fd, &c, 1, KWBOOT_BLK_RSP_TIMEO);
+ if (rc)
+ break;
+
+ if (c != ACK && c!= NAK && c != CAN)
+ printf("%c", c);
+
+ } while (c != ACK && c != NAK && c != CAN);
+
+ if (c != ACK)
+ kwboot_progress(-1, '+');
+
+ } while (c == NAK && retries-- > 0);
+
+ rc = -1;
+
+ switch (c) {
+ case ACK:
+ rc = 0;
+ break;
+ case NAK:
+ errno = EBADMSG;
+ break;
+ case CAN:
+ errno = ECANCELED;
+ break;
+ default:
+ errno = EPROTO;
+ break;
+ }
+
+ return rc;
+}
+
+static int
+kwboot_xmodem(int tty, const void *_data, size_t size)
+{
+ const uint8_t *data = _data;
+ int rc, pnum, N, err;
+
+ pnum = 1;
+ N = 0;
+
+ kwboot_printv("Sending boot image...\n");
+
+ do {
+ struct kwboot_block block;
+ int n;
+
+ n = kwboot_xm_makeblock(&block,
+ data + N, size - N,
+ pnum++);
+ if (n < 0)
+ goto can;
+
+ if (!n)
+ break;
+
+ rc = kwboot_xm_sendblock(tty, &block);
+ if (rc)
+ goto out;
+
+ N += n;
+ kwboot_progress(N * 100 / size, '.');
+ } while (1);
+
+ rc = kwboot_tty_send_char(tty, EOT);
+
+out:
+ return rc;
+
+can:
+ err = errno;
+ kwboot_tty_send_char(tty, CAN);
+ errno = err;
+ goto out;
+}
+
+static int
+kwboot_term_pipe(int in, int out, char *quit, int *s)
+{
+ ssize_t nin, nout;
+ char _buf[128], *buf = _buf;
+
+ nin = read(in, buf, sizeof(buf));
+ if (nin < 0)
+ return -1;
+
+ if (quit) {
+ int i;
+
+ for (i = 0; i < nin; i++) {
+ if (*buf == quit[*s]) {
+ (*s)++;
+ if (!quit[*s])
+ return 0;
+ buf++;
+ nin--;
+ } else
+ while (*s > 0) {
+ nout = write(out, quit, *s);
+ if (nout <= 0)
+ return -1;
+ (*s) -= nout;
+ }
+ }
+ }
+
+ while (nin > 0) {
+ nout = write(out, buf, nin);
+ if (nout <= 0)
+ return -1;
+ nin -= nout;
+ }
+
+ return 0;
+}
+
+static int
+kwboot_terminal(int tty)
+{
+ int rc, in, s;
+ char *quit = "\34c";
+ struct termios otio, tio;
+
+ rc = -1;
+
+ in = STDIN_FILENO;
+ if (isatty(in)) {
+ rc = tcgetattr(in, &otio);
+ if (!rc) {
+ tio = otio;
+ cfmakeraw(&tio);
+ rc = tcsetattr(in, TCSANOW, &tio);
+ }
+ if (rc) {
+ perror("tcsetattr");
+ goto out;
+ }
+
+ kwboot_printv("[Type Ctrl-%c + %c to quit]\r\n",
+ quit[0]|0100, quit[1]);
+ } else
+ in = -1;
+
+ rc = 0;
+ s = 0;
+
+ do {
+ fd_set rfds;
+ int nfds = 0;
+
+ FD_SET(tty, &rfds);
+ nfds = nfds < tty ? tty : nfds;
+
+ if (in >= 0) {
+ FD_SET(in, &rfds);
+ nfds = nfds < in ? in : nfds;
+ }
+
+ nfds = select(nfds + 1, &rfds, NULL, NULL, NULL);
+ if (nfds < 0)
+ break;
+
+ if (FD_ISSET(tty, &rfds)) {
+ rc = kwboot_term_pipe(tty, STDOUT_FILENO, NULL, NULL);
+ if (rc)
+ break;
+ }
+
+ if (FD_ISSET(in, &rfds)) {
+ rc = kwboot_term_pipe(in, tty, quit, &s);
+ if (rc)
+ break;
+ }
+ } while (quit[s] != 0);
+
+ tcsetattr(in, TCSANOW, &otio);
+out:
+ return rc;
+}
+
+static void *
+kwboot_mmap_image(const char *path, size_t *size, int prot)
+{
+ int rc, fd, flags;
+ struct stat st;
+ void *img;
+
+ rc = -1;
+ fd = -1;
+ img = NULL;
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ goto out;
+
+ rc = fstat(fd, &st);
+ if (rc)
+ goto out;
+
+ flags = (prot & PROT_WRITE) ? MAP_PRIVATE : MAP_SHARED;
+
+ img = mmap(NULL, st.st_size, prot, flags, fd, 0);
+ if (img == MAP_FAILED) {
+ img = NULL;
+ goto out;
+ }
+
+ rc = 0;
+ *size = st.st_size;
+out:
+ if (rc && img) {
+ munmap(img, st.st_size);
+ img = NULL;
+ }
+ if (fd >= 0)
+ close(fd);
+
+ return img;
+}
+
+static void
+kwboot_usage(FILE *stream, char *progname)
+{
+ fprintf(stream,
+ "Usage: %s [-d | -b <image> | -D <image> ] [ -t ] [-B <baud> ] <TTY>\n",
+ progname);
+ fprintf(stream, "\n");
+ fprintf(stream,
+ " -b <image>: boot <image> with preamble (Kirkwood, Armada 370/XP)\n");
+ fprintf(stream,
+ " -D <image>: boot <image> without preamble (Dove)\n");
+ fprintf(stream, " -d: enter debug mode\n");
+ fprintf(stream, "\n");
+ fprintf(stream, " -t: mini terminal\n");
+ fprintf(stream, "\n");
+ fprintf(stream, " -B <baud>: set baud rate\n");
+ fprintf(stream, "\n");
+}
+
+int
+main(int argc, char **argv)
+{
+ const char *ttypath, *imgpath;
+ int rv, rc, tty, term;
+ void *bootmsg;
+ void *debugmsg;
+ void *img;
+ size_t size;
+ speed_t speed;
+
+ rv = 1;
+ tty = -1;
+ bootmsg = NULL;
+ debugmsg = NULL;
+ imgpath = NULL;
+ img = NULL;
+ term = 0;
+ size = 0;
+ speed = B115200;
+
+ kwboot_verbose = isatty(STDOUT_FILENO);
+
+ do {
+ int c = getopt(argc, argv, "hb:dtB:D:");
+ if (c < 0)
+ break;
+
+ switch (c) {
+ case 'b':
+ bootmsg = kwboot_msg_boot;
+ imgpath = optarg;
+ break;
+
+ case 'D':
+ bootmsg = NULL;
+ imgpath = optarg;
+ break;
+
+ case 'd':
+ debugmsg = kwboot_msg_debug;
+ break;
+
+ case 't':
+ term = 1;
+ break;
+
+ case 'B':
+ speed = kwboot_tty_speed(atoi(optarg));
+ if (speed == -1)
+ goto usage;
+ break;
+
+ case 'h':
+ rv = 0;
+ default:
+ goto usage;
+ }
+ } while (1);
+
+ if (!bootmsg && !term && !debugmsg)
+ goto usage;
+
+ if (argc - optind < 1)
+ goto usage;
+
+ ttypath = argv[optind++];
+
+ tty = kwboot_open_tty(ttypath, speed);
+ if (tty < 0) {
+ perror(ttypath);
+ goto out;
+ }
+
+ if (imgpath) {
+ img = kwboot_mmap_image(imgpath, &size, PROT_READ);
+ if (!img) {
+ perror(imgpath);
+ goto out;
+ }
+ }
+
+ if (debugmsg) {
+ rc = kwboot_debugmsg(tty, debugmsg);
+ if (rc) {
+ perror("debugmsg");
+ goto out;
+ }
+ } else {
+ rc = kwboot_bootmsg(tty, bootmsg);
+ if (rc) {
+ perror("bootmsg");
+ goto out;
+ }
+ }
+
+ if (img) {
+ rc = kwboot_xmodem(tty, img, size);
+ if (rc) {
+ perror("xmodem");
+ goto out;
+ }
+ }
+
+ if (term) {
+ rc = kwboot_terminal(tty);
+ if (rc && !(errno == EINTR)) {
+ perror("terminal");
+ goto out;
+ }
+ }
+
+ rv = 0;
+out:
+ if (tty >= 0)
+ close(tty);
+
+ if (img)
+ munmap(img, size);
+
+ return rv;
+
+usage:
+ kwboot_usage(rv ? stderr : stdout, basename(argv[0]));
+ goto out;
+}