merged tx6dl-devel into denx master branch
authorLothar Waßmann <LW@KARO-electronics.de>
Wed, 21 Aug 2013 14:14:19 +0000 (16:14 +0200)
committerLothar Waßmann <LW@KARO-electronics.de>
Wed, 21 Aug 2013 14:14:19 +0000 (16:14 +0200)
335 files changed:
.gitignore
Makefile
README
arch/arm/config.mk
arch/arm/cpu/arm926ejs/cpu.c
arch/arm/cpu/arm926ejs/mxs/Makefile
arch/arm/cpu/arm926ejs/mxs/mxs.c
arch/arm/cpu/arm926ejs/mxs/spl_boot.c
arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
arch/arm/cpu/arm926ejs/mxs/timer.c
arch/arm/cpu/arm926ejs/mxs/u-boot-imx28.bd
arch/arm/cpu/armv7/am33xx/Makefile
arch/arm/cpu/armv7/am33xx/board.c
arch/arm/cpu/armv7/am33xx/clock_am33xx.c
arch/arm/cpu/armv7/am33xx/ddr.c
arch/arm/cpu/armv7/am33xx/elm.c
arch/arm/cpu/armv7/am33xx/mem.c
arch/arm/cpu/armv7/am33xx/sys_info.c
arch/arm/cpu/armv7/cache_v7.c
arch/arm/cpu/armv7/cpu.c
arch/arm/cpu/armv7/lowlevel_init.S
arch/arm/cpu/armv7/mx5/clock.c
arch/arm/cpu/armv7/mx5/soc.c
arch/arm/cpu/armv7/mx6/asm-offsets.c [new file with mode: 0644]
arch/arm/cpu/armv7/mx6/clock.c
arch/arm/cpu/armv7/mx6/soc.c
arch/arm/cpu/armv7/omap-common/config.mk [deleted file]
arch/arm/cpu/armv7/omap-common/lowlevel_init.S
arch/arm/cpu/armv7/omap-common/reset.c
arch/arm/cpu/armv7/omap-common/timer.c
arch/arm/cpu/armv7/start.S
arch/arm/dts/am33xx.dtsi [new file with mode: 0644]
arch/arm/dts/imx6qdl.dtsi [new file with mode: 0644]
arch/arm/dts/mx28.dtsi [new file with mode: 0644]
arch/arm/dts/mx51.dtsi [new file with mode: 0644]
arch/arm/dts/mx53.dtsi [new file with mode: 0644]
arch/arm/dts/mx6dl.dtsi [new file with mode: 0644]
arch/arm/dts/mx6q.dtsi [new file with mode: 0644]
arch/arm/imx-common/cpu.c
arch/arm/imx-common/iomux-v3.c
arch/arm/imx-common/timer.c
arch/arm/include/asm/arch-am33xx/clocks_am33xx.h
arch/arm/include/asm/arch-am33xx/cpu.h
arch/arm/include/asm/arch-am33xx/da8xx-fb.h [new file with mode: 0644]
arch/arm/include/asm/arch-am33xx/ddr_defs.h
arch/arm/include/asm/arch-am33xx/gpio.h
arch/arm/include/asm/arch-am33xx/mmc_host_def.h
arch/arm/include/asm/arch-am33xx/nand.h [new file with mode: 0644]
arch/arm/include/asm/arch-exynos/system.h
arch/arm/include/asm/arch-mx5/clock.h
arch/arm/include/asm/arch-mx5/crm_regs.h
arch/arm/include/asm/arch-mx5/imx-regs.h
arch/arm/include/asm/arch-mx5/iomux-mx51.h
arch/arm/include/asm/arch-mx5/iomux-mx53.h
arch/arm/include/asm/arch-mx5/sys_proto.h
arch/arm/include/asm/arch-mx6/clock.h
arch/arm/include/asm/arch-mx6/crm_regs.h
arch/arm/include/asm/arch-mx6/imx-regs.h
arch/arm/include/asm/arch-mx6/mx6dl_pins.h
arch/arm/include/asm/arch-mx6/mx6q_pins.h
arch/arm/include/asm/arch-mx6/regs-ocotp.h [new file with mode: 0644]
arch/arm/include/asm/arch-mx6/sys_proto.h
arch/arm/include/asm/arch-mxs/regs-clkctrl-mx28.h
arch/arm/include/asm/arch-mxs/regs-digctl.h
arch/arm/include/asm/arch-mxs/regs-i2c.h
arch/arm/include/asm/arch-mxs/regs-lcdif.h
arch/arm/include/asm/arch-mxs/regs-ocotp.h
arch/arm/include/asm/arch-mxs/regs-pinctrl.h
arch/arm/include/asm/arch-mxs/regs-power-mx28.h
arch/arm/include/asm/arch-mxs/regs-rtc.h
arch/arm/include/asm/arch-mxs/regs-ssp.h
arch/arm/include/asm/arch-mxs/regs-timrot.h
arch/arm/include/asm/arch-mxs/regs-usbphy.h
arch/arm/include/asm/arch-mxs/sys_proto.h
arch/arm/include/asm/emif.h
arch/arm/include/asm/global_data.h
arch/arm/include/asm/imx-common/iomux-v3.h
arch/arm/include/asm/imx-common/regs-apbh.h
arch/arm/include/asm/imx-common/regs-bch.h
arch/arm/include/asm/imx-common/regs-common.h
arch/arm/include/asm/imx-common/regs-gpmi.h
arch/arm/include/asm/system.h
arch/arm/lib/Makefile
arch/arm/lib/cache-cp15.c
arch/arm/lib/cache.c
arch/arm/lib/crt0.S
arch/arm/lib/reset.c
board/denx/m28evk/spl_boot.c
board/freescale/mx6qarm2/mx6qarm2.c
board/freescale/mx6qsabreauto/mx6qsabreauto.c
board/freescale/mx6qsabrelite/mx6qsabrelite.c
board/karo/common/Makefile [new file with mode: 0644]
board/karo/common/fdt.c [new file with mode: 0644]
board/karo/common/karo.h [new file with mode: 0644]
board/karo/common/splashimage.c [new file with mode: 0644]
board/karo/dts/tx28.dts [new file with mode: 0644]
board/karo/dts/tx48.dts [new file with mode: 0644]
board/karo/dts/tx51.dts [new file with mode: 0644]
board/karo/dts/tx53.dts [new file with mode: 0644]
board/karo/dts/tx6dl.dts [new file with mode: 0644]
board/karo/dts/tx6q.dts [new file with mode: 0644]
board/karo/tx28/Makefile [new file with mode: 0644]
board/karo/tx28/config.mk [new file with mode: 0644]
board/karo/tx28/flash.c [new file with mode: 0644]
board/karo/tx28/spl_boot.c [new file with mode: 0644]
board/karo/tx28/tx28.c [new file with mode: 0644]
board/karo/tx28/u-boot.bd [new file with mode: 0644]
board/karo/tx48/Makefile [new file with mode: 0644]
board/karo/tx48/config.mk [new file with mode: 0644]
board/karo/tx48/spl.c [new file with mode: 0644]
board/karo/tx48/tx48.c [new file with mode: 0644]
board/karo/tx48/u-boot.lds [new file with mode: 0644]
board/karo/tx51/Makefile [new file with mode: 0644]
board/karo/tx51/config.mk [new file with mode: 0644]
board/karo/tx51/lowlevel_init.S [new file with mode: 0644]
board/karo/tx51/tx51.c [new file with mode: 0644]
board/karo/tx51/u-boot.lds [new file with mode: 0644]
board/karo/tx53/Makefile [new file with mode: 0644]
board/karo/tx53/config.mk [new file with mode: 0644]
board/karo/tx53/lowlevel_init.S [new file with mode: 0644]
board/karo/tx53/tx53.c [new file with mode: 0644]
board/karo/tx53/u-boot.lds [new file with mode: 0644]
board/karo/tx6/Makefile [new file with mode: 0644]
board/karo/tx6/config.mk [new file with mode: 0644]
board/karo/tx6/flash.c [new file with mode: 0644]
board/karo/tx6/lowlevel_init.S [new file with mode: 0644]
board/karo/tx6/tx6qdl.c [new file with mode: 0644]
board/karo/tx6/u-boot.lds [new file with mode: 0644]
board/ti/am335x/board.c
boards.cfg
common/Makefile
common/cmd_bootce.c [new file with mode: 0644]
common/cmd_nand.c
common/env_nand.c
common/fdt_support.c
common/lcd.c
common/main.c
common/spl/spl.c
common/spl/spl_nand.c
common/spl/spl_ymodem.c
common/xyzModem.c
config.mk
disk/part.c
doc/README.KARO [new file with mode: 0755]
doc/README.KARO-FDT [new file with mode: 0644]
doc/README.KARO-TX28 [new file with mode: 0644]
doc/README.KARO-TX48 [new file with mode: 0644]
doc/README.KARO-TX51 [new file with mode: 0644]
doc/README.KARO-TX53 [new file with mode: 0644]
drivers/dma/apbh_dma.c
drivers/gpio/Makefile
drivers/gpio/am33xx_gpio.c [new file with mode: 0644]
drivers/gpio/gpiolib.c [new file with mode: 0644]
drivers/mmc/fsl_esdhc.c
drivers/mtd/nand/Makefile
drivers/mtd/nand/am33xx_nand.c [new file with mode: 0644]
drivers/mtd/nand/mxc_nand.c
drivers/mtd/nand/mxs_nand.c
drivers/mtd/nand/nand_spl_simple.c
drivers/net/cpsw.c
drivers/net/fec_mxc.c
drivers/net/fec_mxc.h
drivers/video/Makefile
drivers/video/da8xx-fb.c
drivers/video/ipu_common.c
drivers/video/ipu_disp.c
drivers/video/ipu_regs.h
drivers/video/mxc_ipuv3_fb.c
drivers/watchdog/imx_watchdog.c
dts/Makefile
include/ahci.h
include/asm-generic/gpio.h
include/common.h
include/configs/triton320.h [new file with mode: 0644]
include/configs/tx28.h [new file with mode: 0644]
include/configs/tx48.h [new file with mode: 0644]
include/configs/tx51.h [new file with mode: 0644]
include/configs/tx53.h [new file with mode: 0644]
include/configs/tx6.h [new file with mode: 0644]
include/fsl_esdhc.h
include/ipu.h [moved from drivers/video/ipu.h with 62% similarity]
include/lcd.h
include/linux/mtd/bbm.h
include/mxcfb.h [moved from drivers/video/mxcfb.h with 100% similarity]
include/net.h
include/netdev.h
include/spl.h
include/wince.h [new file with mode: 0644]
lib/Makefile
net/Makefile
net/bootme.c [new file with mode: 0644]
net/bootp.c
net/bootp.h
net/eth.c
net/net.c
net/net_rand.h
tools/elftosb/COPYING [new file with mode: 0644]
tools/elftosb/ReadMe.txt [new file with mode: 0644]
tools/elftosb/bdfiles/basic_test_cmd.e [new file with mode: 0644]
tools/elftosb/bdfiles/complex.bd [new file with mode: 0644]
tools/elftosb/bdfiles/habtest.bd [new file with mode: 0644]
tools/elftosb/bdfiles/simple.e [new file with mode: 0644]
tools/elftosb/bdfiles/test_cmd.e [new file with mode: 0644]
tools/elftosb/common/AESKey.cpp [new file with mode: 0644]
tools/elftosb/common/AESKey.h [new file with mode: 0644]
tools/elftosb/common/Blob.cpp [new file with mode: 0644]
tools/elftosb/common/Blob.h [new file with mode: 0644]
tools/elftosb/common/BootImage.h [new file with mode: 0644]
tools/elftosb/common/DataSource.cpp [new file with mode: 0644]
tools/elftosb/common/DataSource.h [new file with mode: 0644]
tools/elftosb/common/DataSourceImager.cpp [new file with mode: 0644]
tools/elftosb/common/DataSourceImager.h [new file with mode: 0644]
tools/elftosb/common/DataTarget.cpp [new file with mode: 0644]
tools/elftosb/common/DataTarget.h [new file with mode: 0644]
tools/elftosb/common/ELF.h [new file with mode: 0644]
tools/elftosb/common/ELFSourceFile.cpp [new file with mode: 0644]
tools/elftosb/common/ELFSourceFile.h [new file with mode: 0644]
tools/elftosb/common/EncoreBootImage.cpp [new file with mode: 0644]
tools/elftosb/common/EncoreBootImage.h [new file with mode: 0644]
tools/elftosb/common/EndianUtilities.h [new file with mode: 0644]
tools/elftosb/common/EvalContext.cpp [new file with mode: 0644]
tools/elftosb/common/EvalContext.h [new file with mode: 0644]
tools/elftosb/common/ExcludesListMatcher.cpp [new file with mode: 0644]
tools/elftosb/common/ExcludesListMatcher.h [new file with mode: 0644]
tools/elftosb/common/GHSSecInfo.cpp [new file with mode: 0644]
tools/elftosb/common/GHSSecInfo.h [new file with mode: 0644]
tools/elftosb/common/GlobMatcher.cpp [new file with mode: 0644]
tools/elftosb/common/GlobMatcher.h [new file with mode: 0644]
tools/elftosb/common/HexValues.cpp [new file with mode: 0644]
tools/elftosb/common/HexValues.h [new file with mode: 0644]
tools/elftosb/common/IVTDataSource.cpp [new file with mode: 0644]
tools/elftosb/common/IVTDataSource.h [new file with mode: 0644]
tools/elftosb/common/Logging.cpp [new file with mode: 0644]
tools/elftosb/common/Logging.h [new file with mode: 0644]
tools/elftosb/common/Operation.cpp [new file with mode: 0644]
tools/elftosb/common/Operation.h [new file with mode: 0644]
tools/elftosb/common/OptionContext.h [new file with mode: 0644]
tools/elftosb/common/OptionDictionary.cpp [new file with mode: 0644]
tools/elftosb/common/OptionDictionary.h [new file with mode: 0644]
tools/elftosb/common/OutputSection.cpp [new file with mode: 0644]
tools/elftosb/common/OutputSection.h [new file with mode: 0644]
tools/elftosb/common/Random.cpp [new file with mode: 0644]
tools/elftosb/common/Random.h [new file with mode: 0644]
tools/elftosb/common/RijndaelCBCMAC.cpp [new file with mode: 0644]
tools/elftosb/common/RijndaelCBCMAC.h [new file with mode: 0644]
tools/elftosb/common/SHA1.cpp [new file with mode: 0644]
tools/elftosb/common/SHA1.h [new file with mode: 0644]
tools/elftosb/common/SRecordSourceFile.cpp [new file with mode: 0644]
tools/elftosb/common/SRecordSourceFile.h [new file with mode: 0644]
tools/elftosb/common/SearchPath.cpp [new file with mode: 0644]
tools/elftosb/common/SearchPath.h [new file with mode: 0644]
tools/elftosb/common/SourceFile.cpp [new file with mode: 0644]
tools/elftosb/common/SourceFile.h [new file with mode: 0644]
tools/elftosb/common/StELFFile.cpp [new file with mode: 0644]
tools/elftosb/common/StELFFile.h [new file with mode: 0644]
tools/elftosb/common/StExecutableImage.cpp [new file with mode: 0644]
tools/elftosb/common/StExecutableImage.h [new file with mode: 0644]
tools/elftosb/common/StSRecordFile.cpp [new file with mode: 0644]
tools/elftosb/common/StSRecordFile.h [new file with mode: 0644]
tools/elftosb/common/StringMatcher.h [new file with mode: 0644]
tools/elftosb/common/Value.cpp [new file with mode: 0644]
tools/elftosb/common/Value.h [new file with mode: 0644]
tools/elftosb/common/Version.cpp [new file with mode: 0644]
tools/elftosb/common/Version.h [new file with mode: 0644]
tools/elftosb/common/crc.cpp [new file with mode: 0644]
tools/elftosb/common/crc.h [new file with mode: 0644]
tools/elftosb/common/format_string.cpp [new file with mode: 0644]
tools/elftosb/common/format_string.h [new file with mode: 0644]
tools/elftosb/common/int_size.h [new file with mode: 0644]
tools/elftosb/common/options.cpp [new file with mode: 0644]
tools/elftosb/common/options.h [new file with mode: 0644]
tools/elftosb/common/rijndael.cpp [new file with mode: 0644]
tools/elftosb/common/rijndael.h [new file with mode: 0644]
tools/elftosb/common/smart_ptr.h [new file with mode: 0644]
tools/elftosb/common/stdafx.cpp [new file with mode: 0644]
tools/elftosb/common/stdafx.h [new file with mode: 0644]
tools/elftosb/elftosb.ccscc [new file with mode: 0644]
tools/elftosb/elftosb.xcodeproj/creed.mode1 [new file with mode: 0644]
tools/elftosb/elftosb.xcodeproj/creed.mode1v3 [new file with mode: 0644]
tools/elftosb/elftosb.xcodeproj/creed.pbxuser [new file with mode: 0644]
tools/elftosb/elftosb.xcodeproj/project.pbxproj [new file with mode: 0644]
tools/elftosb/elftosb2/BootImageGenerator.cpp [new file with mode: 0644]
tools/elftosb/elftosb2/BootImageGenerator.h [new file with mode: 0644]
tools/elftosb/elftosb2/ConversionController.cpp [new file with mode: 0644]
tools/elftosb/elftosb2/ConversionController.h [new file with mode: 0644]
tools/elftosb/elftosb2/Doxyfile [new file with mode: 0644]
tools/elftosb/elftosb2/ElftosbAST.cpp [new file with mode: 0644]
tools/elftosb/elftosb2/ElftosbAST.h [new file with mode: 0644]
tools/elftosb/elftosb2/ElftosbErrors.h [new file with mode: 0644]
tools/elftosb/elftosb2/ElftosbLexer.cpp [new file with mode: 0644]
tools/elftosb/elftosb2/ElftosbLexer.h [new file with mode: 0644]
tools/elftosb/elftosb2/EncoreBootImageGenerator.cpp [new file with mode: 0644]
tools/elftosb/elftosb2/EncoreBootImageGenerator.h [new file with mode: 0644]
tools/elftosb/elftosb2/FlexLexer.h [new file with mode: 0644]
tools/elftosb/elftosb2/elftosb.cpp [new file with mode: 0644]
tools/elftosb/elftosb2/elftosb2.vcproj [new file with mode: 0644]
tools/elftosb/elftosb2/elftosb_lexer.cpp [new file with mode: 0644]
tools/elftosb/elftosb2/elftosb_lexer.l [new file with mode: 0644]
tools/elftosb/elftosb2/elftosb_parser.tab.cpp [new file with mode: 0644]
tools/elftosb/elftosb2/elftosb_parser.tab.hpp [new file with mode: 0644]
tools/elftosb/elftosb2/elftosb_parser.y [new file with mode: 0644]
tools/elftosb/encryptgpk/encryptgpk.cpp [new file with mode: 0644]
tools/elftosb/encryptgpk/encryptgpk.vcproj [new file with mode: 0644]
tools/elftosb/keygen/Doxyfile [new file with mode: 0644]
tools/elftosb/keygen/keygen.cpp [new file with mode: 0644]
tools/elftosb/keygen/keygen.vcproj [new file with mode: 0644]
tools/elftosb/makefile [new file with mode: 0644]
tools/elftosb/makefile.rules [new file with mode: 0644]
tools/elftosb/sbtool/Doxyfile [new file with mode: 0644]
tools/elftosb/sbtool/EncoreBootImageReader.cpp [new file with mode: 0644]
tools/elftosb/sbtool/EncoreBootImageReader.h [new file with mode: 0644]
tools/elftosb/sbtool/sbtool.cpp [new file with mode: 0644]
tools/elftosb/sbtool/sbtool.vcproj [new file with mode: 0644]
tools/elftosb/stdafx.h [new file with mode: 0644]
tools/elftosb/test_elftosb.bat [new file with mode: 0644]
tools/elftosb/test_elftosb.sh [new file with mode: 0755]
tools/elftosb/test_files/hello_NOR_arm [new file with mode: 0644]
tools/elftosb/test_files/hello_NOR_arm.map [new file with mode: 0644]
tools/elftosb/test_files/hello_NOR_mixed [new file with mode: 0644]
tools/elftosb/test_files/hello_NOR_mixed.map [new file with mode: 0644]
tools/elftosb/test_files/hello_NOR_thumb [new file with mode: 0644]
tools/elftosb/test_files/hello_NOR_thumb.map [new file with mode: 0644]
tools/elftosb/test_files/hostlink [new file with mode: 0644]
tools/elftosb/test_files/player_linfix.elf [new file with mode: 0644]
tools/elftosb/test_files/plugin_complex [new file with mode: 0644]
tools/elftosb/test_files/plugin_hello [new file with mode: 0644]
tools/elftosb/test_files/redboot_gcc.srec [new file with mode: 0644]
tools/elftosb/test_files/rom_nand_ldr_profile [new file with mode: 0644]
tools/elftosb/test_files/sd_player_gcc [new file with mode: 0644]
tools/elftosb/test_files/sd_player_gcc.srec [new file with mode: 0644]
tools/elftosb/test_files/test0.key [new file with mode: 0644]
tools/elftosb/winsupport/unistd.h [new file with mode: 0644]
tools/gen_eth_addr.c
tools/logos/karo.bmp [new file with mode: 0644]

index 43e957a..7b59233 100644 (file)
@@ -69,6 +69,7 @@ patches-*
 # quilt's files
 patches
 series
+.pc
 
 # gdb files
 .gdb_history
index d545d30..b82feeb 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -14,8 +14,6 @@ U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 else
 U_BOOT_VERSION = $(VERSION).$(PATCHLEVEL)$(EXTRAVERSION)
 endif
-TIMESTAMP_FILE = $(obj)include/generated/timestamp_autogenerated.h
-VERSION_FILE = $(obj)include/generated/version_autogenerated.h
 
 HOSTARCH := $(shell uname -m | \
        sed -e s/i.86/x86/ \
@@ -92,7 +90,7 @@ export CHECKSRC
 ifneq ($(BUILD_DIR),)
 saved-output := $(BUILD_DIR)
 
-# Attempt to create a output directory.
+# Attempt to create an output directory.
 $(shell [ -d ${BUILD_DIR} ] || mkdir -p ${BUILD_DIR})
 
 # Verify if it was successful.
@@ -127,6 +125,9 @@ src :=
 endif
 export obj src
 
+TIMESTAMP_FILE = $(obj)include/generated/timestamp_autogenerated.h
+VERSION_FILE = $(obj)include/generated/version_autogenerated.h
+
 # Make sure CDPATH settings don't interfere
 unexport CDPATH
 
@@ -508,7 +509,7 @@ $(obj)u-boot.ais:       $(obj)spl/u-boot-spl.bin $(obj)u-boot.img
                        $(obj)u-boot.ais
 
 
-$(obj)u-boot.sb:       $(obj)u-boot.bin $(obj)spl/u-boot-spl.bin
+$(obj)u-boot.sb:       $(obj)u-boot $(obj)spl/u-boot-spl.bin elftosb
                $(MAKE) -C $(SRCTREE)/$(CPUDIR)/$(SOC)/ $(OBJTREE)/u-boot.sb
 
 # On x600 (SPEAr600) U-Boot is appended to U-Boot SPL.
@@ -609,6 +610,8 @@ $(obj)spl/u-boot-spl.bin:   $(SUBDIR_TOOLS) depend
 
 updater:
                $(MAKE) -C tools/updater all
+elftosb:
+               $(MAKE) -C $(SUBDIR_TOOLS)/elftosb all
 
 # Explicitly make _depend in subdirs containing multiple targets to prevent
 # parallel sub-makes creating .depend files simultaneously.
diff --git a/README b/README
index a5c3e8d..06c09c5 100644 (file)
--- a/README
+++ b/README
@@ -1804,6 +1804,17 @@ CBFS (Coreboot Filesystem) support
                4th and following
                BOOTP requests:         delay 0 ... 8 sec
 
+- BOOTP Random transaction ID:
+               CONFIG_BOOTP_RANDOM_ID
+
+               The standard algorithm to generate a DHCP/BOOTP transaction ID
+               by using the MAC address and the current time stamp may not
+               quite unlikely produce duplicate transaction IDs from different
+               clients in the same network. This option creates a transaction
+               ID using the rand() function. Provided that the RNG has been
+               seeded well, this should guarantee unique transaction IDs
+               always.
+
 - DHCP Advanced Options:
                You can fine tune the DHCP functionality by defining
                CONFIG_BOOTP_* symbols:
index 540a119..f9908e5 100644 (file)
@@ -39,7 +39,7 @@ ifneq ($(CONFIG_SPL_BUILD),y)
 ALL-$(CONFIG_SYS_THUMB_BUILD)  += checkthumb
 endif
 
-# Try if EABI is supported, else fall back to old API,
+# Try if EABI is supported, else fall back to old ABI,
 # i. e. for example:
 # - with ELDK 4.2 (EABI supported), use:
 #      -mabi=aapcs-linux
index e37e87b..174c8d3 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <lcd.h>
 #include <asm/system.h>
 
 static void cache_flush(void);
@@ -30,6 +31,14 @@ int cleanup_before_linux (void)
 
        disable_interrupts ();
 
+#ifdef CONFIG_LCD
+       {
+               /* switch off LCD panel */
+               lcd_panel_disable();
+               /* disable LCD controller */
+               lcd_disable();
+       }
+#endif
 
        /* turn off I/D-cache */
        icache_disable();
index 3d66892..b29227e 100644 (file)
@@ -31,8 +31,8 @@ ELFTOSB_TARGET-$(CONFIG_MX28) = imx28
 $(OBJTREE)/u-boot.bd: $(SRCTREE)/$(CPUDIR)/$(SOC)/u-boot-$(ELFTOSB_TARGET-y).bd
        sed "s@OBJTREE@$(OBJTREE)@g" $^ > $@
 
-$(OBJTREE)/u-boot.sb: $(OBJTREE)/u-boot.bin $(OBJTREE)/spl/u-boot-spl.bin $(OBJTREE)/u-boot.bd
-               elftosb -zf $(ELFTOSB_TARGET-y) -c $(OBJTREE)/u-boot.bd -o $(OBJTREE)/u-boot.sb
+$(OBJTREE)/u-boot.sb: $(OBJTREE)/u-boot $(OBJTREE)/spl/u-boot-spl $(OBJTREE)/u-boot.bd
+               $(TOPDIR)/tools/elftosb/bld/linux/elftosb -V -zf $(ELFTOSB_TARGET-y) -c $(OBJTREE)/u-boot.bd -o $(OBJTREE)/u-boot.sb
 
 #########################################################################
 
index 365542f..b00e404 100644 (file)
@@ -26,6 +26,31 @@ DECLARE_GLOBAL_DATA_PTR;
 /* Lowlevel init isn't used on i.MX28, so just have a dummy here */
 inline void lowlevel_init(void) {}
 
+#define BOOT_CAUSE_MASK                (RTC_PERSISTENT0_EXTERNAL_RESET |       \
+                               RTC_PERSISTENT0_ALARM_WAKE |            \
+                               RTC_PERSISTENT0_THERMAL_RESET)
+
+static int wait_rtc_stat(u32 mask)
+{
+       int timeout = 5000;
+       u32 val;
+       struct mxs_rtc_regs *rtc_regs = (void *)MXS_RTC_BASE;
+       u32 old_val = readl(&rtc_regs->hw_rtc_stat);
+
+       debug("stat=%x\n", old_val);
+
+       while ((val = readl(&rtc_regs->hw_rtc_stat)) & mask) {
+               if (val != old_val) {
+                       old_val = val;
+                       debug("stat: %x -> %x\n", old_val, val);
+               }
+               udelay(1);
+               if (timeout-- < 0)
+                       break;
+       }
+       return !!(readl(&rtc_regs->hw_rtc_stat) & mask);
+}
+
 void reset_cpu(ulong ignored) __attribute__((noreturn));
 
 void reset_cpu(ulong ignored)
@@ -34,6 +59,7 @@ void reset_cpu(ulong ignored)
                (struct mxs_rtc_regs *)MXS_RTC_BASE;
        struct mxs_lcdif_regs *lcdif_regs =
                (struct mxs_lcdif_regs *)MXS_LCDIF_BASE;
+       u32 reg;
 
        /*
         * Shut down the LCD controller as it interferes with BootROM boot mode
@@ -41,7 +67,13 @@ void reset_cpu(ulong ignored)
         */
        writel(LCDIF_CTRL_RUN, &lcdif_regs->hw_lcdif_ctrl_clr);
 
-       /* Wait 1 uS before doing the actual watchdog reset */
+       reg = readl(&rtc_regs->hw_rtc_persistent0);
+       if (reg & BOOT_CAUSE_MASK) {
+               writel(reg & ~BOOT_CAUSE_MASK, &rtc_regs->hw_rtc_persistent0);
+               wait_rtc_stat(RTC_STAT_NEW_REGS_PERSISTENT0);
+       }
+
+       /* Wait 1 mS before doing the actual watchdog reset */
        writel(1, &rtc_regs->hw_rtc_watchdog);
        writel(RTC_CTRL_WATCHDOGEN, &rtc_regs->hw_rtc_ctrl_set);
 
@@ -96,6 +128,7 @@ int arch_misc_init(void)
 }
 #endif
 
+#ifdef CONFIG_ARCH_CPU_INIT
 int arch_cpu_init(void)
 {
        struct mxs_clkctrl_regs *clkctrl_regs =
@@ -129,6 +162,7 @@ int arch_cpu_init(void)
 
        return 0;
 }
+#endif
 
 #if defined(CONFIG_DISPLAY_CPUINFO)
 static const char *get_cpu_type(void)
@@ -223,13 +257,16 @@ int cpu_eth_init(bd_t *bis)
 
        udelay(10);
 
+       /*
+        * Enable pad output; must be done BEFORE enabling PLL
+        * according to i.MX28 Ref. Manual Rev. 1, 2010 p. 883
+        */
+       setbits_le32(&clkctrl_regs->hw_clkctrl_enet, CLKCTRL_ENET_CLK_OUT_EN);
+
        /* Gate on ENET PLL */
        writel(CLKCTRL_PLL2CTRL0_CLKGATE,
                &clkctrl_regs->hw_clkctrl_pll2ctrl0_clr);
 
-       /* Enable pad output */
-       setbits_le32(&clkctrl_regs->hw_clkctrl_enet, CLKCTRL_ENET_CLK_OUT_EN);
-
        return 0;
 }
 #endif
index 0392afd..74bc009 100644 (file)
  * takes a few seconds to roll. The boot doesn't take that long, so to keep the
  * code simple, it doesn't take rolling into consideration.
  */
+/*
+ * There's nothing to be taken into consideration for the rollover.
+ * Two's complement arithmetic used correctly does all that's needed
+ * automagically.
+ */
 void early_delay(int delay)
 {
        struct mxs_digctl_regs *digctl_regs =
                (struct mxs_digctl_regs *)MXS_DIGCTL_BASE;
+       u32 start = readl(&digctl_regs->hw_digctl_microseconds);
 
-       uint32_t st = readl(&digctl_regs->hw_digctl_microseconds);
-       st += delay;
-       while (st > readl(&digctl_regs->hw_digctl_microseconds))
-               ;
+       while (readl(&digctl_regs->hw_digctl_microseconds) - start < delay);
 }
 
 #define        MUX_CONFIG_BOOTMODE_PAD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
@@ -120,7 +123,7 @@ void mxs_common_spl_init(const iomux_cfg_t *iomux_setup,
        mxs_power_wait_pswitch();
 }
 
-/* Support aparatus */
+/* Support apparatus */
 inline void board_init_f(unsigned long bootflag)
 {
        for (;;)
index 3baf4dd..0dda760 100644 (file)
@@ -158,18 +158,17 @@ static void mxs_mem_init_clock(void)
        writeb(CLKCTRL_FRAC_CLKGATE,
                &clkctrl_regs->hw_clkctrl_frac0_clr[CLKCTRL_FRAC0_EMI]);
 
-       early_delay(11000);
 
        /* Set EMI clock divider for EMI clock to 411 / 2 = 205MHz */
        writel((2 << CLKCTRL_EMI_DIV_EMI_OFFSET) |
                (1 << CLKCTRL_EMI_DIV_XTAL_OFFSET),
                &clkctrl_regs->hw_clkctrl_emi);
+       while (readl(&clkctrl_regs->hw_clkctrl_emi) & CLKCTRL_EMI_BUSY_REF_EMI)
+               ;
 
        /* Unbypass EMI */
        writel(CLKCTRL_CLKSEQ_BYPASS_EMI,
                &clkctrl_regs->hw_clkctrl_clkseq_clr);
-
-       early_delay(10000);
 }
 
 static void mxs_mem_setup_cpu_and_hbus(void)
@@ -187,51 +186,56 @@ static void mxs_mem_setup_cpu_and_hbus(void)
                &clkctrl_regs->hw_clkctrl_clkseq_set);
 
        /* HBUS = 151MHz */
-       writel(CLKCTRL_HBUS_DIV_MASK, &clkctrl_regs->hw_clkctrl_hbus_set);
-       writel(((~3) << CLKCTRL_HBUS_DIV_OFFSET) & CLKCTRL_HBUS_DIV_MASK,
-               &clkctrl_regs->hw_clkctrl_hbus_clr);
-
-       early_delay(10000);
+       clrsetbits_le32(&clkctrl_regs->hw_clkctrl_hbus,
+                       CLKCTRL_HBUS_DIV_MASK,
+                       3 << CLKCTRL_HBUS_DIV_OFFSET);
+       while (readl(&clkctrl_regs->hw_clkctrl_hbus) & CLKCTRL_HBUS_ASM_BUSY)
+               ;
 
        /* CPU clock divider = 1 */
        clrsetbits_le32(&clkctrl_regs->hw_clkctrl_cpu,
-                       CLKCTRL_CPU_DIV_CPU_MASK, 1);
+                       CLKCTRL_CPU_DIV_CPU_MASK,
+                       1 << CLKCTRL_CPU_DIV_CPU_OFFSET);
+       while (readl(&clkctrl_regs->hw_clkctrl_cpu) & CLKCTRL_CPU_BUSY_REF_CPU)
+               ;
 
        /* Disable CPU bypass */
        writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
                &clkctrl_regs->hw_clkctrl_clkseq_clr);
-
-       early_delay(15000);
 }
 
-static void mxs_mem_setup_vdda(void)
-{
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
+#define MEM_ABORT_FUNC
 
-       writel((0xc << POWER_VDDACTRL_TRG_OFFSET) |
-               (0x7 << POWER_VDDACTRL_BO_OFFSET_OFFSET) |
-               POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW,
-               &power_regs->hw_power_vddactrl);
+#ifdef MEM_ABORT_FUNC
+static void data_abort_memdetect_handler(void)
+{
+       asm volatile("subs pc, lr, #4");
 }
+#endif
 
 uint32_t mxs_mem_get_size(void)
 {
        uint32_t sz, da;
        uint32_t *vt = (uint32_t *)0x20;
-       /* The following is "subs pc, r14, #4", used as return from DABT. */
-       const uint32_t data_abort_memdetect_handler = 0xe25ef004;
 
        /* Replace the DABT handler. */
        da = vt[4];
-       vt[4] = data_abort_memdetect_handler;
-
-       sz = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
+#ifdef MEM_ABORT_FUNC
+       vt[4] = (uint32_t)data_abort_memdetect_handler;
+#else
+       vt[4] = (uint32_t)&&data_abort_memdetect_handler;
+#endif
+       sz = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE * 2);
 
        /* Restore the old DABT handler. */
        vt[4] = da;
 
        return sz;
+
+#ifndef MEM_ABORT_FUNC
+data_abort_memdetect_handler:
+       asm volatile("subs pc, lr, #4");
+#endif
 }
 
 #ifdef CONFIG_MX23
@@ -317,15 +321,11 @@ void mxs_mem_init(void)
 
        mxs_mem_init_clock();
 
-       mxs_mem_setup_vdda();
-
 #if defined(CONFIG_MX23)
        mx23_mem_init();
 #elif defined(CONFIG_MX28)
        mx28_mem_init();
 #endif
 
-       early_delay(10000);
-
        mxs_mem_setup_cpu_and_hbus();
 }
index e3b6cd9..ff4ff13 100644 (file)
 
 #include "mxs_init.h"
 
+#ifdef CONFIG_SYS_SPL_VDDD_VAL
+#define VDDD_VAL       CONFIG_SYS_SPL_VDDD_VAL
+#else
+#define VDDD_VAL       1350
+#endif
+#ifdef CONFIG_SYS_SPL_VDDIO_VAL
+#define VDDIO_VAL      CONFIG_SYS_SPL_VDDIO_VAL
+#else
+#define VDDIO_VAL      3300
+#endif
+#ifdef CONFIG_SYS_SPL_VDDA_VAL
+#define VDDA_VAL       CONFIG_SYS_SPL_VDDA_VAL
+#else
+#define VDDA_VAL       1800
+#endif
+#ifdef CONFIG_SYS_SPL_VDDMEM_VAL
+#define VDDMEM_VAL     CONFIG_SYS_SPL_VDDMEM_VAL
+#else
+#define VDDMEM_VAL     1700
+#endif
+
+#ifdef CONFIG_SYS_SPL_VDDD_BO_VAL
+#define VDDD_BO_VAL    CONFIG_SYS_SPL_VDDD_BO_VAL
+#else
+#define VDDD_BO_VAL    150
+#endif
+#ifdef CONFIG_SYS_SPL_VDDIO_BO_VAL
+#define VDDIO_BO_VAL   CONFIG_SYS_SPL_VDDIO_BO_VAL
+#else
+#define VDDIO_BO_VAL   150
+#endif
+#ifdef CONFIG_SYS_SPL_VDDA_BO_VAL
+#define VDDA_BO_VAL    CONFIG_SYS_SPL_VDDA_BO_VAL
+#else
+#define VDDA_BO_VAL    175
+#endif
+#ifdef CONFIG_SYS_SPL_VDDMEM_BO_VAL
+#define VDDMEM_BO_VAL  CONFIG_SYS_SPL_VDDMEM_BO_VAL
+#else
+#define VDDMEM_BO_VAL  25
+#endif
+
+#ifdef CONFIG_SYS_SPL_BATT_BO_LEVEL
+#if CONFIG_SYS_SPL_BATT_BO_LEVEL < 2400 || CONFIG_SYS_SPL_BATT_BO_LEVEL > 3640
+#error CONFIG_SYS_SPL_BATT_BO_LEVEL out of range
+#endif
+#define BATT_BO_VAL    (((CONFIG_SYS_SPL_BATT_BO_LEVEL) - 2400) / 40)
+#else
+/* Brownout default at 3V */
+#define BATT_BO_VAL    ((3000 - 2400) / 40)
+#endif
+
+#ifdef CONFIG_SYS_SPL_FIXED_BATT_SUPPLY
+static const int fixed_batt_supply = 1;
+#else
+static const int fixed_batt_supply;
+#endif
+
+static struct mxs_power_regs *power_regs = (void *)MXS_POWER_BASE;
+
 static void mxs_power_clock2xtal(void)
 {
        struct mxs_clkctrl_regs *clkctrl_regs =
@@ -36,44 +96,49 @@ static void mxs_power_clock2pll(void)
                        CLKCTRL_CLKSEQ_BYPASS_CPU);
 }
 
-static void mxs_power_clear_auto_restart(void)
+static int mxs_power_wait_rtc_stat(u32 mask)
 {
-       struct mxs_rtc_regs *rtc_regs =
-               (struct mxs_rtc_regs *)MXS_RTC_BASE;
+       int timeout = 5000; /* 3 ms according to i.MX28 Ref. Manual */
+       u32 val;
+       struct mxs_rtc_regs *rtc_regs = (void *)MXS_RTC_BASE;
 
-       writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr);
-       while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST)
-               ;
+       while ((val = readl(&rtc_regs->hw_rtc_stat)) & mask) {
+               early_delay(1);
+               if (timeout-- < 0)
+                       break;
+       }
+       return !!(readl(&rtc_regs->hw_rtc_stat) & mask);
+}
 
-       writel(RTC_CTRL_CLKGATE, &rtc_regs->hw_rtc_ctrl_clr);
-       while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE)
-               ;
+static int mxs_power_set_auto_restart(int on)
+{
+       struct mxs_rtc_regs *rtc_regs = (void *)MXS_RTC_BASE;
 
        /*
         * Due to the hardware design bug of mx28 EVK-A
         * we need to set the AUTO_RESTART bit.
         */
-       if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART)
-               return;
+       if (mxs_power_wait_rtc_stat(RTC_STAT_STALE_REGS_PERSISTENT0))
+               return 1;
 
-       while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
-               ;
+       if ((!(readl(&rtc_regs->hw_rtc_persistent0) &
+                               RTC_PERSISTENT0_AUTO_RESTART) ^ !on) == 0)
+               return 0;
 
-       setbits_le32(&rtc_regs->hw_rtc_persistent0,
-                       RTC_PERSISTENT0_AUTO_RESTART);
-       writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_set);
-       writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_clr);
-       while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
-               ;
-       while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK)
-               ;
+       if (mxs_power_wait_rtc_stat(RTC_STAT_NEW_REGS_PERSISTENT0))
+               return 1;
+
+       clrsetbits_le32(&rtc_regs->hw_rtc_persistent0,
+                       !on * RTC_PERSISTENT0_AUTO_RESTART,
+                       !!on * RTC_PERSISTENT0_AUTO_RESTART);
+       if (mxs_power_wait_rtc_stat(RTC_STAT_NEW_REGS_PERSISTENT0))
+               return 1;
+
+       return 0;
 }
 
 static void mxs_power_set_linreg(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        /* Set linear regulator 25mV below switching converter */
        clrsetbits_le32(&power_regs->hw_power_vdddctrl,
                        POWER_VDDDCTRL_LINREG_OFFSET_MASK,
@@ -90,9 +155,8 @@ static void mxs_power_set_linreg(void)
 
 static int mxs_get_batt_volt(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t volt = readl(&power_regs->hw_power_battmonitor);
+
        volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
        volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
        volt *= 8;
@@ -106,8 +170,6 @@ static int mxs_is_batt_ready(void)
 
 static int mxs_is_batt_good(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t volt = mxs_get_batt_volt();
 
        if ((volt >= 2400) && (volt <= 4300))
@@ -146,9 +208,6 @@ static int mxs_is_batt_good(void)
 
 static void mxs_power_setup_5v_detect(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        /* Start 5V detection */
        clrsetbits_le32(&power_regs->hw_power_5vctrl,
                        POWER_5VCTRL_VBUSVALID_TRSH_MASK,
@@ -158,9 +217,6 @@ static void mxs_power_setup_5v_detect(void)
 
 static void mxs_src_power_init(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        /* Improve efficieny and reduce transient ripple */
        writel(POWER_LOOPCTRL_TOGGLE_DIF | POWER_LOOPCTRL_EN_CM_HYST |
                POWER_LOOPCTRL_EN_DF_HYST, &power_regs->hw_power_loopctrl_set);
@@ -169,8 +225,14 @@ static void mxs_src_power_init(void)
                        POWER_DCLIMITS_POSLIMIT_BUCK_MASK,
                        0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET);
 
-       setbits_le32(&power_regs->hw_power_battmonitor,
+       if (!fixed_batt_supply) {
+               /* FIXME: This requires the LRADC to be set up! */
+               setbits_le32(&power_regs->hw_power_battmonitor,
                        POWER_BATTMONITOR_EN_BATADJ);
+       } else {
+               clrbits_le32(&power_regs->hw_power_battmonitor,
+                       POWER_BATTMONITOR_EN_BATADJ);
+       }
 
        /* Increase the RCSCALE level for quick DCDC response to dynamic load */
        clrsetbits_le32(&power_regs->hw_power_loopctrl,
@@ -181,17 +243,16 @@ static void mxs_src_power_init(void)
        clrsetbits_le32(&power_regs->hw_power_minpwr,
                        POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
 
-       /* 5V to battery handoff ... FIXME */
-       setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
-       early_delay(30);
-       clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+       if (!fixed_batt_supply) {
+               /* 5V to battery handoff ... FIXME */
+               setbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+               early_delay(30);
+               clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER);
+       }
 }
 
 static void mxs_power_init_4p2_params(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        /* Setup 4P2 parameters */
        clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
                POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK,
@@ -213,8 +274,6 @@ static void mxs_power_init_4p2_params(void)
 
 static void mxs_enable_4p2_dcdc_input(int xfer)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo;
        uint32_t prev_5v_brnout, prev_5v_droop;
 
@@ -309,8 +368,6 @@ static void mxs_enable_4p2_dcdc_input(int xfer)
 
 static void mxs_power_init_4p2_regulator(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t tmp, tmp2;
 
        setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2);
@@ -393,9 +450,6 @@ static void mxs_power_init_4p2_regulator(void)
 
 static void mxs_power_init_dcdc_4p2_source(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        if (!(readl(&power_regs->hw_power_dcdc4p2) &
                POWER_DCDC4P2_ENABLE_DCDC)) {
                hang();
@@ -415,8 +469,6 @@ static void mxs_power_init_dcdc_4p2_source(void)
 
 static void mxs_power_enable_4p2(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t vdddctrl, vddactrl, vddioctrl;
        uint32_t tmp;
 
@@ -474,9 +526,6 @@ static void mxs_power_enable_4p2(void)
 
 static void mxs_boot_valid_5v(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        /*
         * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
         * disconnect event. FIXME
@@ -497,8 +546,6 @@ static void mxs_boot_valid_5v(void)
 
 static void mxs_powerdown(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        writel(POWER_RESET_UNLOCK_KEY, &power_regs->hw_power_reset);
        writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
                &power_regs->hw_power_reset);
@@ -506,9 +553,6 @@ static void mxs_powerdown(void)
 
 static void mxs_batt_boot(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
        clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_ENABLE_DCDC);
 
@@ -550,8 +594,6 @@ static void mxs_batt_boot(void)
 
 static void mxs_handle_5v_conflict(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t tmp;
 
        setbits_le32(&power_regs->hw_power_vddioctrl,
@@ -586,9 +628,6 @@ static void mxs_handle_5v_conflict(void)
 
 static void mxs_5v_boot(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        /*
         * NOTE: In original IMX-Bootlets, this also checks for VBUSVALID,
         * but their implementation always returns 1 so we omit it here.
@@ -607,15 +646,42 @@ static void mxs_5v_boot(void)
        mxs_handle_5v_conflict();
 }
 
-static void mxs_init_batt_bo(void)
+static void mxs_fixed_batt_boot(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
+       writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
+
+       setbits_le32(&power_regs->hw_power_5vctrl,
+               POWER_5VCTRL_PWDN_5VBRNOUT |
+               POWER_5VCTRL_ENABLE_DCDC |
+               POWER_5VCTRL_ILIMIT_EQ_ZERO |
+               POWER_5VCTRL_PWDN_5VBRNOUT |
+               POWER_5VCTRL_PWD_CHARGE_4P2_MASK);
+
+       writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
+
+       clrbits_le32(&power_regs->hw_power_vdddctrl,
+               POWER_VDDDCTRL_DISABLE_FET |
+               POWER_VDDDCTRL_ENABLE_LINREG |
+               POWER_VDDDCTRL_DISABLE_STEPPING);
+
+       clrbits_le32(&power_regs->hw_power_vddactrl,
+               POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG |
+               POWER_VDDACTRL_DISABLE_STEPPING);
 
-       /* Brownout at 3V */
+       clrbits_le32(&power_regs->hw_power_vddioctrl,
+               POWER_VDDIOCTRL_DISABLE_FET |
+               POWER_VDDIOCTRL_DISABLE_STEPPING);
+
+       /* Stop 5V detection */
+       writel(POWER_5VCTRL_PWRUP_VBUS_CMPS,
+               &power_regs->hw_power_5vctrl_clr);
+}
+
+static void mxs_init_batt_bo(void)
+{
        clrsetbits_le32(&power_regs->hw_power_battmonitor,
                POWER_BATTMONITOR_BRWNOUT_LVL_MASK,
-               15 << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
+               BATT_BO_VAL << POWER_BATTMONITOR_BRWNOUT_LVL_OFFSET);
 
        writel(POWER_CTRL_BATT_BO_IRQ, &power_regs->hw_power_ctrl_clr);
        writel(POWER_CTRL_ENIRQ_BATT_BO, &power_regs->hw_power_ctrl_clr);
@@ -623,9 +689,6 @@ static void mxs_init_batt_bo(void)
 
 static void mxs_switch_vddd_to_dcdc_source(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        clrsetbits_le32(&power_regs->hw_power_vdddctrl,
                POWER_VDDDCTRL_LINREG_OFFSET_MASK,
                POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
@@ -637,33 +700,32 @@ static void mxs_switch_vddd_to_dcdc_source(void)
 
 static void mxs_power_configure_power_source(void)
 {
-       int batt_ready, batt_good;
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        struct mxs_lradc_regs *lradc_regs =
                (struct mxs_lradc_regs *)MXS_LRADC_BASE;
 
        mxs_src_power_init();
 
-       if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
-               batt_ready = mxs_is_batt_ready();
-               if (batt_ready) {
-                       /* 5V source detected, good battery detected. */
-                       mxs_batt_boot();
-               } else {
-                       batt_good = mxs_is_batt_good();
-                       if (!batt_good) {
-                               /* 5V source detected, bad battery detected. */
-                               writel(LRADC_CONVERSION_AUTOMATIC,
-                                       &lradc_regs->hw_lradc_conversion_clr);
-                               clrbits_le32(&power_regs->hw_power_battmonitor,
-                                       POWER_BATTMONITOR_BATT_VAL_MASK);
+       if (!fixed_batt_supply) {
+               if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+                       if (mxs_is_batt_ready()) {
+                               /* 5V source detected, good battery detected. */
+                               mxs_batt_boot();
+                       } else {
+                               if (!mxs_is_batt_good()) {
+                                       /* 5V source detected, bad battery detected. */
+                                       writel(LRADC_CONVERSION_AUTOMATIC,
+                                               &lradc_regs->hw_lradc_conversion_clr);
+                                       clrbits_le32(&power_regs->hw_power_battmonitor,
+                                               POWER_BATTMONITOR_BATT_VAL_MASK);
+                               }
+                               mxs_5v_boot();
                        }
-                       mxs_5v_boot();
+               } else {
+                       /* 5V not detected, booting from battery. */
+                       mxs_batt_boot();
                }
        } else {
-               /* 5V not detected, booting from battery. */
-               mxs_batt_boot();
+               mxs_fixed_batt_boot();
        }
 
        mxs_power_clock2pll();
@@ -681,9 +743,6 @@ static void mxs_power_configure_power_source(void)
 
 static void mxs_enable_output_rail_protection(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
                POWER_CTRL_VDDIO_BO_IRQ, &power_regs->hw_power_ctrl_clr);
 
@@ -699,11 +758,12 @@ static void mxs_enable_output_rail_protection(void)
 
 static int mxs_get_vddio_power_source_off(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t tmp;
 
-       if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+       if ((readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) &&
+               !(readl(&power_regs->hw_power_5vctrl) &
+                       POWER_5VCTRL_ILIMIT_EQ_ZERO)) {
+
                tmp = readl(&power_regs->hw_power_vddioctrl);
                if (tmp & POWER_VDDIOCTRL_DISABLE_FET) {
                        if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
@@ -722,13 +782,10 @@ static int mxs_get_vddio_power_source_off(void)
        }
 
        return 0;
-
 }
 
 static int mxs_get_vddd_power_source_off(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t tmp;
 
        tmp = readl(&power_regs->hw_power_vdddctrl);
@@ -756,10 +813,40 @@ static int mxs_get_vddd_power_source_off(void)
        return 0;
 }
 
+static int mxs_get_vdda_power_source_off(void)
+{
+       uint32_t tmp;
+
+       tmp = readl(&power_regs->hw_power_vddactrl);
+       if (tmp & POWER_VDDACTRL_DISABLE_FET) {
+               if ((tmp & POWER_VDDACTRL_LINREG_OFFSET_MASK) ==
+                       POWER_VDDACTRL_LINREG_OFFSET_0STEPS) {
+                       return 1;
+               }
+       }
+
+       if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
+               if (!(readl(&power_regs->hw_power_5vctrl) &
+                       POWER_5VCTRL_ENABLE_DCDC)) {
+                       return 1;
+               }
+       }
+
+       if (!(tmp & POWER_VDDACTRL_ENABLE_LINREG)) {
+               if ((tmp & POWER_VDDACTRL_LINREG_OFFSET_MASK) ==
+                       POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW) {
+                       return 1;
+               }
+       }
+
+       return 0;
+}
+
 struct mxs_vddx_cfg {
        uint32_t                *reg;
        uint8_t                 step_mV;
        uint16_t                lowest_mV;
+       uint16_t                highest_mV;
        int                     (*powered_by_linreg)(void);
        uint32_t                trg_mask;
        uint32_t                bo_irq;
@@ -768,15 +855,17 @@ struct mxs_vddx_cfg {
        uint32_t                bo_offset_offset;
 };
 
+#define POWER_REG(n)           &((struct mxs_power_regs *)MXS_POWER_BASE)->n
+
 static const struct mxs_vddx_cfg mxs_vddio_cfg = {
-       .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
-                                       hw_power_vddioctrl),
+       .reg                    = POWER_REG(hw_power_vddioctrl),
 #if defined(CONFIG_MX23)
        .step_mV                = 25,
 #else
        .step_mV                = 50,
 #endif
        .lowest_mV              = 2800,
+       .highest_mV             = 3600,
        .powered_by_linreg      = mxs_get_vddio_power_source_off,
        .trg_mask               = POWER_VDDIOCTRL_TRG_MASK,
        .bo_irq                 = POWER_CTRL_VDDIO_BO_IRQ,
@@ -786,10 +875,10 @@ static const struct mxs_vddx_cfg mxs_vddio_cfg = {
 };
 
 static const struct mxs_vddx_cfg mxs_vddd_cfg = {
-       .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
-                                       hw_power_vdddctrl),
+       .reg                    = POWER_REG(hw_power_vdddctrl),
        .step_mV                = 25,
        .lowest_mV              = 800,
+       .highest_mV             = 1575,
        .powered_by_linreg      = mxs_get_vddd_power_source_off,
        .trg_mask               = POWER_VDDDCTRL_TRG_MASK,
        .bo_irq                 = POWER_CTRL_VDDD_BO_IRQ,
@@ -798,12 +887,25 @@ static const struct mxs_vddx_cfg mxs_vddd_cfg = {
        .bo_offset_offset       = POWER_VDDDCTRL_BO_OFFSET_OFFSET,
 };
 
+static const struct mxs_vddx_cfg mxs_vdda_cfg = {
+       .reg                    = POWER_REG(hw_power_vddactrl),
+       .step_mV                = 50,
+       .lowest_mV              = 2800,
+       .highest_mV             = 3600,
+       .powered_by_linreg      = mxs_get_vdda_power_source_off,
+       .trg_mask               = POWER_VDDACTRL_TRG_MASK,
+       .bo_irq                 = POWER_CTRL_VDDA_BO_IRQ,
+       .bo_enirq               = POWER_CTRL_ENIRQ_VDDA_BO,
+       .bo_offset_mask         = POWER_VDDACTRL_BO_OFFSET_MASK,
+       .bo_offset_offset       = POWER_VDDACTRL_BO_OFFSET_OFFSET,
+};
+
 #ifdef CONFIG_MX23
 static const struct mxs_vddx_cfg mxs_vddmem_cfg = {
-       .reg                    = &(((struct mxs_power_regs *)MXS_POWER_BASE)->
-                                       hw_power_vddmemctrl),
+       .reg                    = POWER_REG(hw_power_vddmemctrl),
        .step_mV                = 50,
-       .lowest_mV              = 1700,
+       .lowest_mV              = 1500,
+       .highest_mV             = 1700,
        .powered_by_linreg      = NULL,
        .trg_mask               = POWER_VDDMEMCTRL_TRG_MASK,
        .bo_irq                 = 0,
@@ -816,11 +918,14 @@ static const struct mxs_vddx_cfg mxs_vddmem_cfg = {
 static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
                                uint32_t new_target, uint32_t new_brownout)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
        uint32_t cur_target, diff, bo_int = 0;
-       uint32_t powered_by_linreg = 0;
-       int adjust_up, tmp;
+       int powered_by_linreg = 0;
+       int adjust_up;
+
+       if (new_target < cfg->lowest_mV)
+               new_target = cfg->lowest_mV;
+       if (new_target > cfg->highest_mV)
+               new_target = cfg->highest_mV;
 
        new_brownout = DIV_ROUND(new_target - new_brownout, cfg->step_mV);
 
@@ -858,13 +963,12 @@ static void mxs_power_set_vddx(const struct mxs_vddx_cfg *cfg,
 
                if (powered_by_linreg ||
                        (readl(&power_regs->hw_power_sts) &
-                               POWER_STS_VDD5V_GT_VDDIO))
+                               POWER_STS_VDD5V_GT_VDDIO)) {
                        early_delay(500);
-               else {
-                       for (;;) {
-                               tmp = readl(&power_regs->hw_power_sts);
-                               if (tmp & POWER_STS_DC_OK)
-                                       break;
+               } else {
+                       while (!(readl(&power_regs->hw_power_sts) &
+                                       POWER_STS_DC_OK)) {
+
                        }
                }
 
@@ -896,51 +1000,61 @@ static void mxs_setup_batt_detect(void)
 static void mxs_ungate_power(void)
 {
 #ifdef CONFIG_MX23
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        writel(POWER_CTRL_CLKGATE, &power_regs->hw_power_ctrl_clr);
 #endif
 }
 
+#ifdef CONFIG_CONFIG_MACH_MX28EVK
+#define auto_restart 1
+#else
+#define auto_restart 0
+#endif
+
 void mxs_power_init(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        mxs_ungate_power();
 
        mxs_power_clock2xtal();
-       mxs_power_clear_auto_restart();
+       if (mxs_power_set_auto_restart(auto_restart)) {
+               serial_puts("Inconsistent value in RTC_PERSISTENT0 register; power-on-reset required\n");
+       }
        mxs_power_set_linreg();
-       mxs_power_setup_5v_detect();
 
-       mxs_setup_batt_detect();
+       if (!fixed_batt_supply) {
+               mxs_power_setup_5v_detect();
+               mxs_setup_batt_detect();
+       }
 
        mxs_power_configure_power_source();
        mxs_enable_output_rail_protection();
 
-       mxs_power_set_vddx(&mxs_vddio_cfg, 3300, 3150);
-       mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000);
+       mxs_power_set_vddx(&mxs_vddio_cfg, VDDIO_VAL, VDDIO_BO_VAL);
+       mxs_power_set_vddx(&mxs_vddd_cfg, VDDD_VAL, VDDD_BO_VAL);
+       mxs_power_set_vddx(&mxs_vdda_cfg, VDDA_VAL, VDDA_BO_VAL);
 #ifdef CONFIG_MX23
-       mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700);
+       mxs_power_set_vddx(&mxs_vddmem_cfg, VDDMEM_VAL, VDDMEM_BO_VAL);
+
+       setbits_le32(&power_regs->hw_power_vddmemctrl,
+               POWER_VDDMEMCTRL_ENABLE_LINREG);
+       early_delay(500);
+       clrbits_le32(&power_regs->hw_power_vddmemctrl,
+               POWER_VDDMEMCTRL_ENABLE_ILIMIT);
+#else
+       clrbits_le32(&power_regs->hw_power_vddmemctrl,
+               POWER_VDDMEMCTRL_ENABLE_LINREG);
 #endif
        writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ |
                POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ |
                POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_BATT_BO_IRQ |
                POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
-
-       writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set);
-
-       early_delay(1000);
+       if (!fixed_batt_supply)
+               writel(POWER_5VCTRL_PWDN_5VBRNOUT,
+                       &power_regs->hw_power_5vctrl_set);
 }
 
 #ifdef CONFIG_SPL_MXS_PSWITCH_WAIT
 void mxs_power_wait_pswitch(void)
 {
-       struct mxs_power_regs *power_regs =
-               (struct mxs_power_regs *)MXS_POWER_BASE;
-
        while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK))
                ;
 }
index 9b49ef4..20693e2 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define timestamp (gd->arch.tbl)
-#define lastdec (gd->arch.lastinc)
+/* Enable this to verify that the code can correctly
+ * handle the timer rollover
+ */
+/* #define DEBUG_TIMER_WRAP */
+
+#ifdef DEBUG_TIMER_WRAP
+/*
+ * Let the timer wrap 15 seconds after start to catch misbehaving
+ * timer related code early
+ */
+#define TIMER_START            (-time_to_tick(15 * CONFIG_SYS_HZ))
+#else
+#define TIMER_START            0UL
+#endif
 
 /*
  * This driver uses 1kHz clock source.
@@ -42,12 +54,6 @@ static inline unsigned long time_to_tick(unsigned long time)
        return time * (MXS_INCREMENTER_HZ / CONFIG_SYS_HZ);
 }
 
-/* Calculate how many ticks happen in "us" microseconds */
-static inline unsigned long us_to_tick(unsigned long us)
-{
-       return (us * MXS_INCREMENTER_HZ) / 1000000;
-}
-
 int timer_init(void)
 {
        struct mxs_timrot_regs *timrot_regs =
@@ -75,38 +81,60 @@ int timer_init(void)
        writel(TIMER_LOAD_VAL, &timrot_regs->hw_timrot_fixed_count0);
 #endif
 
+#ifndef DEBUG_TIMER_WRAP
+       /* Set fixed_count to maximum value */
+       writel(TIMER_LOAD_VAL, &timrot_regs->hw_timrot_fixed_count0);
+#else
+       /* Set fixed_count so that the counter will wrap after 20 seconds */
+       writel(20 * MXS_INCREMENTER_HZ,
+               &timrot_regs->hw_timrot_fixed_count0);
+       gd->arch.lastinc = TIMER_LOAD_VAL - 20 * MXS_INCREMENTER_HZ;
+#endif
+#ifdef DEBUG_TIMER_WRAP
+       /* Make the usec counter roll over 30 seconds after startup */
+       writel(-30000000, MXS_HW_DIGCTL_MICROSECONDS);
+#endif
+       writel(TIMROT_TIMCTRLn_UPDATE,
+               &timrot_regs->hw_timrot_timctrl0_clr);
+#ifdef DEBUG_TIMER_WRAP
+       /* Set fixed_count to maximal value for subsequent loads */
+       writel(TIMER_LOAD_VAL, &timrot_regs->hw_timrot_fixed_count0);
+#endif
+       gd->arch.timer_rate_hz = MXS_INCREMENTER_HZ;
+       gd->arch.tbl = TIMER_START;
+       gd->arch.tbu = 0;
        return 0;
 }
 
+/* Note: This function works correctly for TIMER_LOAD_VAL == 0xffffffff!
+ * The rollover is handled automagically due to the properties of
+ * two's complement arithmetic.
+ * For any other value of TIMER_LOAD_VAL the calculations would have
+ * to be done modulus(TIMER_LOAD_VAL + 1).
+ */
 unsigned long long get_ticks(void)
 {
        struct mxs_timrot_regs *timrot_regs =
                (struct mxs_timrot_regs *)MXS_TIMROT_BASE;
-       uint32_t now;
-
-       /* Current tick value */
+       unsigned long now;
 #if defined(CONFIG_MX23)
        /* Upper bits are the valid ones. */
        now = readl(&timrot_regs->hw_timrot_timcount0) >>
                TIMROT_RUNNING_COUNTn_RUNNING_COUNT_OFFSET;
-#elif defined(CONFIG_MX28)
-       now = readl(&timrot_regs->hw_timrot_running_count0);
+#else
+       /* The timer is counting down, so subtract the register value from
+        * the counter period length (implicitly 2^32) to get an incrementing
+        * timestamp
+        */
+       now = -readl(&timrot_regs->hw_timrot_running_count0);
 #endif
+       ulong inc = now - gd->arch.lastinc;
 
-       if (lastdec >= now) {
-               /*
-                * normal mode (non roll)
-                * move stamp forward with absolut diff ticks
-                */
-               timestamp += (lastdec - now);
-       } else {
-               /* we have rollover of decrementer */
-               timestamp += (TIMER_LOAD_VAL - now) + lastdec;
-
-       }
-       lastdec = now;
-
-       return timestamp;
+       if (gd->arch.tbl + inc < gd->arch.tbl)
+               gd->arch.tbu++;
+       gd->arch.tbl += inc;
+       gd->arch.lastinc = now;
+       return ((unsigned long long)gd->arch.tbu << 32) | gd->arch.tbl;
 }
 
 ulong get_timer_masked(void)
@@ -116,7 +144,8 @@ ulong get_timer_masked(void)
 
 ulong get_timer(ulong base)
 {
-       return get_timer_masked() - base;
+       /* NOTE: time_to_tick(base) is required to correctly handle rollover! */
+       return tick_to_time(get_ticks() - time_to_tick(base));
 }
 
 /* We use the HW_DIGCTL_MICROSECONDS register for sub-millisecond timer. */
@@ -124,36 +153,19 @@ ulong get_timer(ulong base)
 
 void __udelay(unsigned long usec)
 {
-       uint32_t old, new, incr;
-       uint32_t counter = 0;
-
-       old = readl(MXS_HW_DIGCTL_MICROSECONDS);
-
-       while (counter < usec) {
-               new = readl(MXS_HW_DIGCTL_MICROSECONDS);
-
-               /* Check if the timer wrapped. */
-               if (new < old) {
-                       incr = 0xffffffff - old;
-                       incr += new;
-               } else {
-                       incr = new - old;
-               }
-
-               /*
-                * Check if we are close to the maximum time and the counter
-                * would wrap if incremented. If that's the case, break out
-                * from the loop as the requested delay time passed.
+       uint32_t start = readl(MXS_HW_DIGCTL_MICROSECONDS);
+
+       while (readl(MXS_HW_DIGCTL_MICROSECONDS) - start <= usec)
+               /* use '<=' to guarantee a delay of _at least_
+                * the given number of microseconds.
+                * No need for fancy rollover checks
+                * Two's complement arithmetic applied correctly
+                * does everything that's needed  automagically!
                 */
-               if (counter + incr < counter)
-                       break;
-
-               counter += incr;
-               old = new;
-       }
+               ;
 }
 
 ulong get_tbclk(void)
 {
-       return MXS_INCREMENTER_HZ;
+       return gd->arch.timer_rate_hz;
 }
index a5fa648..ee9cc75 100644 (file)
@@ -1,14 +1,14 @@
 sources {
-       u_boot_spl="OBJTREE/spl/u-boot-spl.bin";
-       u_boot="OBJTREE/u-boot.bin";
+       u_boot_spl="OBJTREE/spl/u-boot-spl";
+       u_boot="OBJTREE/u-boot";
 }
 
 section (0) {
-       load u_boot_spl > 0x0000;
-       load ivt (entry = 0x0014) > 0x8000;
+       load u_boot_spl;
+       load ivt (entry = u_boot_spl:reset) > 0x8000;
        hab call 0x8000;
 
-       load u_boot > 0x40000100;
-       load ivt (entry = 0x40000100) > 0x8000;
+       load u_boot;
+       load ivt (entry = u_boot:reset) > 0x8000;
        hab call 0x8000;
 }
index dbd1ec3..2db1d41 100644 (file)
@@ -17,6 +17,7 @@ COBJS += emif4.o
 COBJS  += board.o
 COBJS  += mux.o
 COBJS-$(CONFIG_NAND_OMAP_GPMC) += elm.o
+COBJS-$(CONFIG_NAND_AM33XX) += elm.o
 
 SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS))
index 07ab91c..5b3cefb 100644 (file)
@@ -43,6 +43,60 @@ static const struct gpio_bank gpio_bank_am33xx[4] = {
 
 const struct gpio_bank *const omap_gpio_bank = gpio_bank_am33xx;
 
+#ifdef CONFIG_HW_WATCHDOG
+void hw_watchdog_reset(void)
+{
+       struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
+       static int trg __attribute__((section(".data")));
+
+       switch (trg) {
+       case 0:
+       case 1:
+               if (readl(&wdtimer->wdtwwps) & (1 << 4))
+                       return;
+               writel(trg ? 0x5555 : 0xaaaa, &wdtimer->wdtwspr);
+               break;
+       case 2:
+               if (readl(&wdtimer->wdtwwps) & (1 << 2))
+                       return;
+               /* 10 sec timeout */
+               writel(-32768 * 10, &wdtimer->wdtwldr);
+
+               if (readl(&wdtimer->wdtwwps) & (1 << 0))
+                       return;
+               /* prescaler = 1 */
+               writel(0, &wdtimer->wdtwclr);
+               break;
+
+       case 3:
+       case 4:
+               /* enable watchdog */
+               if (readl(&wdtimer->wdtwwps) & (1 << 4))
+                       return;
+               writel((trg & 1) ? 0xBBBB : 0x4444, &wdtimer->wdtwspr);
+               break;
+
+       default:
+               /* retrigger watchdog */
+               if (readl(&wdtimer->wdtwwps) & (1 << 3))
+                       return;
+
+               writel(trg, &wdtimer->wdtwtgr);
+               trg ^= 0x2;
+               return;
+       }
+       trg++;
+}
+#endif
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+void enable_caches(void)
+{
+       /* Enable D-cache. I-cache is already enabled in start.S */
+       dcache_enable();
+}
+#endif
+
 #if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
 int cpu_mmc_init(bd_t *bis)
 {
index fb3fb43..5e37af3 100644 (file)
 #define CLK_DIV_MASK           0x1f
 #define CLK_DIV2_MASK          0x7f
 #define CLK_SEL_SHIFT          0x8
+#define CLK_MODE_MASK          0x7
 #define CLK_MODE_SEL           0x7
-#define CLK_MODE_MASK          0xfffffff8
-#define CLK_DIV_SEL            0xFFFFFFE0
-#define CPGMAC0_IDLE           0x30000
-#define DPLL_CLKDCOLDO_GATE_CTRL        0x300
+#define DPLL_CLKDCOLDO_GATE_CTRL 0x300
+
 
 #define OSC    (V_OSCK/1000000)
 
@@ -68,36 +67,35 @@ const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
 const struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL;
 const struct cm_rtc *cmrtc = (struct cm_rtc *)CM_RTC;
 
+#ifdef CONFIG_SPL_BUILD
+#define enable_clk(reg, val) __enable_clk(#reg, &reg, val)
+
+static void __enable_clk(const char *name, const void *reg, u32 mask)
+{
+       unsigned long timeout = 10000000;
+
+       writel(mask, reg);
+       while (readl(reg) != mask)
+               /* poor man's timeout, since timers not initialized */
+               if (timeout-- == 0)
+                       /* no error message, since console not yet available */
+                       break;
+}
+
 static void enable_interface_clocks(void)
 {
        /* Enable all the Interconnect Modules */
-       writel(PRCM_MOD_EN, &cmper->l3clkctrl);
-       while (readl(&cmper->l3clkctrl) != PRCM_MOD_EN)
-               ;
-
-       writel(PRCM_MOD_EN, &cmper->l4lsclkctrl);
-       while (readl(&cmper->l4lsclkctrl) != PRCM_MOD_EN)
-               ;
-
-       writel(PRCM_MOD_EN, &cmper->l4fwclkctrl);
-       while (readl(&cmper->l4fwclkctrl) != PRCM_MOD_EN)
-               ;
-
-       writel(PRCM_MOD_EN, &cmwkup->wkl4wkclkctrl);
-       while (readl(&cmwkup->wkl4wkclkctrl) != PRCM_MOD_EN)
-               ;
-
-       writel(PRCM_MOD_EN, &cmper->l3instrclkctrl);
-       while (readl(&cmper->l3instrclkctrl) != PRCM_MOD_EN)
-               ;
-
-       writel(PRCM_MOD_EN, &cmper->l4hsclkctrl);
-       while (readl(&cmper->l4hsclkctrl) != PRCM_MOD_EN)
-               ;
-
-       writel(PRCM_MOD_EN, &cmwkup->wkgpio0clkctrl);
-       while (readl(&cmwkup->wkgpio0clkctrl) != PRCM_MOD_EN)
-               ;
+       enable_clk(cmper->l3clkctrl, PRCM_MOD_EN);
+       enable_clk(cmper->l4lsclkctrl, PRCM_MOD_EN);
+       enable_clk(cmper->l4fwclkctrl, PRCM_MOD_EN);
+       enable_clk(cmwkup->wkl4wkclkctrl, PRCM_MOD_EN);
+       enable_clk(cmper->l3instrclkctrl, PRCM_MOD_EN);
+       enable_clk(cmper->l4hsclkctrl, PRCM_MOD_EN);
+#ifdef CONFIG_HW_WATCHDOG
+       enable_clk(cmwkup->wdtimer1ctrl, PRCM_MOD_EN);
+#endif
+       /* GPIO0 */
+       enable_clk(cmwkup->wkgpio0clkctrl, PRCM_MOD_EN);
 }
 
 /*
@@ -120,72 +118,50 @@ static void power_domain_wkup_transition(void)
 static void enable_per_clocks(void)
 {
        /* Enable the control module though RBL would have done it*/
-       writel(PRCM_MOD_EN, &cmwkup->wkctrlclkctrl);
-       while (readl(&cmwkup->wkctrlclkctrl) != PRCM_MOD_EN)
-               ;
-
-       /* Enable the module clock */
-       writel(PRCM_MOD_EN, &cmper->timer2clkctrl);
-       while (readl(&cmper->timer2clkctrl) != PRCM_MOD_EN)
-               ;
-
+       enable_clk(cmwkup->wkctrlclkctrl, PRCM_MOD_EN);
+       /* Enable the timer2 clock */
+       enable_clk(cmper->timer2clkctrl, PRCM_MOD_EN);
        /* Select the Master osc 24 MHZ as Timer2 clock source */
        writel(0x1, &cmdpll->clktimer2clk);
 
+#ifdef CONFIG_SYS_NS16550_COM1
        /* UART0 */
-       writel(PRCM_MOD_EN, &cmwkup->wkup_uart0ctrl);
-       while (readl(&cmwkup->wkup_uart0ctrl) != PRCM_MOD_EN)
-               ;
-
-       /* UART1 */
-#ifdef CONFIG_SERIAL2
-       writel(PRCM_MOD_EN, &cmper->uart1clkctrl);
-       while (readl(&cmper->uart1clkctrl) != PRCM_MOD_EN)
-               ;
-#endif /* CONFIG_SERIAL2 */
-
-       /* UART2 */
-#ifdef CONFIG_SERIAL3
-       writel(PRCM_MOD_EN, &cmper->uart2clkctrl);
-       while (readl(&cmper->uart2clkctrl) != PRCM_MOD_EN)
-               ;
-#endif /* CONFIG_SERIAL3 */
-
-       /* UART3 */
-#ifdef CONFIG_SERIAL4
-       writel(PRCM_MOD_EN, &cmper->uart3clkctrl);
-       while (readl(&cmper->uart3clkctrl) != PRCM_MOD_EN)
-               ;
-#endif /* CONFIG_SERIAL4 */
-
-       /* UART4 */
-#ifdef CONFIG_SERIAL5
-       writel(PRCM_MOD_EN, &cmper->uart4clkctrl);
-       while (readl(&cmper->uart4clkctrl) != PRCM_MOD_EN)
-               ;
-#endif /* CONFIG_SERIAL5 */
-
-       /* UART5 */
-#ifdef CONFIG_SERIAL6
-       writel(PRCM_MOD_EN, &cmper->uart5clkctrl);
-       while (readl(&cmper->uart5clkctrl) != PRCM_MOD_EN)
-               ;
-#endif /* CONFIG_SERIAL6 */
-
+       enable_clk(cmwkup->wkup_uart0ctrl, PRCM_MOD_EN);
+#endif
+#ifdef CONFIG_SYS_NS16550_COM2
+       enable_clk(cmper->uart1clkctrl, PRCM_MOD_EN);
+#endif
+#ifdef CONFIG_SYS_NS16550_COM3
+       enable_clk(cmper->uart2clkctrl, PRCM_MOD_EN);
+#endif
+#ifdef CONFIG_SYS_NS16550_COM4
+       enable_clk(cmper->uart3clkctrl, PRCM_MOD_EN);
+#endif
+#ifdef CONFIG_SYS_NS16550_COM5
+       enable_clk(cmper->uart4clkctrl, PRCM_MOD_EN);
+#endif
+#ifdef CONFIG_SYS_NS16550_COM6
+       enable_clk(cmper->uart5clkctrl, PRCM_MOD_EN);
+#endif
        /* GPMC */
-       writel(PRCM_MOD_EN, &cmper->gpmcclkctrl);
-       while (readl(&cmper->gpmcclkctrl) != PRCM_MOD_EN)
-               ;
+       enable_clk(cmper->gpmcclkctrl, PRCM_MOD_EN);
 
        /* ELM */
-       writel(PRCM_MOD_EN, &cmper->elmclkctrl);
-       while (readl(&cmper->elmclkctrl) != PRCM_MOD_EN)
-               ;
+       enable_clk(cmper->elmclkctrl, PRCM_MOD_EN);
 
-       /* MMC0*/
-       writel(PRCM_MOD_EN, &cmper->mmc0clkctrl);
-       while (readl(&cmper->mmc0clkctrl) != PRCM_MOD_EN)
-               ;
+       /* Ethernet */
+       enable_clk(cmper->cpswclkstctrl, PRCM_MOD_EN);
+       enable_clk(cmper->cpgmac0clkctrl, PRCM_MOD_EN);
+
+       /* MMC */
+#ifndef CONFIG_OMAP_MMC_DEV_0
+       enable_clk(cmper->mmc0clkctrl, PRCM_MOD_EN);
+#endif
+#ifdef CONFIG_OMAP_MMC_DEV_1
+       enable_clk(cmper->mmc1clkctrl, PRCM_MOD_EN);
+#endif
+       /* LCD */
+       enable_clk(cmper->lcdclkctrl, PRCM_MOD_EN);
 
        /* MMC1 */
        writel(PRCM_MOD_EN, &cmper->mmc1clkctrl);
@@ -193,50 +169,26 @@ static void enable_per_clocks(void)
                ;
 
        /* i2c0 */
-       writel(PRCM_MOD_EN, &cmwkup->wkup_i2c0ctrl);
-       while (readl(&cmwkup->wkup_i2c0ctrl) != PRCM_MOD_EN)
-               ;
+       enable_clk(cmwkup->wkup_i2c0ctrl, PRCM_MOD_EN);
 
-       /* gpio1 module */
-       writel(PRCM_MOD_EN, &cmper->gpio1clkctrl);
-       while (readl(&cmper->gpio1clkctrl) != PRCM_MOD_EN)
-               ;
-
-       /* gpio2 module */
-       writel(PRCM_MOD_EN, &cmper->gpio2clkctrl);
-       while (readl(&cmper->gpio2clkctrl) != PRCM_MOD_EN)
-               ;
-
-       /* gpio3 module */
-       writel(PRCM_MOD_EN, &cmper->gpio3clkctrl);
-       while (readl(&cmper->gpio3clkctrl) != PRCM_MOD_EN)
-               ;
+       /* GPIO1-3 */
+       enable_clk(cmper->gpio1clkctrl, PRCM_MOD_EN);
+       enable_clk(cmper->gpio2clkctrl, PRCM_MOD_EN);
+       enable_clk(cmper->gpio3clkctrl, PRCM_MOD_EN);
 
        /* i2c1 */
-       writel(PRCM_MOD_EN, &cmper->i2c1clkctrl);
-       while (readl(&cmper->i2c1clkctrl) != PRCM_MOD_EN)
-               ;
-
-       /* Ethernet */
-       writel(PRCM_MOD_EN, &cmper->cpgmac0clkctrl);
-       while ((readl(&cmper->cpgmac0clkctrl) & CPGMAC0_IDLE) != PRCM_FUNCTL)
-               ;
+       enable_clk(cmper->i2c1clkctrl, PRCM_MOD_EN);
 
        /* spi0 */
-       writel(PRCM_MOD_EN, &cmper->spi0clkctrl);
-       while (readl(&cmper->spi0clkctrl) != PRCM_MOD_EN)
-               ;
+       enable_clk(cmper->spi0clkctrl, PRCM_MOD_EN);
 
-       /* RTC */
-       writel(PRCM_MOD_EN, &cmrtc->rtcclkctrl);
-       while (readl(&cmrtc->rtcclkctrl) != PRCM_MOD_EN)
-               ;
+       /* rtc */
+       enable_clk(cmrtc->rtcclkctrl, PRCM_MOD_EN);
 
-       /* MUSB */
-       writel(PRCM_MOD_EN, &cmper->usb0clkctrl);
-       while (readl(&cmper->usb0clkctrl) != PRCM_MOD_EN)
-               ;
+       /* usb0 */
+       enable_clk(cmper->usb0clkctrl, PRCM_MOD_EN);
 }
+#endif /* CONFIG_SPL_BUILD */
 
 void mpu_pll_config_val(int mpull_m)
 {
@@ -251,27 +203,28 @@ void mpu_pll_config_val(int mpull_m)
        while (readl(&cmwkup->idlestdpllmpu) != ST_MN_BYPASS)
                ;
 
-       clksel = clksel & (~CLK_SEL_MASK);
-       clksel = clksel | ((mpull_m << CLK_SEL_SHIFT) | MPUPLL_N);
+       clksel &= ~CLK_SEL_MASK;
+       clksel |= (mpull_m << CLK_SEL_SHIFT) | MPUPLL_N;
        writel(clksel, &cmwkup->clkseldpllmpu);
 
-       div_m2 = div_m2 & ~CLK_DIV_MASK;
-       div_m2 = div_m2 | MPUPLL_M2;
+       div_m2 &= ~CLK_DIV_MASK;
+       div_m2 |= MPUPLL_M2;
        writel(div_m2, &cmwkup->divm2dpllmpu);
 
-       clkmode = clkmode | CLK_MODE_SEL;
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= CLK_MODE_SEL;
        writel(clkmode, &cmwkup->clkmoddpllmpu);
 
        while (readl(&cmwkup->idlestdpllmpu) != ST_DPLL_CLK)
                ;
 }
 
-static void mpu_pll_config(void)
+void mpu_pll_config(void)
 {
        mpu_pll_config_val(CONFIG_SYS_MPUCLK);
 }
 
-static void core_pll_config(void)
+static void core_pll_config_val(int m)
 {
        u32 clkmode, clksel, div_m4, div_m5, div_m6;
 
@@ -287,30 +240,36 @@ static void core_pll_config(void)
        while (readl(&cmwkup->idlestdpllcore) != ST_MN_BYPASS)
                ;
 
-       clksel = clksel & (~CLK_SEL_MASK);
-       clksel = clksel | ((COREPLL_M << CLK_SEL_SHIFT) | COREPLL_N);
+       clksel &= ~CLK_SEL_MASK;
+       clksel |= ((m << CLK_SEL_SHIFT) | COREPLL_N);
        writel(clksel, &cmwkup->clkseldpllcore);
 
-       div_m4 = div_m4 & ~CLK_DIV_MASK;
-       div_m4 = div_m4 | COREPLL_M4;
+       div_m4 &= ~CLK_DIV_MASK;
+       div_m4 |= COREPLL_M4;
        writel(div_m4, &cmwkup->divm4dpllcore);
 
-       div_m5 = div_m5 & ~CLK_DIV_MASK;
-       div_m5 = div_m5 | COREPLL_M5;
+       div_m5 &= ~CLK_DIV_MASK;
+       div_m5 |= COREPLL_M5;
        writel(div_m5, &cmwkup->divm5dpllcore);
 
-       div_m6 = div_m6 & ~CLK_DIV_MASK;
-       div_m6 = div_m6 | COREPLL_M6;
+       div_m6 &= ~CLK_DIV_MASK;
+       div_m6 |= COREPLL_M6;
        writel(div_m6, &cmwkup->divm6dpllcore);
 
-       clkmode = clkmode | CLK_MODE_SEL;
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= CLK_MODE_SEL;
        writel(clkmode, &cmwkup->clkmoddpllcore);
 
        while (readl(&cmwkup->idlestdpllcore) != ST_DPLL_CLK)
                ;
 }
 
-static void per_pll_config(void)
+static inline void core_pll_config(void)
+{
+       core_pll_config_val(COREPLL_M);
+}
+
+static void per_pll_config_val(int m)
 {
        u32 clkmode, clksel, div_m2;
 
@@ -324,15 +283,16 @@ static void per_pll_config(void)
        while (readl(&cmwkup->idlestdpllper) != ST_MN_BYPASS)
                ;
 
-       clksel = clksel & (~CLK_SEL_MASK);
-       clksel = clksel | ((PERPLL_M << CLK_SEL_SHIFT) | PERPLL_N);
+       clksel &= ~CLK_SEL_MASK;
+       clksel |= (m << CLK_SEL_SHIFT) | PERPLL_N;
        writel(clksel, &cmwkup->clkseldpllper);
 
-       div_m2 = div_m2 & ~CLK_DIV2_MASK;
-       div_m2 = div_m2 | PERPLL_M2;
+       div_m2 &= ~CLK_DIV2_MASK;
+       div_m2 |= PERPLL_M2;
        writel(div_m2, &cmwkup->divm2dpllper);
 
-       clkmode = clkmode | CLK_MODE_SEL;
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= CLK_MODE_SEL;
        writel(clkmode, &cmwkup->clkmoddpllper);
 
        while (readl(&cmwkup->idlestdpllper) != ST_DPLL_CLK)
@@ -341,6 +301,46 @@ static void per_pll_config(void)
        writel(DPLL_CLKDCOLDO_GATE_CTRL, &cmwkup->clkdcoldodpllper);
 }
 
+static inline void per_pll_config(void)
+{
+       per_pll_config_val(PERPLL_M);
+}
+
+static void disp_pll_config_val(int m)
+{
+       u32 clkmode, clksel, div_m2;
+
+       clkmode = readl(&cmwkup->clkmoddplldisp);
+       clksel = readl(&cmwkup->clkseldplldisp);
+       div_m2 = readl(&cmwkup->divm2dplldisp);
+
+       /* Set the PLL to bypass Mode */
+       writel(PLL_BYPASS_MODE, &cmwkup->clkmoddplldisp);
+
+       while (!(readl(&cmwkup->idlestdplldisp) & ST_MN_BYPASS))
+               ;
+
+       clksel &= ~CLK_SEL_MASK;
+       clksel |= (m << CLK_SEL_SHIFT) | DISPPLL_N;
+       writel(clksel, &cmwkup->clkseldplldisp);
+
+       div_m2 &= ~CLK_DIV2_MASK;
+       div_m2 |= DISPPLL_M2;
+       writel(div_m2, &cmwkup->divm2dplldisp);
+
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= CLK_MODE_SEL;
+       writel(clkmode, &cmwkup->clkmoddplldisp);
+
+       while (!(readl(&cmwkup->idlestdplldisp) & ST_DPLL_CLK))
+               ;
+}
+
+static inline void disp_pll_config(void)
+{
+       disp_pll_config_val(DISPPLL_M);
+}
+
 void ddr_pll_config(unsigned int ddrpll_m)
 {
        u32 clkmode, clksel, div_m2;
@@ -350,23 +350,24 @@ void ddr_pll_config(unsigned int ddrpll_m)
        div_m2 = readl(&cmwkup->divm2dpllddr);
 
        /* Set the PLL to bypass Mode */
-       clkmode = (clkmode & CLK_MODE_MASK) | PLL_BYPASS_MODE;
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= PLL_BYPASS_MODE;
        writel(clkmode, &cmwkup->clkmoddpllddr);
 
        /* Wait till bypass mode is enabled */
-       while ((readl(&cmwkup->idlestdpllddr) & ST_MN_BYPASS)
-                               != ST_MN_BYPASS)
+       while (!(readl(&cmwkup->idlestdpllddr) & ST_MN_BYPASS))
                ;
 
-       clksel = clksel & (~CLK_SEL_MASK);
-       clksel = clksel | ((ddrpll_m << CLK_SEL_SHIFT) | DDRPLL_N);
+       clksel &= ~CLK_SEL_MASK;
+       clksel |= (ddrpll_m << CLK_SEL_SHIFT) | DDRPLL_N;
        writel(clksel, &cmwkup->clkseldpllddr);
 
-       div_m2 = div_m2 & CLK_DIV_SEL;
-       div_m2 = div_m2 | DDRPLL_M2;
+       div_m2 &= ~CLK_DIV_MASK;
+       div_m2 |= DDRPLL_M2;
        writel(div_m2, &cmwkup->divm2dpllddr);
 
-       clkmode = (clkmode & CLK_MODE_MASK) | CLK_MODE_SEL;
+       clkmode &= ~CLK_MODE_MASK;
+       clkmode |= CLK_MODE_SEL;
        writel(clkmode, &cmwkup->clkmoddpllddr);
 
        /* Wait till dpll is locked */
@@ -374,6 +375,7 @@ void ddr_pll_config(unsigned int ddrpll_m)
                ;
 }
 
+#ifdef CONFIG_SPL_BUILD
 void enable_emif_clocks(void)
 {
        /* Enable the  EMIF_FW Functional clock */
@@ -393,6 +395,7 @@ void pll_init()
        mpu_pll_config();
        core_pll_config();
        per_pll_config();
+       disp_pll_config();
 
        /* Enable the required interconnect clocks */
        enable_interface_clocks();
@@ -403,3 +406,140 @@ void pll_init()
        /* Enable the required peripherals */
        enable_per_clocks();
 }
+#endif
+
+#define M(mn) (((mn) & CLK_SEL_MASK) >> CLK_SEL_SHIFT)
+#define N(mn) ((mn) & CLK_DIV2_MASK)
+
+unsigned long __clk_get_rate(u32 m_n, u32 div_m2)
+{
+       unsigned long rate;
+
+       div_m2 &= CLK_DIV_MASK;
+       debug("M=%u N=%u M2=%u\n", M(m_n), N(m_n), div_m2);
+       rate = V_OSCK / 1000 * M(m_n) / (N(m_n) + 1) / div_m2;
+       debug("CLK = %lu.%03luMHz\n", rate / 1000, rate % 1000);
+       return rate * 1000;
+}
+
+unsigned long lcdc_clk_rate(void)
+{
+       return clk_get_rate(cmwkup, disp);
+}
+
+unsigned long mpu_clk_rate(void)
+{
+       return clk_get_rate(cmwkup, mpu);
+}
+
+enum {
+       CLK_MPU_PLL,
+       CLK_CORE_PLL,
+       CLK_PER_PLL,
+       CLK_DISP_PLL,
+       CLK_GPMC,
+};
+
+static struct clk_lookup {
+       const char *name;
+       unsigned int index;
+} am33xx_clk_lookup[] = {
+       { "mpu", CLK_MPU_PLL, },
+       { "core", CLK_CORE_PLL, },
+       { "per", CLK_PER_PLL, },
+       { "lcdc", CLK_DISP_PLL, },
+       { "gpmc", CLK_GPMC, },
+};
+
+#define print_pll(dom, pll) {                          \
+       u32 __pll = clk_get_rate(dom, pll);             \
+       printf("%-12s %4d.%03d MHz\n", #pll,            \
+               __pll / 1000000, __pll / 1000 % 1000);  \
+       }
+
+#define print_pll2(dom, n, pll) {                      \
+       u32 __m_n = readl(&(dom)->clkseldpll##pll);     \
+       u32 __div = readl(&(dom)->divm##n##dpll##pll);  \
+       u32 __pll = __clk_get_rate(__m_n, __div);       \
+       printf("%-12s %4d.%03d MHz\n", #pll "_m" #n,    \
+               __pll / 1000000, __pll / 1000 % 1000);  \
+       }
+
+static void do_showclocks(void)
+{
+       print_pll(cmwkup, mpu);
+       print_pll2(cmwkup, 4, core);
+       print_pll2(cmwkup, 5, core);
+       print_pll2(cmwkup, 6, core);
+       print_pll(cmwkup, ddr);
+       print_pll(cmwkup, per);
+       print_pll(cmwkup, disp);
+}
+
+int do_clocks(cmd_tbl_t *cmdtp, int flag, int argc,
+       char *const argv[])
+{
+       int i;
+       unsigned long freq;
+       unsigned long __attribute__((unused)) ref = ~0UL;
+
+       if (argc < 2) {
+               do_showclocks();
+               return CMD_RET_SUCCESS;
+       } else if (argc == 2 || argc > 4) {
+               return CMD_RET_USAGE;
+       }
+
+       freq = simple_strtoul(argv[2], NULL, 0);
+       if (freq < 1000) {
+               printf("Invalid clock frequency %lu\n", freq);
+               return CMD_RET_FAILURE;
+       }
+       if (argc > 3) {
+               ref = simple_strtoul(argv[3], NULL, 0);
+       }
+       for (i = 0; i < ARRAY_SIZE(am33xx_clk_lookup); i++) {
+               if (strcasecmp(argv[1], am33xx_clk_lookup[i].name) == 0) {
+                       switch (am33xx_clk_lookup[i].index) {
+                       case CLK_MPU_PLL:
+                               mpu_pll_config_val(freq / 1000000);
+                               break;
+                       case CLK_CORE_PLL:
+                               core_pll_config_val(freq / 1000000);
+                               break;
+                       case CLK_PER_PLL:
+                               per_pll_config_val(freq / 1000000);
+                               break;
+                       case CLK_DISP_PLL:
+                               disp_pll_config_val(freq / 1000000);
+                               break;
+                       default:
+                               printf("Cannot change %s clock\n",
+                                       am33xx_clk_lookup[i].name);
+                               return CMD_RET_FAILURE;
+                       }
+
+                       printf("%s clock set to %lu.%03lu MHz\n",
+                               am33xx_clk_lookup[i].name,
+                               freq / 1000000, freq / 1000 % 1000);
+                       return CMD_RET_SUCCESS;
+               }
+       }
+       if (i == ARRAY_SIZE(am33xx_clk_lookup)) {
+               printf("clock %s not found; supported clocks are:\n", argv[1]);
+               for (i = 0; i < ARRAY_SIZE(am33xx_clk_lookup); i++) {
+                       printf("\t%s\n", am33xx_clk_lookup[i].name);
+               }
+       } else {
+               printf("Failed to set clock %s to %s MHz\n",
+                       argv[1], argv[2]);
+       }
+       return CMD_RET_FAILURE;
+}
+
+U_BOOT_CMD(
+       clocks, 4, 0, do_clocks,
+       "display/set clocks",
+       "                    - display clock settings\n"
+       "clocks <clkname> <freq>    - set clock <clkname> to <freq> Hz"
+);
index fa697c7..11cbac4 100644 (file)
  */
 static struct emif_reg_struct *emif_reg[2] = {
                                (struct emif_reg_struct *)EMIF4_0_CFG_BASE,
-                               (struct emif_reg_struct *)EMIF4_1_CFG_BASE};
+                               (struct emif_reg_struct *)EMIF4_1_CFG_BASE,
+};
 
 /**
  * Base addresses for DDR PHY cmd/data regs
  */
 static struct ddr_cmd_regs *ddr_cmd_reg[2] = {
                                (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR,
-                               (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR2};
+                               (struct ddr_cmd_regs *)DDR_PHY_CMD_ADDR2,
+};
 
 static struct ddr_data_regs *ddr_data_reg[2] = {
                                (struct ddr_data_regs *)DDR_PHY_DATA_ADDR,
-                               (struct ddr_data_regs *)DDR_PHY_DATA_ADDR2};
+                               (struct ddr_data_regs *)DDR_PHY_DATA_ADDR2,
+};
 
 /**
  * Base address for ddr io control instances
  */
-static struct ddr_cmdtctrl *ioctrl_reg = {
-                       (struct ddr_cmdtctrl *)DDR_CONTROL_BASE_ADDR};
+static struct ddr_cmdtctrl *ioctrl_reg =
+                               (struct ddr_cmdtctrl *)DDR_CONTROL_BASE_ADDR;
 
 /**
  * Configure SDRAM
@@ -49,7 +52,7 @@ void config_sdram(const struct emif_regs *regs, int nr)
                 */
                writel(0x2800, &emif_reg[nr]->emif_sdram_ref_ctrl);
                writel(regs->zq_config, &emif_reg[nr]->emif_zq_config);
-               writel(regs->sdram_config, &cstat->secure_emif_sdram_config);
+               writel(regs->sdram_config, &cstat->emif_sdram_config);
                writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
                writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
                writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
index 8f1d6af..b0b05f4 100644 (file)
 #include <asm/omap_gpmc.h>
 #include <asm/arch/elm.h>
 
-#define ELM_DEFAULT_POLY (0)
+#define ELM_DEFAULT_POLY 0
 
-struct elm *elm_cfg;
+/* make sure this variable does not end up in bss
+ * because that would corrupt the relocation section
+ * that is overlayed with the bss section
+ */
+static struct elm *elm_cfg __attribute__((section(".data")));
 
 /**
  * elm_load_syndromes - Load BCH syndromes based on nibble selection
@@ -34,58 +38,53 @@ struct elm *elm_cfg;
  */
 static void elm_load_syndromes(u8 *syndrome, u32 nibbles, u8 poly)
 {
-       u32 *ptr;
        u32 val;
+       struct  syndrome *sf = &elm_cfg->syndrome_fragments[poly];
 
        /* reg 0 */
-       ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[0];
        val = syndrome[0] | (syndrome[1] << 8) | (syndrome[2] << 16) |
                                (syndrome[3] << 24);
-       writel(val, ptr);
+       writel(val, &sf->syndrome_fragment_x[0]);
+
        /* reg 1 */
-       ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[1];
        val = syndrome[4] | (syndrome[5] << 8) | (syndrome[6] << 16) |
                                (syndrome[7] << 24);
-       writel(val, ptr);
+       writel(val, &sf->syndrome_fragment_x[1]);
 
        /* BCH 8-bit with 26 nibbles (4*8=32) */
        if (nibbles > 13) {
                /* reg 2 */
-               ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[2];
                val = syndrome[8] | (syndrome[9] << 8) | (syndrome[10] << 16) |
                                (syndrome[11] << 24);
-               writel(val, ptr);
+               writel(val, &sf->syndrome_fragment_x[2]);
+
                /* reg 3 */
-               ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[3];
-               val = syndrome[12] | (syndrome[13] << 8) |
-                       (syndrome[14] << 16) | (syndrome[15] << 24);
-               writel(val, ptr);
+               val = syndrome[12] | (syndrome[13] << 8) | (syndrome[14] << 16) |
+                               (syndrome[15] << 24);
+               writel(val, &sf->syndrome_fragment_x[3]);
        }
 
        /* BCH 16-bit with 52 nibbles (7*8=56) */
        if (nibbles > 26) {
                /* reg 4 */
-               ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[4];
-               val = syndrome[16] | (syndrome[17] << 8) |
-                       (syndrome[18] << 16) | (syndrome[19] << 24);
-               writel(val, ptr);
+               val = syndrome[16] | (syndrome[17] << 8) | (syndrome[18] << 16) |
+                               (syndrome[19] << 24);
+               writel(val, &sf->syndrome_fragment_x[4]);
 
                /* reg 5 */
-               ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[5];
-               val = syndrome[20] | (syndrome[21] << 8) |
-                       (syndrome[22] << 16) | (syndrome[23] << 24);
-               writel(val, ptr);
+               val = syndrome[20] | (syndrome[21] << 8) | (syndrome[22] << 16) |
+                               (syndrome[23] << 24);
+               writel(val, &sf->syndrome_fragment_x[5]);
 
                /* reg 6 */
-               ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6];
-               val = syndrome[24] | (syndrome[25] << 8) |
-                       (syndrome[26] << 16) | (syndrome[27] << 24);
-               writel(val, ptr);
+               val = syndrome[24] | (syndrome[25] << 8) | (syndrome[26] << 16) |
+                               (syndrome[27] << 24);
+               writel(val, &sf->syndrome_fragment_x[6]);
        }
 }
 
 /**
- * elm_check_errors - Check for BCH errors and return error locations
+ * elm_check_error - Check for BCH errors and return error locations
  * @syndrome: BCH syndrome
  * @nibbles:
  * @error_count: Returns number of errrors in the syndrome
@@ -107,14 +106,13 @@ int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count,
        /* start processing */
        writel((readl(&elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6])
                                | ELM_SYNDROME_FRAGMENT_6_SYNDROME_VALID),
-               &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6]);
+                       &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6]);
 
        /* wait for processing to complete */
-       while ((readl(&elm_cfg->irqstatus) & (0x1 << poly)) != 0x1)
-               ;
+       while (!(readl(&elm_cfg->irqstatus) & (0x1 << poly)));
        /* clear status */
-       writel((readl(&elm_cfg->irqstatus) (0x1 << poly)),
-                       &elm_cfg->irqstatus);
+       writel((readl(&elm_cfg->irqstatus) & ~(0x1 << poly)),
+               &elm_cfg->irqstatus);
 
        /* check if correctable */
        location_status = readl(&elm_cfg->error_location[poly].location_status);
@@ -123,12 +121,11 @@ int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count,
 
        /* get error count */
        *error_count = readl(&elm_cfg->error_location[poly].location_status) &
-                                       ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK;
+                                               ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK;
 
-       for (i = 0; i < *error_count; i++) {
+       for (i = 0; i < *error_count; i++)
                error_locations[i] =
                        readl(&elm_cfg->error_location[poly].error_location_x[i]);
-       }
 
        return 0;
 }
index f81c9a8..b1a1329 100644 (file)
@@ -20,8 +20,6 @@
 #include <asm/arch/sys_proto.h>
 #include <command.h>
 
-struct gpmc *gpmc_cfg;
-
 #if defined(CONFIG_CMD_NAND)
 static const u32 gpmc_m_nand[GPMC_MAX_REG] = {
        M_NAND_GPMC_CONFIG1,
@@ -60,8 +58,7 @@ void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
 void gpmc_init(void)
 {
        /* putting a blanket check on GPMC based on ZeBu for now */
-       gpmc_cfg = (struct gpmc *)GPMC_BASE;
-
+       struct gpmc *gpmc_cfg = (struct gpmc *)GPMC_BASE;
 #ifdef CONFIG_CMD_NAND
        const u32 *gpmc_config = NULL;
        u32 base = 0;
index 63afaaa..3f6d180 100644 (file)
@@ -63,7 +63,7 @@ u32 get_board_rev(void)
 u32 get_device_type(void)
 {
        int mode;
-       mode = readl(&cstat->statusreg) & (DEVICE_MASK);
+       mode = readl(&cstat->statusreg) & DEVICE_MASK;
        return mode >>= 8;
 }
 
@@ -73,17 +73,36 @@ u32 get_device_type(void)
 u32 get_sysboot_value(void)
 {
        int mode;
-       mode = readl(&cstat->statusreg) & (SYSBOOT_MASK);
+       mode = readl(&cstat->statusreg) & SYSBOOT_MASK;
        return mode;
 }
 
 #ifdef CONFIG_DISPLAY_CPUINFO
+#define SYSBOOT_FREQ_SHIFT     22
+#define SYSBOOT_FREQ_MASK      (3 << SYSBOOT_FREQ_SHIFT)
+
+static unsigned long bootfreqs[] = {
+       19200000,
+       24000000,
+       25000000,
+       26000000,
+};
+
+static u32 get_sysboot_freq(void)
+{
+       int mode;
+       mode = readl(&cstat->statusreg) & SYSBOOT_FREQ_MASK;
+       return bootfreqs[mode >> SYSBOOT_FREQ_SHIFT];
+}
+
 /**
  * Print CPU information
  */
 int print_cpuinfo(void)
 {
        char *cpu_s, *sec_s;
+       unsigned long clk;
+       const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
 
        switch (get_cpu_type()) {
        case AM335X:
@@ -94,7 +113,6 @@ int print_cpuinfo(void)
                break;
        default:
                cpu_s = "Unknown cpu type";
-               break;
        }
 
        switch (get_device_type()) {
@@ -116,6 +134,24 @@ int print_cpuinfo(void)
 
        printf("%s-%s rev %d\n", cpu_s, sec_s, get_cpu_rev());
 
+       clk = get_sysboot_freq();
+       printf("OSC clk: %4lu.%03lu MHz\n",
+               clk / 1000000, clk / 1000 % 1000);
+       clk = clk_get_rate(cmwkup, mpu);
+       printf("MPU clk: %4lu.%03lu MHz\n",
+               clk / 1000000, clk / 1000 % 1000);
+       clk = clk_get_rate(cmwkup, ddr);
+       printf("DDR clk: %4lu.%03lu MHz\n",
+               clk / 1000000, clk / 1000 % 1000);
+       clk = clk_get_rate(cmwkup, per);
+       printf("PER clk: %4lu.%03lu MHz\n",
+               clk / 1000000, clk / 1000 % 1000);
+#ifdef CONFIG_LCD
+       clk = clk_get_rate(cmwkup, disp);
+       printf("LCD clk: %4lu.%03lu MHz\n",
+               clk / 1000000, clk / 1000 % 1000);
+#endif
+
        return 0;
 }
 #endif /* CONFIG_DISPLAY_CPUINFO */
index bc5fc42..f7865bc 100644 (file)
@@ -220,16 +220,18 @@ static void v7_dcache_maint_range(u32 start, u32 stop, u32 range_op)
 /* Invalidate TLB */
 static void v7_inval_tlb(void)
 {
-       /* Invalidate entire unified TLB */
-       asm volatile ("mcr p15, 0, %0, c8, c7, 0" : : "r" (0));
-       /* Invalidate entire data TLB */
-       asm volatile ("mcr p15, 0, %0, c8, c6, 0" : : "r" (0));
-       /* Invalidate entire instruction TLB */
-       asm volatile ("mcr p15, 0, %0, c8, c5, 0" : : "r" (0));
-       /* Full system DSB - make sure that the invalidation is complete */
-       CP15DSB;
-       /* Full system ISB - make sure the instruction stream sees it */
-       CP15ISB;
+       asm volatile (
+               /* Invalidate entire unified TLB */
+               "mcr p15, 0, %0, c8, c7, 0\n"
+               /* Invalidate entire data TLB */
+               "mcr p15, 0, %0, c8, c6, 0\n"
+               /* Invalidate entire instruction TLB */
+               "mcr p15, 0, %0, c8, c5, 0\n"
+               /* Full system DSB - make sure that the invalidation is complete */
+               "mcr     p15, 0, %0, c7, c10, 4\n"
+               /* Full system ISB - make sure the instruction stream sees it */
+               "mcr     p15, 0, %0, c7, c5, 4\n"
+               : : "r" (0));
 }
 
 void invalidate_dcache_all(void)
@@ -337,16 +339,15 @@ void invalidate_icache_all(void)
         * Invalidate all instruction caches to PoU.
         * Also flushes branch target cache.
         */
-       asm volatile ("mcr p15, 0, %0, c7, c5, 0" : : "r" (0));
-
-       /* Invalidate entire branch predictor array */
-       asm volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0));
-
-       /* Full system DSB - make sure that the invalidation is complete */
-       CP15DSB;
-
-       /* ISB - make sure the instruction stream sees it */
-       CP15ISB;
+       asm volatile (
+               "mcr p15, 0, %0, c7, c5, 0\n"
+               /* Invalidate entire branch predictor array */
+               "mcr p15, 0, %0, c7, c5, 6\n"
+               /* Full system DSB - make sure that the invalidation is complete */
+               "mcr     p15, 0, %0, c7, c10, 4\n"
+               /* ISB - make sure the instruction stream sees it */
+               "mcr     p15, 0, %0, c7, c5, 4\n"
+               : : "r" (0));
 }
 #else
 void invalidate_icache_all(void)
index 01cdb7e..a5794c6 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <lcd.h>
 #include <asm/system.h>
 #include <asm/cache.h>
 #include <asm/armv7.h>
@@ -34,7 +35,15 @@ int cleanup_before_linux(void)
         */
 #ifndef CONFIG_SPL_BUILD
        disable_interrupts();
-#endif
+#ifdef CONFIG_LCD
+       {
+               /* switch off LCD panel */
+               lcd_panel_disable();
+               /* disable LCD controller */
+               lcd_disable();
+       }
+#endif /* CONFIG_LCD */
+#endif /* CONFIG_SPL_BUILD */
 
        /*
         * Turn off I-cache and invalidate it
index 82b2b86..cf477a9 100644 (file)
@@ -19,7 +19,11 @@ ENTRY(lowlevel_init)
        /*
         * Setup a temporary stack
         */
+#ifndef CONFIG_SPL_BUILD
        ldr     sp, =CONFIG_SYS_INIT_SP_ADDR
+#else
+       ldr     sp, =CONFIG_SPL_STACK
+#endif
        bic     sp, sp, #7 /* 8-byte alignment for ABI compliance */
 #ifdef CONFIG_SPL_BUILD
        ldr     r8, =gdata
index fbbb365..21fef9f 100644 (file)
@@ -46,9 +46,6 @@ struct mxc_pll_reg *mxc_plls[PLL_CLOCKS] = {
 #define EMI_DIV_MAX     8
 #define NFC_DIV_MAX     8
 
-#define MX5_CBCMR      0x00015154
-#define MX5_CBCDR      0x02888945
-
 struct fixed_pll_mfd {
        u32 ref_clk_hz;
        u32 mfd;
@@ -73,6 +70,93 @@ struct pll_param {
 
 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
 
+int clk_enable(struct clk *clk)
+{
+       int ret = 0;
+
+       if (!clk)
+               return 0;
+       if (clk->usecount++ == 0) {
+               ret = clk->enable(clk);
+               if (ret)
+                       clk->usecount--;
+       }
+       return ret;
+}
+
+void clk_disable(struct clk *clk)
+{
+       if (!clk)
+               return;
+
+       if (!(--clk->usecount)) {
+               if (clk->disable)
+                       clk->disable(clk);
+       }
+       if (clk->usecount < 0) {
+               printf("%s: clk %p underflow\n", __func__, clk);
+               hang();
+       }
+}
+
+int clk_get_usecount(struct clk *clk)
+{
+       if (clk == NULL)
+               return 0;
+
+       return clk->usecount;
+}
+
+u32 clk_get_rate(struct clk *clk)
+{
+       if (!clk)
+               return 0;
+
+       return clk->rate;
+}
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+       if (!clk)
+               return 0;
+
+       return clk->parent;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       if (clk && clk->set_rate)
+               clk->set_rate(clk, rate);
+       return clk->rate;
+}
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       if (clk == NULL || !clk->round_rate)
+               return 0;
+
+       return clk->round_rate(clk, rate);
+}
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+       debug("Setting parent of clk %p to %p (%p)\n", clk, parent,
+               clk ? clk->parent : NULL);
+
+       if (!clk || clk == parent)
+               return 0;
+
+       if (clk->set_parent) {
+               int ret;
+
+               ret = clk->set_parent(clk, parent);
+               if (ret)
+                       return ret;
+       }
+       clk->parent = parent;
+       return 0;
+}
+
 void set_usboh3_clk(void)
 {
        clrsetbits_le32(&mxc_ccm->cscmr1,
@@ -94,6 +178,34 @@ void enable_usboh3_clk(unsigned char enable)
                        MXC_CCM_CCGR2_USBOH3_60M(cg));
 }
 
+void ipu_clk_enable(void)
+{
+       /* IPU root clock derived from AXI B */
+       clrsetbits_le32(&mxc_ccm->cbcmr, MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_MASK,
+                       MXC_CCM_CBCMR_IPU_HSP_CLK_SEL(1));
+
+       setbits_le32(&mxc_ccm->CCGR5,
+               MXC_CCM_CCGR5_IPU(MXC_CCM_CCGR_CG_MASK));
+
+       /* Handshake with IPU when certain clock rates are changed. */
+       clrbits_le32(&mxc_ccm->ccdr, MXC_CCM_CCDR_IPU_HS_MASK);
+
+       /* Handshake with IPU when LPM is entered as its enabled. */
+       clrbits_le32(&mxc_ccm->clpcr, MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS);
+}
+
+void ipu_clk_disable(void)
+{
+       clrbits_le32(&mxc_ccm->CCGR5,
+               MXC_CCM_CCGR5_IPU(MXC_CCM_CCGR_CG_MASK));
+
+       /* Handshake with IPU when certain clock rates are changed. */
+       setbits_le32(&mxc_ccm->ccdr, MXC_CCM_CCDR_IPU_HS_MASK);
+
+       /* Handshake with IPU when LPM is entered as its enabled. */
+       setbits_le32(&mxc_ccm->clpcr, MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS);
+}
+
 #ifdef CONFIG_I2C_MXC
 /* i2c_num can be from 0, to 1 for i.MX51 and 2 for i.MX53 */
 int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
@@ -561,8 +673,7 @@ static int calc_pll_params(u32 ref, u32 target, struct pll_param *pll)
         */
        if (n_target < PLL_FREQ_MIN(ref) ||
                n_target > PLL_FREQ_MAX(ref)) {
-               printf("Targeted peripheral clock should be"
-                       "within [%d - %d]\n",
+               printf("Targeted peripheral clock should be within [%d - %d]\n",
                        PLL_FREQ_MIN(ref) / SZ_DEC_1M,
                        PLL_FREQ_MAX(ref) / SZ_DEC_1M);
                return -EINVAL;
@@ -628,71 +739,63 @@ static int calc_pll_params(u32 ref, u32 target, struct pll_param *pll)
 
 #define CHANGE_PLL_SETTINGS(pll, pd, fi, fn, fd) \
        {       \
-               writel(0x1232, &pll->ctrl);             \
-               writel(0x2, &pll->config);              \
-               writel((((pd) - 1) << 0) | ((fi) << 4), \
-                       &pll->op);                      \
-               writel(fn, &(pll->mfn));                \
-               writel((fd) - 1, &pll->mfd);            \
-               writel((((pd) - 1) << 0) | ((fi) << 4), \
-                       &pll->hfs_op);                  \
-               writel(fn, &pll->hfs_mfn);              \
-               writel((fd) - 1, &pll->hfs_mfd);        \
-               writel(0x1232, &pll->ctrl);             \
-               while (!readl(&pll->ctrl) & 0x1)        \
+               __raw_writel(0x1232, &pll->ctrl);               \
+               __raw_writel(0x2, &pll->config);                \
+               __raw_writel((((pd) - 1) << 0) | ((fi) << 4),   \
+                       &pll->op);                              \
+               __raw_writel(fn, &(pll->mfn));                  \
+               __raw_writel((fd) - 1, &pll->mfd);              \
+               __raw_writel((((pd) - 1) << 0) | ((fi) << 4),   \
+                       &pll->hfs_op);                          \
+               __raw_writel(fn, &pll->hfs_mfn);                \
+               __raw_writel((fd) - 1, &pll->hfs_mfd);          \
+               __raw_writel(0x1232, &pll->ctrl);               \
+               while (!__raw_readl(&pll->ctrl) & 0x1)          \
                        ;\
        }
 
 static int config_pll_clk(enum pll_clocks index, struct pll_param *pll_param)
 {
-       u32 ccsr = readl(&mxc_ccm->ccsr);
+       u32 ccsr = __raw_readl(&mxc_ccm->ccsr);
        struct mxc_pll_reg *pll = mxc_plls[index];
 
        switch (index) {
        case PLL1_CLOCK:
                /* Switch ARM to PLL2 clock */
-               writel(ccsr | MXC_CCM_CCSR_PLL1_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr | 0x4, &mxc_ccm->ccsr);
                CHANGE_PLL_SETTINGS(pll, pll_param->pd,
                                        pll_param->mfi, pll_param->mfn,
                                        pll_param->mfd);
                /* Switch back */
-               writel(ccsr & ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr & ~0x4, &mxc_ccm->ccsr);
                break;
        case PLL2_CLOCK:
                /* Switch to pll2 bypass clock */
-               writel(ccsr | MXC_CCM_CCSR_PLL2_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr | 0x2, &mxc_ccm->ccsr);
                CHANGE_PLL_SETTINGS(pll, pll_param->pd,
                                        pll_param->mfi, pll_param->mfn,
                                        pll_param->mfd);
                /* Switch back */
-               writel(ccsr & ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr & ~0x2, &mxc_ccm->ccsr);
                break;
        case PLL3_CLOCK:
                /* Switch to pll3 bypass clock */
-               writel(ccsr | MXC_CCM_CCSR_PLL3_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr | 0x1, &mxc_ccm->ccsr);
                CHANGE_PLL_SETTINGS(pll, pll_param->pd,
                                        pll_param->mfi, pll_param->mfn,
                                        pll_param->mfd);
                /* Switch back */
-               writel(ccsr & ~MXC_CCM_CCSR_PLL3_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr & ~0x1, &mxc_ccm->ccsr);
                break;
 #ifdef CONFIG_MX53
        case PLL4_CLOCK:
                /* Switch to pll4 bypass clock */
-               writel(ccsr | MXC_CCM_CCSR_PLL4_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr | 0x20, &mxc_ccm->ccsr);
                CHANGE_PLL_SETTINGS(pll, pll_param->pd,
                                        pll_param->mfi, pll_param->mfn,
                                        pll_param->mfd);
                /* Switch back */
-               writel(ccsr & ~MXC_CCM_CCSR_PLL4_SW_CLK_SEL,
-                               &mxc_ccm->ccsr);
+               __raw_writel(ccsr & ~0x20, &mxc_ccm->ccsr);
                break;
 #endif
        default:
@@ -713,7 +816,9 @@ static int config_core_clk(u32 ref, u32 freq)
        /* The case that periph uses PLL1 is not considered here */
        ret = calc_pll_params(ref, freq, &pll_param);
        if (ret != 0) {
-               printf("Error:Can't find pll parameters: %d\n", ret);
+               printf("Error: Can't find pll parameters for %u.%03uMHz ref %u.%03uMHz\n",
+                       freq / 1000000, freq / 1000 % 1000,
+                       ref / 1000000, ref / 1000 % 1000);
                return ret;
        }
 
@@ -902,28 +1007,38 @@ void mxc_set_sata_internal_clock(void)
 /*
  * Dump some core clockes.
  */
+#define pr_clk_val(c, v) {                                     \
+       printf("%-11s %3lu.%03lu MHz\n", #c,                    \
+               (v) / 1000000, (v) / 1000 % 1000);              \
+}
+
+#define pr_clk(c) {                                            \
+       unsigned long __clk = mxc_get_clock(MXC_##c##_CLK);     \
+       pr_clk_val(c, __clk);                                   \
+}
+
 int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-       u32 freq;
+       unsigned long freq;
 
        freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK);
-       printf("PLL1       %8d MHz\n", freq / 1000000);
+       pr_clk_val(PLL1, freq);
        freq = decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK);
-       printf("PLL2       %8d MHz\n", freq / 1000000);
+       pr_clk_val(PLL2, freq);
        freq = decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK);
-       printf("PLL3       %8d MHz\n", freq / 1000000);
+       pr_clk_val(PLL3, freq);
 #ifdef CONFIG_MX53
        freq = decode_pll(mxc_plls[PLL4_CLOCK], MXC_HCLK);
-       printf("PLL4       %8d MHz\n", freq / 1000000);
+       pr_clk_val(PLL4, freq);
 #endif
 
        printf("\n");
-       printf("AHB        %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000);
-       printf("IPG        %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000);
-       printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000);
-       printf("DDR        %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000);
+       pr_clk(AHB);
+       pr_clk(IPG);
+       pr_clk(IPG);
+       pr_clk(DDR);
 #ifdef CONFIG_MXC_SPI
-       printf("CSPI       %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000);
+       pr_clk(CSPI);
 #endif
        return 0;
 }
index 2d53669..3ccea67 100644 (file)
 #error "CPU_TYPE not defined"
 #endif
 
+#ifdef CONFIG_HW_WATCHDOG
+#define wdog_base      ((void *)WDOG1_BASE_ADDR)
+#define WDOG_WCR       0x00
+#define WCR_WDE                (1 << 2)
+#define WDOG_WSR       0x02
+
+void hw_watchdog_reset(void)
+{
+       if (readw(wdog_base + WDOG_WCR) & WCR_WDE) {
+               static u16 toggle = 0xaaaa;
+
+               writew(toggle, wdog_base + WDOG_WSR);
+               toggle ^= 0xffff;
+       }
+}
+#endif
+
 u32 get_cpu_rev(void)
 {
 #ifdef CONFIG_MX51
@@ -72,7 +89,7 @@ void enable_caches(void)
 #endif
 
 #if defined(CONFIG_FEC_MXC)
-void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+static void __imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
 {
        int i;
        struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
@@ -83,6 +100,10 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
        for (i = 0; i < 6; i++)
                mac[i] = readl(&fuse->mac_addr[i]) & 0xff;
 }
+
+void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
+       __attribute__((weak, alias("__imx_get_mac_from_fuse")));
+
 #endif
 
 void set_chipselect_size(int const cs_size)
@@ -116,6 +137,19 @@ void set_chipselect_size(int const cs_size)
        writel(reg, &iomuxc_regs->gpr1);
 }
 
+#if 1
+void cpu_cache_initialization(void)
+{
+       printf("Enabling L2 cache\n");
+       asm volatile(
+               "mrc 15, 0, r0, c1, c0, 1\n"
+               "orr r0, r0, #0x2\n"
+               "mcr 15, 0, r0, c1, c0, 1\n"
+               : : : "r0", "memory"
+               );
+}
+#endif
+
 #ifdef CONFIG_MX53
 void boot_mode_apply(unsigned cfg_val)
 {
diff --git a/arch/arm/cpu/armv7/mx6/asm-offsets.c b/arch/arm/cpu/armv7/mx6/asm-offsets.c
new file mode 100644 (file)
index 0000000..77699c2
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * Adapted from Linux v2.6.36 kernel: arch/powerpc/kernel/asm-offsets.c
+ *
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ *
+ * We use the technique used in the OSF Mach kernel code:
+ * generate asm statements containing #defines,
+ * compile this file to assembler, and then extract the
+ * #defines from the assembly-language output.
+ *
+ * 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 <asm/arch/imx-regs.h>
+#include <asm/arch/crm_regs.h>
+
+#include <linux/kbuild.h>
+
+int main(void)
+{
+       DEFINE(CCM_CCR, offsetof(struct mxc_ccm_reg, ccr));
+       DEFINE(CCM_CCDR, offsetof(struct mxc_ccm_reg, ccdr));
+       DEFINE(CCM_CSR, offsetof(struct mxc_ccm_reg, csr));
+       DEFINE(CCM_CCSR, offsetof(struct mxc_ccm_reg, ccsr));
+       DEFINE(CCM_CACRR, offsetof(struct mxc_ccm_reg, cacrr));
+       DEFINE(CCM_CBCDR, offsetof(struct mxc_ccm_reg, cbcdr));
+       DEFINE(CCM_CBCMR, offsetof(struct mxc_ccm_reg, cbcmr));
+       DEFINE(CCM_CSCMR1, offsetof(struct mxc_ccm_reg, cscmr1));
+       DEFINE(CCM_CSCMR2, offsetof(struct mxc_ccm_reg, cscmr2));
+       DEFINE(CCM_CSCDR1, offsetof(struct mxc_ccm_reg, cscdr1));
+       DEFINE(CCM_CS1CDR, offsetof(struct mxc_ccm_reg, cs1cdr));
+       DEFINE(CCM_CS2CDR, offsetof(struct mxc_ccm_reg, cs2cdr));
+       DEFINE(CCM_CDCDR, offsetof(struct mxc_ccm_reg, cdcdr));
+       DEFINE(CCM_CHSCCDR, offsetof(struct mxc_ccm_reg, chsccdr));
+       DEFINE(CCM_CSCDR2, offsetof(struct mxc_ccm_reg, cscdr2));
+       DEFINE(CCM_CSCDR3, offsetof(struct mxc_ccm_reg, cscdr3));
+       DEFINE(CCM_CSCDR4, offsetof(struct mxc_ccm_reg, cscdr4));
+       DEFINE(CCM_CDHIPR, offsetof(struct mxc_ccm_reg, cdhipr));
+       DEFINE(CCM_CDCR, offsetof(struct mxc_ccm_reg, cdcr));
+       DEFINE(CCM_CTOR, offsetof(struct mxc_ccm_reg, ctor));
+       DEFINE(CCM_CLPCR, offsetof(struct mxc_ccm_reg, clpcr));
+       DEFINE(CCM_CISR, offsetof(struct mxc_ccm_reg, cisr));
+       DEFINE(CCM_CIMR, offsetof(struct mxc_ccm_reg, cimr));
+       DEFINE(CCM_CCOSR, offsetof(struct mxc_ccm_reg, ccosr));
+       DEFINE(CCM_CGPR, offsetof(struct mxc_ccm_reg, cgpr));
+       DEFINE(CCM_CCGR0, offsetof(struct mxc_ccm_reg, CCGR0));
+       DEFINE(CCM_CCGR1, offsetof(struct mxc_ccm_reg, CCGR1));
+       DEFINE(CCM_CCGR2, offsetof(struct mxc_ccm_reg, CCGR2));
+       DEFINE(CCM_CCGR3, offsetof(struct mxc_ccm_reg, CCGR3));
+       DEFINE(CCM_CCGR4, offsetof(struct mxc_ccm_reg, CCGR4));
+       DEFINE(CCM_CCGR5, offsetof(struct mxc_ccm_reg, CCGR5));
+       DEFINE(CCM_CCGR6, offsetof(struct mxc_ccm_reg, CCGR6));
+       DEFINE(CCM_CCGR7, offsetof(struct mxc_ccm_reg, CCGR7));
+       DEFINE(CCM_CMEOR, offsetof(struct mxc_ccm_reg, cmeor));
+
+       DEFINE(ANATOP_PLL_ENET, offsetof(struct anatop_regs, pll_enet));
+       return 0;
+}
index 3bdb553..abe3c05 100644 (file)
 #include <asm/arch/sys_proto.h>
 
 enum pll_clocks {
-       PLL_SYS,        /* System PLL */
-       PLL_BUS,        /* System Bus PLL*/
-       PLL_USBOTG,     /* OTG USB PLL */
-       PLL_ENET,       /* ENET PLL */
+       PLL_ARM,        /* PLL1: ARM PLL */
+       PLL_BUS,        /* PLL2: System Bus PLL*/
+       PLL_USBOTG,     /* PLL3: OTG USB PLL */
+       PLL_AUDIO,      /* PLL4: Audio PLL */
+       PLL_VIDEO,      /* PLL5: Video PLL */
+       PLL_ENET,       /* PLL6: ENET PLL */
+       PLL_USB2,       /* PLL7: USB2 PLL */
+       PLL_MLB,        /* PLL8: MLB PLL */
 };
 
-struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+struct mxc_ccm_reg *const imx_ccm = (void *)CCM_BASE_ADDR;
+struct anatop_regs *const anatop = (void *)ANATOP_BASE_ADDR;
+
+int clk_enable(struct clk *clk)
+{
+       int ret = 0;
+
+       if (!clk)
+               return 0;
+       if (clk->usecount == 0) {
+debug("%s: Enabling %s clock\n", __func__, clk->name);
+               ret = clk->enable(clk);
+               if (ret)
+                       return ret;
+               clk->usecount++;
+       }
+       assert(clk->usecount > 0);
+       return ret;
+}
+
+void clk_disable(struct clk *clk)
+{
+       if (!clk)
+               return;
+
+       assert(clk->usecount > 0);
+       if (!(--clk->usecount)) {
+               if (clk->disable) {
+debug("%s: Disabling %s clock\n", __func__, clk->name);
+                       clk->disable(clk);
+               }
+       }
+}
+
+int clk_get_usecount(struct clk *clk)
+{
+       if (clk == NULL)
+               return 0;
+
+       return clk->usecount;
+}
+
+u32 clk_get_rate(struct clk *clk)
+{
+       if (!clk)
+               return 0;
+
+       return clk->rate;
+}
+
+struct clk *clk_get_parent(struct clk *clk)
+{
+       if (!clk)
+               return 0;
+
+       return clk->parent;
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+       if (clk && clk->set_rate)
+               clk->set_rate(clk, rate);
+       return clk->rate;
+}
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+       if (clk == NULL || !clk->round_rate)
+               return 0;
+
+       return clk->round_rate(clk, rate);
+}
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+       debug("Setting parent of clk %p to %p (%p)\n", clk, parent,
+               clk ? clk->parent : NULL);
+
+       if (!clk || clk == parent)
+               return 0;
+
+       if (clk->set_parent) {
+               int ret;
+
+               ret = clk->set_parent(clk, parent);
+               if (ret)
+                       return ret;
+       }
+       clk->parent = parent;
+       return 0;
+}
 
 #ifdef CONFIG_MXC_OCOTP
 void enable_ocotp_clk(unsigned char enable)
@@ -75,30 +169,64 @@ static u32 decode_pll(enum pll_clocks pll, u32 infreq)
        u32 div;
 
        switch (pll) {
-       case PLL_SYS:
-               div = __raw_readl(&imx_ccm->analog_pll_sys);
-               div &= BM_ANADIG_PLL_SYS_DIV_SELECT;
-
-               return infreq * (div >> 1);
+       case PLL_ARM:
+               div = __raw_readl(&anatop->pll_arm);
+               if (div & BM_ANADIG_PLL_ARM_BYPASS)
+                       /* Assume the bypass clock is always derived from OSC */
+                       return infreq;
+               div &= BM_ANADIG_PLL_ARM_DIV_SELECT;
+
+               return infreq * div / 2;
        case PLL_BUS:
-               div = __raw_readl(&imx_ccm->analog_pll_528);
-               div &= BM_ANADIG_PLL_528_DIV_SELECT;
+               div = __raw_readl(&anatop->pll_528);
+               if (div & BM_ANADIG_PLL_SYS_BYPASS)
+                       return infreq;
+               div &= BM_ANADIG_PLL_SYS_DIV_SELECT;
 
-               return infreq * (20 + (div << 1));
+               return infreq * (20 + div * 2);
        case PLL_USBOTG:
-               div = __raw_readl(&imx_ccm->analog_usb1_pll_480_ctrl);
+               div = __raw_readl(&anatop->usb1_pll_480_ctrl);
+               if (div & BM_ANADIG_USB1_PLL_480_CTRL_BYPASS)
+                       return infreq;
                div &= BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT;
 
-               return infreq * (20 + (div << 1));
+               return infreq * (20 + div * 2);
+       case PLL_AUDIO:
+               div = __raw_readl(&anatop->pll_audio);
+               if (div & BM_ANADIG_PLL_AUDIO_BYPASS)
+                       return infreq;
+               div &= BM_ANADIG_PLL_AUDIO_DIV_SELECT;
+
+               return infreq * div;
+       case PLL_VIDEO:
+               div = __raw_readl(&anatop->pll_video);
+               if (div & BM_ANADIG_PLL_VIDEO_BYPASS)
+                       return infreq;
+               div &= BM_ANADIG_PLL_VIDEO_DIV_SELECT;
+
+               return infreq * div;
        case PLL_ENET:
-               div = __raw_readl(&imx_ccm->analog_pll_enet);
+               div = __raw_readl(&anatop->pll_enet);
+               if (div & BM_ANADIG_PLL_ENET_BYPASS)
+                       return infreq;
                div &= BM_ANADIG_PLL_ENET_DIV_SELECT;
 
-               return (div == 3 ? 125000000 : 25000000 * (div << 1));
-       default:
+               return (div == 3 ? 125000000 : 25000000 * div * 2);
+       case PLL_USB2:
+               div = __raw_readl(&anatop->usb2_pll_480_ctrl);
+               if (div & BM_ANADIG_USB2_PLL_480_CTRL_BYPASS)
+                       return infreq;
+               div &= BM_ANADIG_USB2_PLL_480_CTRL_DIV_SELECT;
+
+               return infreq * (20 + div * 2);
+       case PLL_MLB:
+               div = __raw_readl(&anatop->pll_mlb);
+               if (div & BM_ANADIG_PLL_MLB_BYPASS)
+                       return infreq;
+               /* unknown external clock provided on MLB_CLK pin */
                return 0;
        }
-       /* NOTREACHED */
+       return 0;
 }
 
 static u32 get_mcu_main_clk(void)
@@ -108,7 +236,7 @@ static u32 get_mcu_main_clk(void)
        reg = __raw_readl(&imx_ccm->cacrr);
        reg &= MXC_CCM_CACRR_ARM_PODF_MASK;
        reg >>= MXC_CCM_CACRR_ARM_PODF_OFFSET;
-       freq = decode_pll(PLL_SYS, MXC_HCLK);
+       freq = decode_pll(PLL_ARM, MXC_HCLK);
 
        return freq / (reg + 1);
 }
@@ -131,8 +259,6 @@ u32 get_periph_clk(void)
                case 2:
                        freq = MXC_HCLK;
                        break;
-               default:
-                       break;
                }
        } else {
                reg = __raw_readl(&imx_ccm->cbcmr);
@@ -152,8 +278,6 @@ u32 get_periph_clk(void)
                case 3:
                        freq = PLL2_PFD2_DIV_FREQ;
                        break;
-               default:
-                       break;
                }
        }
 
@@ -254,6 +378,104 @@ static u32 get_emi_slow_clk(void)
        return root_freq / (emi_slow_pof + 1);
 }
 
+static u32 get_nfc_clk(void)
+{
+       u32 cs2cdr = __raw_readl(&imx_ccm->cs2cdr);
+       u32 podf = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK) >> MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET;
+       u32 pred = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK) >> MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET;
+       int nfc_clk_sel = (cs2cdr & MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK) >>
+               MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET;
+       u32 root_freq;
+
+       switch (nfc_clk_sel) {
+       case 0:
+               root_freq = PLL2_PFD0_FREQ;
+               break;
+       case 1:
+               root_freq = decode_pll(PLL_BUS, MXC_HCLK);
+               break;
+       case 2:
+               root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
+               break;
+       case 3:
+               root_freq = PLL2_PFD2_FREQ;
+               break;
+       }
+
+       return root_freq / (pred + 1) / (podf + 1);
+}
+
+#define CS2CDR_ENFC_MASK       (MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |    \
+                               MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |     \
+                               MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK)
+
+static int set_nfc_clk(u32 ref, u32 freq_khz)
+{
+       u32 cs2cdr = __raw_readl(&imx_ccm->cs2cdr);
+       u32 podf;
+       u32 pred;
+       int nfc_clk_sel;
+       u32 root_freq;
+       u32 min_err = ~0;
+       u32 nfc_val = ~0;
+       u32 freq = freq_khz * 1000;
+
+       for (nfc_clk_sel = 0; nfc_clk_sel < 4; nfc_clk_sel++) {
+               u32 act_freq;
+               u32 err;
+
+               if (ref < 4 && ref != nfc_clk_sel)
+                       continue;
+
+               switch (nfc_clk_sel) {
+               case 0:
+                       root_freq = PLL2_PFD0_FREQ;
+                       break;
+               case 1:
+                       root_freq = decode_pll(PLL_BUS, MXC_HCLK);
+                       break;
+               case 2:
+                       root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
+                       break;
+               case 3:
+                       root_freq = PLL2_PFD2_FREQ;
+                       break;
+               }
+               if (root_freq < freq)
+                       continue;
+
+               podf = min(DIV_ROUND_UP(root_freq, freq), 1 << 6);
+               pred = min(DIV_ROUND_UP(root_freq / podf, freq), 8);
+               act_freq = root_freq / pred / podf;
+               err = (freq - act_freq) * 100 / freq;
+               debug("root=%d[%u] freq=%u pred=%u podf=%u act=%u err=%d\n",
+                       nfc_clk_sel, root_freq, freq, pred, podf, act_freq, err);
+               if (act_freq > freq)
+                       continue;
+               if (err < min_err) {
+                       nfc_val = (podf - 1) << MXC_CCM_CS2CDR_ENFC_CLK_PODF_OFFSET;
+                       nfc_val |= (pred - 1) << MXC_CCM_CS2CDR_ENFC_CLK_PRED_OFFSET;
+                       nfc_val |= nfc_clk_sel << MXC_CCM_CS2CDR_ENFC_CLK_SEL_OFFSET;
+                       min_err = err;
+                       if (err == 0)
+                               break;
+               }
+       }
+
+       if (nfc_val == ~0 || min_err > 10)
+               return -EINVAL;
+
+       if ((cs2cdr & CS2CDR_ENFC_MASK) != nfc_val) {
+               debug("changing cs2cdr from %08x to %08x\n", cs2cdr,
+                       (cs2cdr & ~CS2CDR_ENFC_MASK) | nfc_val);
+               __raw_writel((cs2cdr & ~CS2CDR_ENFC_MASK) | nfc_val,
+                       &imx_ccm->cs2cdr);
+       } else {
+               debug("Leaving cs2cdr unchanged [%08x]\n", cs2cdr);
+       }
+       return 0;
+}
+
 #ifdef CONFIG_MX6SL
 static u32 get_mmdc_ch0_clk(void)
 {
@@ -348,10 +570,8 @@ u32 imx_get_fecclk(void)
 
 int enable_sata_clock(void)
 {
-       u32 reg = 0;
+       u32 reg;
        s32 timeout = 100000;
-       struct mxc_ccm_reg *const imx_ccm
-               = (struct mxc_ccm_reg *) CCM_BASE_ADDR;
 
        /* Enable sata clock */
        reg = readl(&imx_ccm->CCGR5); /* CCGR5 */
@@ -359,24 +579,52 @@ int enable_sata_clock(void)
        writel(reg, &imx_ccm->CCGR5);
 
        /* Enable PLLs */
-       reg = readl(&imx_ccm->analog_pll_enet);
-       reg &= ~BM_ANADIG_PLL_SYS_POWERDOWN;
-       writel(reg, &imx_ccm->analog_pll_enet);
-       reg |= BM_ANADIG_PLL_SYS_ENABLE;
+       reg = readl(&anatop->pll_enet);
+       reg &= ~BM_ANADIG_PLL_ENET_POWERDOWN;
+       writel(reg, &anatop->pll_enet);
+       reg |= BM_ANADIG_PLL_ENET_ENABLE;
        while (timeout--) {
-               if (readl(&imx_ccm->analog_pll_enet) & BM_ANADIG_PLL_SYS_LOCK)
+               if (readl(&anatop->pll_enet) & BM_ANADIG_PLL_ENET_LOCK)
                        break;
        }
        if (timeout <= 0)
                return -EIO;
-       reg &= ~BM_ANADIG_PLL_SYS_BYPASS;
-       writel(reg, &imx_ccm->analog_pll_enet);
+       reg &= ~BM_ANADIG_PLL_ENET_BYPASS;
+       writel(reg, &anatop->pll_enet);
        reg |= BM_ANADIG_PLL_ENET_ENABLE_SATA;
-       writel(reg, &imx_ccm->analog_pll_enet);
+       writel(reg, &anatop->pll_enet);
 
        return 0 ;
 }
 
+void ipu_clk_enable(void)
+{
+       u32 reg = readl(&imx_ccm->CCGR3);
+       reg |= MXC_CCM_CCGR3_IPU1_IPU_MASK;
+       writel(reg, &imx_ccm->CCGR3);
+}
+
+void ipu_clk_disable(void)
+{
+       u32 reg = readl(&imx_ccm->CCGR3);
+       reg &= ~MXC_CCM_CCGR3_IPU1_IPU_MASK;
+       writel(reg, &imx_ccm->CCGR3);
+}
+
+void ocotp_clk_enable(void)
+{
+       u32 reg = readl(&imx_ccm->CCGR2);
+       reg |= MXC_CCM_CCGR2_OCOTP_CTRL_MASK;
+       writel(reg, &imx_ccm->CCGR2);
+}
+
+void ocotp_clk_disable(void)
+{
+       u32 reg = readl(&imx_ccm->CCGR2);
+       reg &= ~MXC_CCM_CCGR2_OCOTP_CTRL_MASK;
+       writel(reg, &imx_ccm->CCGR2);
+}
+
 unsigned int mxc_get_clock(enum mxc_clock clk)
 {
        switch (clk) {
@@ -411,51 +659,281 @@ unsigned int mxc_get_clock(enum mxc_clock clk)
                return get_usdhc_clk(3);
        case MXC_SATA_CLK:
                return get_ahb_clk();
-       default:
-               break;
+       case MXC_NFC_CLK:
+               return get_nfc_clk();
        }
 
        return -1;
 }
 
+static inline int gcd(int m, int n)
+{
+       int t;
+       while (m > 0) {
+               if (n > m) {
+                       t = m;
+                       m = n;
+                       n = t;
+               } /* swap */
+               m -= n;
+       }
+       return n;
+}
+
+/* Config CPU clock */
+static int set_arm_clk(u32 ref, u32 freq_khz)
+{
+       int d;
+       int div = 0;
+       int mul = 0;
+       u32 min_err = ~0;
+       u32 reg;
+
+       if (freq_khz > ref / 1000 * 108 / 2 || freq_khz < ref / 1000 * 54 / 8 / 2) {
+               printf("Frequency %u.%03uMHz is out of range: %u.%03u..%u.%03u\n",
+                       freq_khz / 1000, freq_khz % 1000,
+                       54 * ref / 1000000 / 8 / 2, 54 * ref / 1000 / 8 / 2 % 1000,
+                       108 * ref / 1000000 / 2, 108 * ref / 1000 / 2 % 1000);
+               return -EINVAL;
+       }
+
+       for (d = DIV_ROUND_UP(648000, freq_khz); d <= 8; d++) {
+               int m = freq_khz * 2 * d / (ref / 1000);
+               u32 f;
+               u32 err;
+
+               if (m > 108) {
+                       debug("%s@%d: d=%d m=%d\n", __func__, __LINE__,
+                               d, m);
+                       break;
+               }
+
+               f = ref * m / d / 2;
+               if (f > freq_khz * 1000) {
+                       debug("%s@%d: d=%d m=%d f=%u freq=%u\n", __func__, __LINE__,
+                               d, m, f, freq_khz);
+                       if (--m < 54)
+                               return -EINVAL;
+                       f = ref * m / d / 2;
+               }
+               err = freq_khz * 1000 - f;
+               debug("%s@%d: d=%d m=%d f=%u freq=%u err=%d\n", __func__, __LINE__,
+                       d, m, f, freq_khz, err);
+               if (err < min_err) {
+                       mul = m;
+                       div = d;
+                       min_err = err;
+                       if (err == 0)
+                               break;
+               }
+       }
+       if (min_err == ~0)
+               return -EINVAL;
+       debug("Setting M=%3u D=%2u for %u.%03uMHz (actual: %u.%03uMHz)\n",
+               mul, div, freq_khz / 1000, freq_khz % 1000,
+               ref * mul / 2 / div / 1000000, ref * mul / 2 / div / 1000 % 1000);
+
+       reg = readl(&anatop->pll_arm);
+       debug("anadig_pll_arm=%08x -> %08x\n",
+               reg, (reg & ~0x7f) | mul);
+
+       reg |= 1 << 16;
+       writel(reg, &anatop->pll_arm); /* bypass PLL */
+
+       reg = (reg & ~0x7f) | mul;
+       writel(reg, &anatop->pll_arm);
+
+       writel(div - 1, &imx_ccm->cacrr);
+
+       reg &= ~(1 << 16);
+       writel(reg, &anatop->pll_arm); /* disable PLL bypass */
+
+       return 0;
+}
+
+/*
+ * This function assumes the expected core clock has to be changed by
+ * modifying the PLL. This is NOT true always but for most of the times,
+ * it is. So it assumes the PLL output freq is the same as the expected
+ * core clock (presc=1) unless the core clock is less than PLL_FREQ_MIN.
+ * In the latter case, it will try to increase the presc value until
+ * (presc*core_clk) is greater than PLL_FREQ_MIN. It then makes call to
+ * calc_pll_params() and obtains the values of PD, MFI,MFN, MFD based
+ * on the targeted PLL and reference input clock to the PLL. Lastly,
+ * it sets the register based on these values along with the dividers.
+ * Note 1) There is no value checking for the passed-in divider values
+ *         so the caller has to make sure those values are sensible.
+ *      2) Also adjust the NFC divider such that the NFC clock doesn't
+ *         exceed NFC_CLK_MAX.
+ *      3) IPU HSP clock is independent of AHB clock. Even it can go up to
+ *         177MHz for higher voltage, this function fixes the max to 133MHz.
+ *      4) This function should not have allowed diag_printf() calls since
+ *         the serial driver has been stoped. But leave then here to allow
+ *         easy debugging by NOT calling the cyg_hal_plf_serial_stop().
+ */
+int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk)
+{
+       int ret;
+
+       freq *= 1000;
+
+       switch (clk) {
+       case MXC_ARM_CLK:
+               ret = set_arm_clk(ref, freq);
+               break;
+
+       case MXC_NFC_CLK:
+               ret = set_nfc_clk(ref, freq);
+               break;
+
+       default:
+               printf("Warning: Unsupported or invalid clock type: %d\n",
+                       clk);
+               return -EINVAL;
+       }
+
+       return ret;
+}
+
 /*
- * Dump some core clockes.
+ * Dump some core clocks.
  */
-int do_mx6_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
-{
-       u32 freq;
-       freq = decode_pll(PLL_SYS, MXC_HCLK);
-       printf("PLL_SYS    %8d MHz\n", freq / 1000000);
-       freq = decode_pll(PLL_BUS, MXC_HCLK);
-       printf("PLL_BUS    %8d MHz\n", freq / 1000000);
-       freq = decode_pll(PLL_USBOTG, MXC_HCLK);
-       printf("PLL_OTG    %8d MHz\n", freq / 1000000);
-       freq = decode_pll(PLL_ENET, MXC_HCLK);
-       printf("PLL_NET    %8d MHz\n", freq / 1000000);
+#define print_pll(pll) {                               \
+       u32 __pll = decode_pll(pll, MXC_HCLK);          \
+       printf("%-12s %4d.%03d MHz\n", #pll,            \
+               __pll / 1000000, __pll / 1000 % 1000);  \
+       }
+
+#define MXC_IPG_PER_CLK        MXC_IPG_PERCLK
+
+#define print_clk(clk) {                               \
+       u32 __clk = mxc_get_clock(MXC_##clk##_CLK);     \
+       printf("%-12s %4d.%03d MHz\n", #clk,            \
+               __clk / 1000000, __clk / 1000 % 1000);  \
+       }
 
+#define print_pfd(pll, pfd)    {                                       \
+       u32 __pfd = readl(&anatop->pfd_##pll);                          \
+       if (__pfd & (0x80 << 8 * pfd)) {                                \
+               printf("PFD_%s[%d]      OFF\n", #pll, pfd);             \
+       } else {                                                        \
+               __pfd = (__pfd >> 8 * pfd) & 0x3f;                      \
+               printf("PFD_%s[%d]   %4d.%03d MHz\n", #pll, pfd,        \
+                       pll * 18 / __pfd,                               \
+                       pll * 18 * 1000 / __pfd % 1000);                \
+       }                                                               \
+}
+
+static void do_mx6_showclocks(void)
+{
+       print_pll(PLL_ARM);
+       print_pll(PLL_BUS);
+       print_pll(PLL_USBOTG);
+       print_pll(PLL_AUDIO);
+       print_pll(PLL_VIDEO);
+       print_pll(PLL_ENET);
+       print_pll(PLL_USB2);
        printf("\n");
-       printf("IPG        %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000);
-       printf("UART       %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000);
-#ifdef CONFIG_MXC_SPI
-       printf("CSPI       %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000);
-#endif
-       printf("AHB        %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000);
-       printf("AXI        %8d kHz\n", mxc_get_clock(MXC_AXI_CLK) / 1000);
-       printf("DDR        %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000);
-       printf("USDHC1     %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000);
-       printf("USDHC2     %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000);
-       printf("USDHC3     %8d kHz\n", mxc_get_clock(MXC_ESDHC3_CLK) / 1000);
-       printf("USDHC4     %8d kHz\n", mxc_get_clock(MXC_ESDHC4_CLK) / 1000);
-       printf("EMI SLOW   %8d kHz\n", mxc_get_clock(MXC_EMI_SLOW_CLK) / 1000);
-       printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000);
 
-       return 0;
+       print_pfd(480, 0);
+       print_pfd(480, 1);
+       print_pfd(480, 2);
+       print_pfd(480, 3);
+       print_pfd(528, 0);
+       print_pfd(528, 1);
+       print_pfd(528, 2);
+       print_pfd(528, 3);
+       printf("\n");
+
+       print_clk(IPG);
+       print_clk(UART);
+       print_clk(CSPI);
+       print_clk(AHB);
+       print_clk(AXI);
+       print_clk(DDR);
+       print_clk(ESDHC);
+       print_clk(ESDHC2);
+       print_clk(ESDHC3);
+       print_clk(ESDHC4);
+       print_clk(EMI_SLOW);
+       print_clk(NFC);
+       print_clk(IPG_PER);
+       print_clk(ARM);
+}
+
+static struct clk_lookup {
+       const char *name;
+       unsigned int index;
+} mx6_clk_lookup[] = {
+       { "arm", MXC_ARM_CLK, },
+       { "nfc", MXC_NFC_CLK, },
+};
+
+int do_clocks(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
+{
+       int i;
+       unsigned long freq;
+       unsigned long ref = ~0UL;
+
+       if (argc < 2) {
+               do_mx6_showclocks();
+               return CMD_RET_SUCCESS;
+       } else if (argc == 2 || argc > 4) {
+               return CMD_RET_USAGE;
+       }
+
+       freq = simple_strtoul(argv[2], NULL, 0);
+       if (freq == 0) {
+               printf("Invalid clock frequency %lu\n", freq);
+               return CMD_RET_FAILURE;
+       }
+       if (argc > 3) {
+               ref = simple_strtoul(argv[3], NULL, 0);
+       }
+       for (i = 0; i < ARRAY_SIZE(mx6_clk_lookup); i++) {
+               if (strcasecmp(argv[1], mx6_clk_lookup[i].name) == 0) {
+                       switch (mx6_clk_lookup[i].index) {
+                       case MXC_ARM_CLK:
+                               if (argc > 3)
+                                       return CMD_RET_USAGE;
+                               ref = CONFIG_SYS_MX6_HCLK;
+                               break;
+
+                       case MXC_NFC_CLK:
+                               if (argc > 3 && ref > 3) {
+                                       printf("Invalid clock selector value: %lu\n", ref);
+                                       return CMD_RET_FAILURE;
+                               }
+                               break;
+                       }
+                       printf("Setting %s clock to %lu MHz\n",
+                               mx6_clk_lookup[i].name, freq);
+                       if (mxc_set_clock(ref, freq, mx6_clk_lookup[i].index))
+                               break;
+                       freq = mxc_get_clock(mx6_clk_lookup[i].index);
+                       printf("%s clock set to %lu.%03lu MHz\n",
+                               mx6_clk_lookup[i].name,
+                               freq / 1000000, freq / 1000 % 1000);
+                       return CMD_RET_SUCCESS;
+               }
+       }
+       if (i == ARRAY_SIZE(mx6_clk_lookup)) {
+               printf("clock %s not found; supported clocks are:\n", argv[1]);
+               for (i = 0; i < ARRAY_SIZE(mx6_clk_lookup); i++) {
+                       printf("\t%s\n", mx6_clk_lookup[i].name);
+               }
+       } else {
+               printf("Failed to set clock %s to %s MHz\n",
+                       argv[1], argv[2]);
+       }
+       return CMD_RET_FAILURE;
 }
 
 /***************************************************/
 
 U_BOOT_CMD(
-       clocks, CONFIG_SYS_MAXARGS, 1, do_mx6_showclocks,
-       "display clocks",
-       ""
+       clocks, 4, 0, do_clocks,
+       "display/set clocks",
+       "                    - display clock settings\n"
+       "clocks <clkname> <freq>    - set clock <clkname> to <freq> MHz"
 );
index 32572ee..86b1525 100644 (file)
 #include <asm/errno.h>
 #include <asm/io.h>
 #include <asm/arch/imx-regs.h>
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/regs-ocotp.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/imx-common/boot_mode.h>
 #include <asm/imx-common/dma.h>
 #include <stdbool.h>
+#ifdef CONFIG_VIDEO_IPUV3
+#include <ipu.h>
+#endif
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define TEMPERATURE_MIN                        -40
+#define TEMPERATURE_HOT                        80
+#define TEMPERATURE_MAX                        125
+#define REG_VALUE_TO_CEL(ratio, raw) ((raw_n40c - raw) * 100 / ratio - 40)
+
+#define __data __attribute__((section(".data")))
 
 struct scu_regs {
        u32     ctrl;
@@ -25,6 +39,28 @@ struct scu_regs {
        u32     fpga_rev;
 };
 
+#ifdef CONFIG_HW_WATCHDOG
+#define wdog_base      ((void *)WDOG1_BASE_ADDR)
+#define WDOG_WCR       0x00
+#define WCR_WDE                (1 << 2)
+#define WDOG_WSR       0x02
+
+void hw_watchdog_reset(void)
+{
+       if (readw(wdog_base + WDOG_WCR) & WCR_WDE) {
+               static u16 toggle = 0xaaaa;
+               static int first = 1;
+
+               if (first) {
+                       printf("Watchdog active\n");
+                       first = 0;
+               }
+               writew(toggle, wdog_base + WDOG_WSR);
+               toggle ^= 0xffff;
+       }
+}
+#endif
+
 u32 get_cpu_rev(void)
 {
        struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
@@ -99,7 +135,7 @@ void init_aips(void)
  * Possible values are from 0.725V to 1.450V in steps of
  * 0.025V (25mV).
  */
-void set_vddsoc(u32 mv)
+static void set_vddsoc(u32 mv)
 {
        struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
        u32 val, reg = readl(&anatop->reg_core);
@@ -119,6 +155,116 @@ void set_vddsoc(u32 mv)
        writel(reg, &anatop->reg_core);
 }
 
+static u32 __data thermal_calib;
+
+int read_cpu_temperature(void)
+{
+       unsigned int reg, tmp, i;
+       unsigned int raw_25c, raw_hot, hot_temp, raw_n40c, ratio;
+       int temperature;
+       struct anatop_regs *const anatop = (void *)ANATOP_BASE_ADDR;
+       struct mx6_ocotp_regs *const ocotp_regs = (void *)OCOTP_BASE_ADDR;
+
+       if (!thermal_calib) {
+               ocotp_clk_enable();
+               writel(1, &ocotp_regs->hw_ocotp_read_ctrl);
+               thermal_calib = readl(&ocotp_regs->hw_ocotp_ana1);
+               writel(0, &ocotp_regs->hw_ocotp_read_ctrl);
+               ocotp_clk_disable();
+       }
+
+       if (thermal_calib == 0 || thermal_calib == 0xffffffff)
+               return TEMPERATURE_MIN;
+
+       /* Fuse data layout:
+        * [31:20] sensor value @ 25C
+        * [19:8] sensor value of hot
+        * [7:0] hot temperature value */
+       raw_25c = thermal_calib >> 20;
+       raw_hot = (thermal_calib & 0xfff00) >> 8;
+       hot_temp = thermal_calib & 0xff;
+
+       ratio = ((raw_25c - raw_hot) * 100) / (hot_temp - 25);
+       raw_n40c = raw_25c + (13 * ratio) / 20;
+
+       /* now we only using single measure, every time we measure
+       the temperature, we will power on/down the anadig module*/
+       writel(BM_ANADIG_TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_clr);
+       writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set);
+
+       /* write measure freq */
+       reg = readl(&anatop->tempsense1);
+       reg &= ~BM_ANADIG_TEMPSENSE1_MEASURE_FREQ;
+       reg |= 327;
+       writel(reg, &anatop->tempsense1);
+
+       writel(BM_ANADIG_TEMPSENSE0_MEASURE_TEMP, &anatop->tempsense0_clr);
+       writel(BM_ANADIG_TEMPSENSE0_FINISHED, &anatop->tempsense0_clr);
+       writel(BM_ANADIG_TEMPSENSE0_MEASURE_TEMP, &anatop->tempsense0_set);
+
+       tmp = 0;
+       /* read five times of temperature values to get average*/
+       for (i = 0; i < 5; i++) {
+               while ((readl(&anatop->tempsense0) &
+                               BM_ANADIG_TEMPSENSE0_FINISHED) == 0)
+                       udelay(10000);
+               reg = readl(&anatop->tempsense0);
+               tmp += (reg & BM_ANADIG_TEMPSENSE0_TEMP_VALUE) >>
+                       BP_ANADIG_TEMPSENSE0_TEMP_VALUE;
+               writel(BM_ANADIG_TEMPSENSE0_FINISHED,
+                       &anatop->tempsense0_clr);
+       }
+
+       tmp = tmp / 5;
+       if (tmp <= raw_n40c)
+               temperature = REG_VALUE_TO_CEL(ratio, tmp);
+       else
+               temperature = TEMPERATURE_MIN;
+
+       /* power down anatop thermal sensor */
+       writel(BM_ANADIG_TEMPSENSE0_POWER_DOWN, &anatop->tempsense0_set);
+       writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_clr);
+
+       return temperature;
+}
+
+int check_cpu_temperature(int boot)
+{
+       static int __data max_temp;
+       int boot_limit = TEMPERATURE_HOT;
+       int tmp = read_cpu_temperature();
+
+       if (tmp < TEMPERATURE_MIN || tmp > TEMPERATURE_MAX) {
+               printf("Temperature:   can't get valid data!\n");
+               return tmp;
+       }
+
+       while (tmp >= boot_limit) {
+               if (boot) {
+                       printf("CPU is %d C, too hot to boot, waiting...\n",
+                               tmp);
+                       udelay(5000000);
+                       tmp = read_cpu_temperature();
+                       boot_limit = TEMPERATURE_HOT - 1;
+               } else {
+                       printf("CPU is %d C, too hot, resetting...\n",
+                               tmp);
+                       udelay(1000000);
+                       reset_cpu(0);
+               }
+       }
+
+       if (boot) {
+               printf("Temperature:   %d C, calibration data 0x%x\n",
+                       tmp, thermal_calib);
+       } else if (tmp > max_temp) {
+               if (tmp > TEMPERATURE_HOT - 5)
+                       printf("WARNING: CPU temperature %d C\n", tmp);
+               max_temp = tmp;
+       }
+       return tmp;
+}
+
 static void imx_set_wdog_powerdown(bool enable)
 {
        struct wdog_regs *wdog1 = (struct wdog_regs *)WDOG1_BASE_ADDR;
@@ -129,6 +275,7 @@ static void imx_set_wdog_powerdown(bool enable)
        writew(enable, &wdog2->wmcr);
 }
 
+#ifdef CONFIG_ARCH_CPU_INIT
 int arch_cpu_init(void)
 {
        init_aips();
@@ -137,13 +284,17 @@ int arch_cpu_init(void)
 
        imx_set_wdog_powerdown(false); /* Disable PDE bit of WMCR register */
 
-#ifdef CONFIG_APBH_DMA
-       /* Start APBH DMA */
+#ifdef CONFIG_VIDEO_IPUV3
+       gd->arch.ipu_hw_rev = IPUV3_HW_REV_IPUV3H;
+#endif
+#ifdef  CONFIG_APBH_DMA
+       /* Timer is required for Initializing APBH DMA */
+       timer_init();
        mxs_dma_init();
 #endif
-
        return 0;
 }
+#endif
 
 #ifndef CONFIG_SYS_DCACHE_OFF
 void enable_caches(void)
@@ -163,14 +314,13 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
 
        u32 value = readl(&fuse->mac_addr_high);
        mac[0] = (value >> 8);
-       mac[1] = value ;
+       mac[1] = value;
 
        value = readl(&fuse->mac_addr_low);
-       mac[2] = value >> 24 ;
-       mac[3] = value >> 16 ;
-       mac[4] = value >> 8 ;
-       mac[5] = value ;
-
+       mac[2] = value >> 24;
+       mac[3] = value >> 16;
+       mac[4] = value >> 8;
+       mac[5] = value;
 }
 #endif
 
diff --git a/arch/arm/cpu/armv7/omap-common/config.mk b/arch/arm/cpu/armv7/omap-common/config.mk
deleted file mode 100644 (file)
index 3a36ab6..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#
-# (C) Copyright 2002
-# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
-#
-# SPDX-License-Identifier:     GPL-2.0+
-#
-
-# Make ARMv5 to allow more compilers to work, even though its v7a.
-PLATFORM_CPPFLAGS += -march=armv5
index 86c0e42..9c8cf89 100644 (file)
@@ -26,7 +26,11 @@ ENTRY(set_pl310_ctrl_reg)
        PUSH    {r4-r11, lr}    @ save registers - ROM code may pollute
                                @ our registers
        LDR     r12, =0x102     @ Set PL310 control register - value in R0
-       .word   0xe1600070      @ SMC #0 - hand assembled because -march=armv5
-                               @ call ROM Code API to set control register
+#if __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 && defined(__ARM_ARCH_7A__)
+       .arch_extension sec
+       smc     #0              @ call ROM Code API to set control register
+#else
+       .word   0xe1600070
+#endif
        POP     {r4-r11, pc}
 ENDPROC(set_pl310_ctrl_reg)
index 91ad031..4145e37 100644 (file)
@@ -9,6 +9,7 @@
  *
  * SPDX-License-Identifier:    GPL-2.0+
  */
+#include <common.h>
 #include <config.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
@@ -16,6 +17,8 @@
 
 void __weak reset_cpu(unsigned long ignored)
 {
+       /* clear the reset status flags */
+       writel(readl(PRM_RSTST), PRM_RSTST);
        writel(PRM_RSTCTRL_RESET, PRM_RSTCTRL);
 }
 
index 7c9924d..95da274 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <common.h>
+#include <div64.h>
 #include <asm/io.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/clock.h>
@@ -29,22 +30,66 @@ static struct gptimer *timer_base = (struct gptimer *)CONFIG_SYS_TIMERBASE;
  * Nothing really to do with interrupts, just starts up a counter.
  */
 
+#if CONFIG_SYS_PTV > 7
+#error Invalid CONFIG_SYS_PTV value
+#elif CONFIG_SYS_PTV >= 0
 #define TIMER_CLOCK            (V_SCLK / (2 << CONFIG_SYS_PTV))
-#define TIMER_OVERFLOW_VAL     0xffffffff
+#define TCLR_VAL               ((CONFIG_SYS_PTV << 2) | TCLR_PRE | TCLR_AR | TCLR_ST)
+#else
+#define TIMER_CLOCK            V_SCLK
+#define TCLR_VAL               (TCLR_AR | TCLR_ST)
+#endif
 #define TIMER_LOAD_VAL         0
 
+#define TIOCP_CFG_SOFTRESET    (1 << 0)
+
+#if TIMER_CLOCK < CONFIG_SYS_HZ
+#error TIMER_CLOCK must be >= CONFIG_SYS_HZ
+#endif
+
+/*
+ * Start timer so that it will overflow 15 sec after boot,
+ * to catch misbehaving timer code early on!
+*/
+#define TIMER_START            (-time_to_tick(15 * CONFIG_SYS_HZ))
+
+static inline unsigned long tick_to_time(unsigned long tick)
+{
+       return tick / (TIMER_CLOCK / CONFIG_SYS_HZ);
+}
+
+static inline unsigned long time_to_tick(unsigned long time)
+{
+       return time * (TIMER_CLOCK / CONFIG_SYS_HZ);
+}
+
+static inline unsigned long us_to_ticks(unsigned long usec)
+{
+       return usec * (TIMER_CLOCK / CONFIG_SYS_HZ / 1000);
+}
+
 int timer_init(void)
 {
+#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
+       /* Reset the Timer */
+       writel(TIOCP_CFG_SOFTRESET, &timer_base->tiocp_cfg);
+
+       /* Wait until the reset is done */
+       while (readl(&timer_base->tiocp_cfg) & TIOCP_CFG_SOFTRESET)
+               ;
+
+       /* preload the counter to make overflow occur early */
+       writel(TIMER_START, &timer_base->tldr);
+       writel(~0, &timer_base->ttgr);
+
        /* start the counter ticking up, reload value on overflow */
        writel(TIMER_LOAD_VAL, &timer_base->tldr);
        /* enable timer */
-       writel((CONFIG_SYS_PTV << 2) | TCLR_PRE | TCLR_AR | TCLR_ST,
-               &timer_base->tclr);
-
-       /* reset time, capture current incrementer value time */
-       gd->arch.lastinc = readl(&timer_base->tcrr) /
-                                       (TIMER_CLOCK / CONFIG_SYS_HZ);
-       gd->arch.tbl = 0;       /* start "advancing" time stamp from 0 */
+       writel(TCLR_VAL, &timer_base->tclr);
+#endif
+       gd->arch.lastinc = -30 * TIMER_CLOCK;
+       gd->arch.tbl = TIMER_START;
+       gd->arch.timer_rate_hz = TIMER_CLOCK;
 
        return 0;
 }
@@ -54,39 +99,29 @@ int timer_init(void)
  */
 ulong get_timer(ulong base)
 {
-       return get_timer_masked() - base;
+       return tick_to_time(get_ticks() - time_to_tick(base));
 }
 
 /* delay x useconds */
 void __udelay(unsigned long usec)
 {
-       long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
-       unsigned long now, last = readl(&timer_base->tcrr);
-
-       while (tmo > 0) {
-               now = readl(&timer_base->tcrr);
-               if (last > now) /* count up timer overflow */
-                       tmo -= TIMER_OVERFLOW_VAL - last + now + 1;
-               else
-                       tmo -= now - last;
-               last = now;
-       }
+       unsigned long start = readl(&timer_base->tcrr);
+       unsigned long ticks = us_to_ticks(usec);
+
+       if (usec == 0)
+               return;
+
+       if (ticks == 0)
+               ticks++;
+
+       while (readl(&timer_base->tcrr) - start < ticks)
+               /* NOP */ ;
 }
 
 ulong get_timer_masked(void)
 {
        /* current tick value */
-       ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ);
-
-       if (now >= gd->arch.lastinc) {  /* normal mode (non roll) */
-               /* move stamp fordward with absoulte diff ticks */
-               gd->arch.tbl += (now - gd->arch.lastinc);
-       } else {        /* we have rollover of incrementer */
-               gd->arch.tbl += ((TIMER_LOAD_VAL / (TIMER_CLOCK /
-                               CONFIG_SYS_HZ)) - gd->arch.lastinc) + now;
-       }
-       gd->arch.lastinc = now;
-       return gd->arch.tbl;
+       return tick_to_time(get_ticks());
 }
 
 /*
@@ -95,7 +130,12 @@ ulong get_timer_masked(void)
  */
 unsigned long long get_ticks(void)
 {
-       return get_timer(0);
+       ulong now = readl(&timer_base->tcrr);
+       ulong inc = now - gd->arch.lastinc;
+
+       gd->arch.tbl += inc;
+       gd->arch.lastinc = now;
+       return gd->arch.tbl;
 }
 
 /*
@@ -104,5 +144,5 @@ unsigned long long get_ticks(void)
  */
 ulong get_tbclk(void)
 {
-       return CONFIG_SYS_HZ;
+       return gd->arch.timer_rate_hz;
 }
index ef62fc8..364094e 100644 (file)
@@ -65,11 +65,7 @@ _end_vect:
 
 .globl _TEXT_BASE
 _TEXT_BASE:
-#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_TEXT_BASE)
-       .word   CONFIG_SPL_TEXT_BASE
-#else
-       .word   CONFIG_SYS_TEXT_BASE
-#endif
+       .word   _start
 
 /*
  * These are defined in the board-specific linker script.
diff --git a/arch/arm/dts/am33xx.dtsi b/arch/arm/dts/am33xx.dtsi
new file mode 100644 (file)
index 0000000..edee62f
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ * Device Tree Source for AM33XX SoC
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2.  This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+       compatible = "ti,am33xx";
+
+       aliases {
+               serial0 = &uart0;
+               serial1 = &uart1;
+               serial2 = &uart2;
+               serial3 = &uart3;
+               serial4 = &uart4;
+               serial5 = &uart5;
+       };
+
+       cpus {
+               cpu@0 {
+                       compatible = "arm,cortex-a8";
+               };
+       };
+
+       /*
+        * The soc node represents the soc top level view. It is uses for IPs
+        * that are not memory mapped in the MPU view or for the MPU itself.
+        */
+       soc {
+               compatible = "ti,omap-infra";
+               mpu {
+                       compatible = "ti,omap3-mpu";
+                       ti,hwmods = "mpu";
+               };
+       };
+
+       /*
+        * XXX: Use a flat representation of the AM33XX interconnect.
+        * The real AM33XX interconnect network is quite complex.Since
+        * that will not bring real advantage to represent that in DT
+        * for the moment, just use a fake OCP bus entry to represent
+        * the whole bus hierarchy.
+        */
+       ocp {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+               ti,hwmods = "l3_main";
+
+               intc: interrupt-controller@48200000 {
+                       compatible = "ti,omap2-intc";
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+                       ti,intc-size = <128>;
+                       reg = <0x48200000 0x1000>;
+               };
+
+               gpio0: gpio@44e07000 {
+                       compatible = "ti,omap4-gpio";
+                       ti,hwmods = "gpio1";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+               };
+
+               gpio1: gpio@4804C000 {
+                       compatible = "ti,omap4-gpio";
+                       ti,hwmods = "gpio2";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+               };
+
+               gpio2: gpio@481AC000 {
+                       compatible = "ti,omap4-gpio";
+                       ti,hwmods = "gpio3";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+               };
+
+               gpio3: gpio@481AE000 {
+                       compatible = "ti,omap4-gpio";
+                       ti,hwmods = "gpio4";
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
+               };
+
+               uart0: serial@44E09000 {
+                       compatible = "ti,omap3-uart";
+                       ti,hwmods = "uart1";
+                       clock-frequency = <48000000>;
+               };
+
+               uart1: serial@48022000 {
+                       compatible = "ti,omap3-uart";
+                       ti,hwmods = "uart2";
+                       clock-frequency = <48000000>;
+               };
+
+               uart2: serial@48024000 {
+                       compatible = "ti,omap3-uart";
+                       ti,hwmods = "uart3";
+                       clock-frequency = <48000000>;
+               };
+
+               uart3: serial@481A6000 {
+                       compatible = "ti,omap3-uart";
+                       ti,hwmods = "uart4";
+                       clock-frequency = <48000000>;
+               };
+
+               uart4: serial@481A8000 {
+                       compatible = "ti,omap3-uart";
+                       ti,hwmods = "uart5";
+                       clock-frequency = <48000000>;
+               };
+
+               uart5: serial@481AA000 {
+                       compatible = "ti,omap3-uart";
+                       ti,hwmods = "uart6";
+                       clock-frequency = <48000000>;
+               };
+
+               i2c0: i2c@44E0B000 {
+                       compatible = "ti,omap4-i2c";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "i2c1";
+               };
+
+               i2c1: i2c@4802A000 {
+                       compatible = "ti,omap4-i2c";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "i2c2";
+               };
+
+               i2c2: i2c@4819C000 {
+                       compatible = "ti,omap4-i2c";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ti,hwmods = "i2c3";
+               };
+       };
+};
diff --git a/arch/arm/dts/imx6qdl.dtsi b/arch/arm/dts/imx6qdl.dtsi
new file mode 100644 (file)
index 0000000..06ec460
--- /dev/null
@@ -0,0 +1,800 @@
+/*
+ * 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;
+       };
+
+       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@00110000 {
+                       compatible = "fsl,imx6q-dma-apbh", "fsl,imx28-dma-apbh";
+                       reg = <0x00110000 0x2000>;
+                       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";
+                       fsl,gpmi-dma-channel = <0>;
+                       status = "disabled";
+               };
+
+               timer@00a00600 {
+                       compatible = "arm,cortex-a9-twd-timer";
+                       reg = <0x00a00600 0x20>;
+                       interrupts = <1 13 0xf01>;
+               };
+
+               L2: l2-cache@00a02000 {
+                       compatible = "arm,pl310-cache";
+                       reg = <0x00a02000 0x1000>;
+                       interrupts = <0 92 0x04>;
+                       cache-unified;
+                       cache-level = <2>;
+               };
+
+               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";
+                               reg = <0x02098000 0x4000>;
+                               interrupts = <0 55 0x04>;
+                       };
+
+                       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";
+                               reg = <0x020d8000 0x4000>;
+                               interrupts = <0 91 0x04 0 96 0x04>;
+                       };
+
+                       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>;
+                       };
+
+                       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";
+               };
+       };
+};
diff --git a/arch/arm/dts/mx28.dtsi b/arch/arm/dts/mx28.dtsi
new file mode 100644 (file)
index 0000000..a9bda8e
--- /dev/null
@@ -0,0 +1,872 @@
+/*
+ * Copyright 2012 Freescale Semiconductor, Inc.
+ *
+ * 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"
+
+/ {
+       interrupt-parent = <&icoll>;
+
+       aliases {
+               gpio0 = &gpio0;
+               gpio1 = &gpio1;
+               gpio2 = &gpio2;
+               gpio3 = &gpio3;
+               gpio4 = &gpio4;
+               saif0 = &saif0;
+               saif1 = &saif1;
+               serial0 = &auart0;
+               serial1 = &auart1;
+               serial2 = &auart2;
+               serial3 = &auart3;
+               serial4 = &auart4;
+       };
+
+       cpus {
+               cpu@0 {
+                       compatible = "arm,arm926ejs";
+               };
+       };
+
+       apb@80000000 {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0x80000000 0x80000>;
+               ranges;
+
+               apbh@80000000 {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       reg = <0x80000000 0x3c900>;
+                       ranges;
+
+                       icoll: interrupt-controller@80000000 {
+                               compatible = "fsl,imx28-icoll", "fsl,mxs-icoll";
+                               interrupt-controller;
+                               #interrupt-cells = <1>;
+                               reg = <0x80000000 0x2000>;
+                       };
+
+                       hsadc@80002000 {
+                               reg = <0x80002000 0x2000>;
+                               interrupts = <13 87>;
+                               status = "disabled";
+                       };
+
+                       dma-apbh@80004000 {
+                               compatible = "fsl,imx28-dma-apbh";
+                               reg = <0x80004000 0x2000>;
+                       };
+
+                       perfmon@80006000 {
+                               reg = <0x80006000 0x800>;
+                               interrupts = <27>;
+                               status = "disabled";
+                       };
+
+                       gpmi-nand@8000c000 {
+                               compatible = "fsl,imx28-gpmi-nand";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0x8000c000 0x2000>, <0x8000a000 0x2000>;
+                               reg-names = "gpmi-nand", "bch";
+                               interrupts = <88>, <41>;
+                               interrupt-names = "gpmi-dma", "bch";
+                               fsl,gpmi-dma-channel = <4>;
+                               status = "disabled";
+                       };
+
+                       ssp0: ssp@80010000 {
+                               reg = <0x80010000 0x2000>;
+                               interrupts = <96 82>;
+                               fsl,ssp-dma-channel = <0>;
+                               status = "disabled";
+                       };
+
+                       ssp1: ssp@80012000 {
+                               reg = <0x80012000 0x2000>;
+                               interrupts = <97 83>;
+                               fsl,ssp-dma-channel = <1>;
+                               status = "disabled";
+                       };
+
+                       ssp2: ssp@80014000 {
+                               reg = <0x80014000 0x2000>;
+                               interrupts = <98 84>;
+                               fsl,ssp-dma-channel = <2>;
+                               status = "disabled";
+                       };
+
+                       ssp3: ssp@80016000 {
+                               reg = <0x80016000 0x2000>;
+                               interrupts = <99 85>;
+                               fsl,ssp-dma-channel = <3>;
+                               status = "disabled";
+                       };
+
+                       pinctrl@80018000 {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               compatible = "fsl,imx28-pinctrl", "simple-bus";
+                               reg = <0x80018000 0x2000>;
+
+                               gpio0: gpio@0 {
+                                       compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+                                       interrupts = <127>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio1: gpio@1 {
+                                       compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+                                       interrupts = <126>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio2: gpio@2 {
+                                       compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+                                       interrupts = <125>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio3: gpio@3 {
+                                       compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+                                       interrupts = <124>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               gpio4: gpio@4 {
+                                       compatible = "fsl,imx28-gpio", "fsl,mxs-gpio";
+                                       interrupts = <123>;
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                               };
+
+                               duart_pins_a: duart@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3102 /* MX28_PAD_PWM0__DUART_RX */
+                                               0x3112 /* MX28_PAD_PWM1__DUART_TX */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               duart_pins_b: duart@1 {
+                                       reg = <1>;
+                                       fsl,pinmux-ids = <
+                                               0x3022 /* MX28_PAD_AUART0_CTS__DUART_RX */
+                                               0x3032 /* MX28_PAD_AUART0_RTS__DUART_TX */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               duart_4pins_a: duart-4pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3022 /* MX28_PAD_AUART0_CTS__DUART_RX */
+                                               0x3032 /* MX28_PAD_AUART0_RTS__DUART_TX */
+                                               0x3002 /* MX28_PAD_AUART0_RX__DUART_CTS */
+                                               0x3012 /* MX28_PAD_AUART0_TX__DUART_RTS */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               gpmi_pins_a: gpmi-nand@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x0000 /* MX28_PAD_GPMI_D00__GPMI_D0 */
+                                               0x0010 /* MX28_PAD_GPMI_D01__GPMI_D1 */
+                                               0x0020 /* MX28_PAD_GPMI_D02__GPMI_D2 */
+                                               0x0030 /* MX28_PAD_GPMI_D03__GPMI_D3 */
+                                               0x0040 /* MX28_PAD_GPMI_D04__GPMI_D4 */
+                                               0x0050 /* MX28_PAD_GPMI_D05__GPMI_D5 */
+                                               0x0060 /* MX28_PAD_GPMI_D06__GPMI_D6 */
+                                               0x0070 /* MX28_PAD_GPMI_D07__GPMI_D7 */
+                                               0x0100 /* MX28_PAD_GPMI_CE0N__GPMI_CE0N */
+                                               0x0140 /* MX28_PAD_GPMI_RDY0__GPMI_READY0 */
+                                               0x0180 /* MX28_PAD_GPMI_RDN__GPMI_RDN */
+                                               0x0190 /* MX28_PAD_GPMI_WRN__GPMI_WRN */
+                                               0x01a0 /* MX28_PAD_GPMI_ALE__GPMI_ALE */
+                                               0x01b0 /* MX28_PAD_GPMI_CLE__GPMI_CLE */
+                                               0x01c0 /* MX28_PAD_GPMI_RESETN__GPMI_RESETN */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               gpmi_status_cfg: gpmi-status-cfg {
+                                       fsl,pinmux-ids = <
+                                               0x0180 /* MX28_PAD_GPMI_RDN__GPMI_RDN */
+                                               0x0190 /* MX28_PAD_GPMI_WRN__GPMI_WRN */
+                                               0x01c0 /* MX28_PAD_GPMI_RESETN__GPMI_RESETN */
+                                       >;
+                                       fsl,drive-strength = <2>;
+                               };
+
+                               auart0_pins_a: auart0@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3000 /* MX28_PAD_AUART0_RX__AUART0_RX */
+                                               0x3010 /* MX28_PAD_AUART0_TX__AUART0_TX */
+                                               0x3020 /* MX28_PAD_AUART0_CTS__AUART0_CTS */
+                                               0x3030 /* MX28_PAD_AUART0_RTS__AUART0_RTS */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               auart0_2pins_a: auart0-2pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3000 /* MX28_PAD_AUART0_RX__AUART0_RX */
+                                               0x3010 /* MX28_PAD_AUART0_TX__AUART0_TX */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               auart1_pins_a: auart1@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3040 /* MX28_PAD_AUART1_RX__AUART1_RX */
+                                               0x3050 /* MX28_PAD_AUART1_TX__AUART1_TX */
+                                               0x3060 /* MX28_PAD_AUART1_CTS__AUART1_CTS */
+                                               0x3070 /* MX28_PAD_AUART1_RTS__AUART1_RTS */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               auart1_2pins_a: auart1-2pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x3040 /* MX28_PAD_AUART1_RX__AUART1_RX */
+                                               0x3050 /* MX28_PAD_AUART1_TX__AUART1_TX */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               auart2_2pins_a: auart2-2pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x2101 /* MX28_PAD_SSP2_SCK__AUART2_RX */
+                                               0x2111 /* MX28_PAD_SSP2_MOSI__AUART2_TX */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               auart3_pins_a: auart3@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x30c0 /* MX28_PAD_AUART3_RX__AUART3_RX */
+                                               0x30d0 /* MX28_PAD_AUART3_TX__AUART3_TX */
+                                               0x30e0 /* MX28_PAD_AUART3_CTS__AUART3_CTS */
+                                               0x30f0 /* MX28_PAD_AUART3_RTS__AUART3_RTS */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               auart3_2pins_a: auart3-2pins@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x2121 /* MX28_PAD_SSP2_MISO__AUART3_RX */
+                                               0x2131 /* MX28_PAD_SSP2_SS0__AUART3_TX */
+                                       >;
+                                       fsl,drive-strength = <0>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               mac0_pins_a: mac0@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x4000 /* MX28_PAD_ENET0_MDC__ENET0_MDC */
+                                               0x4010 /* MX28_PAD_ENET0_MDIO__ENET0_MDIO */
+                                               0x4020 /* MX28_PAD_ENET0_RX_EN__ENET0_RX_EN */
+                                               0x4030 /* MX28_PAD_ENET0_RXD0__ENET0_RXD0 */
+                                               0x4040 /* MX28_PAD_ENET0_RXD1__ENET0_RXD1 */
+                                               0x4060 /* MX28_PAD_ENET0_TX_EN__ENET0_TX_EN */
+                                               0x4070 /* MX28_PAD_ENET0_TXD0__ENET0_TXD0 */
+                                               0x4080 /* MX28_PAD_ENET0_TXD1__ENET0_TXD1 */
+                                               0x4100 /* MX28_PAD_ENET_CLK__CLKCTRL_ENET */
+                                       >;
+                                       fsl,drive-strength = <1>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <1>;
+                               };
+
+                               mac1_pins_a: mac1@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x40f1 /* MX28_PAD_ENET0_CRS__ENET1_RX_EN */
+                                               0x4091 /* MX28_PAD_ENET0_RXD2__ENET1_RXD0 */
+                                               0x40a1 /* MX28_PAD_ENET0_RXD3__ENET1_RXD1 */
+                                               0x40e1 /* MX28_PAD_ENET0_COL__ENET1_TX_EN */
+                                               0x40b1 /* MX28_PAD_ENET0_TXD2__ENET1_TXD0 */
+                                               0x40c1 /* MX28_PAD_ENET0_TXD3__ENET1_TXD1 */
+                                       >;
+                                       fsl,drive-strength = <1>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <1>;
+                               };
+
+                               mmc0_8bit_pins_a: mmc0-8bit@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x2000 /* MX28_PAD_SSP0_DATA0__SSP0_D0 */
+                                               0x2010 /* MX28_PAD_SSP0_DATA1__SSP0_D1 */
+                                               0x2020 /* MX28_PAD_SSP0_DATA2__SSP0_D2 */
+                                               0x2030 /* MX28_PAD_SSP0_DATA3__SSP0_D3 */
+                                               0x2040 /* MX28_PAD_SSP0_DATA4__SSP0_D4 */
+                                               0x2050 /* MX28_PAD_SSP0_DATA5__SSP0_D5 */
+                                               0x2060 /* MX28_PAD_SSP0_DATA6__SSP0_D6 */
+                                               0x2070 /* MX28_PAD_SSP0_DATA7__SSP0_D7 */
+                                               0x2080 /* MX28_PAD_SSP0_CMD__SSP0_CMD */
+                                               0x2090 /* MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT */
+                                               0x20a0 /* MX28_PAD_SSP0_SCK__SSP0_SCK */
+                                       >;
+                                       fsl,drive-strength = <1>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <1>;
+                               };
+
+                               mmc0_4bit_pins_a: mmc0-4bit@0 {
+                                       reg = <0>;
+                                       fsl,pinmux-ids = <
+                                               0x2000 /* MX28_PAD_SSP0_DATA0__SSP0_D0 */
+                                               0x2010 /* MX28_PAD_SSP0_DATA1__SSP0_D1 */
+                                               0x2020 /* MX28_PAD_SSP0_DATA2__SSP0_D2 */
+                                               0x2030 /* MX28_PAD_SSP0_DATA3__SSP0_D3 */
+                                               0x2080 /* MX28_PAD_SSP0_CMD__SSP0_CMD */
+                                               0x2090 /* MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT */
+                                               0x20a0 /* MX28_PAD_SSP0_SCK__SSP0_SCK */
+                                       >;
+                                       fsl,drive-strength = <1>;
+                                       fsl,voltage = <1>;
+                                       fsl,pull-up = <1>;
+                               };
+
+                               mmc0_cd_cfg: mmc0-cd-cfg {
+                                       fsl,pinmux-ids = <
+                                               0x2090 /* MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT */
+                                       >;
+                                       fsl,pull-up = <0>;
+                               };
+
+                               mmc0_sck_cfg: mmc0-sck-cfg {
+                        &