Unified codebase for TX28, TX48, TX51, TX53
authorLothar Waßmann <LW@KARO-electronics.de>
Wed, 24 Oct 2012 15:28:44 +0000 (17:28 +0200)
committerLothar Waßmann <LW@KARO-electronics.de>
Wed, 24 Oct 2012 15:28:44 +0000 (17:28 +0200)
544 files changed:
.gitignore
MAINTAINERS
Makefile
README
arch/arm/config.mk
arch/arm/cpu/arm926ejs/config.mk
arch/arm/cpu/arm926ejs/cpu.c
arch/arm/cpu/arm926ejs/mx25/generic.c
arch/arm/cpu/arm926ejs/mx28/Makefile
arch/arm/cpu/arm926ejs/mx28/debug.c [new file with mode: 0644]
arch/arm/cpu/arm926ejs/mx28/debug.h [new file with mode: 0644]
arch/arm/cpu/arm926ejs/mx28/mx28.c
arch/arm/cpu/arm926ejs/mx28/mx28_init.h
arch/arm/cpu/arm926ejs/mx28/spl_boot.c
arch/arm/cpu/arm926ejs/mx28/spl_lradc_init.c [new file with mode: 0644]
arch/arm/cpu/arm926ejs/mx28/spl_mem_init.c
arch/arm/cpu/arm926ejs/mx28/spl_power_init.c
arch/arm/cpu/arm926ejs/mx28/timer.c
arch/arm/cpu/armv7/am33xx/Makefile
arch/arm/cpu/armv7/am33xx/board.c
arch/arm/cpu/armv7/am33xx/clock.c
arch/arm/cpu/armv7/am33xx/ddr.c [deleted file]
arch/arm/cpu/armv7/am33xx/ddr2.c [new file with mode: 0644]
arch/arm/cpu/armv7/am33xx/ddr3.c [new file with mode: 0644]
arch/arm/cpu/armv7/am33xx/elm.c [new file with mode: 0644]
arch/arm/cpu/armv7/am33xx/emif4.c
arch/arm/cpu/armv7/am33xx/mem.c [new file with mode: 0644]
arch/arm/cpu/armv7/am33xx/sys_info.c
arch/arm/cpu/armv7/cache_v7.c
arch/arm/cpu/armv7/config.mk
arch/arm/cpu/armv7/cpu.c
arch/arm/cpu/armv7/exynos/Makefile
arch/arm/cpu/armv7/exynos/clock.c
arch/arm/cpu/armv7/exynos/power.c [new file with mode: 0644]
arch/arm/cpu/armv7/exynos/system.c [new file with mode: 0644]
arch/arm/cpu/armv7/imx-common/cpu.c
arch/arm/cpu/armv7/imx-common/timer.c
arch/arm/cpu/armv7/mx5/Makefile
arch/arm/cpu/armv7/mx5/clock.c
arch/arm/cpu/armv7/mx5/iomux-v3.c [new file with mode: 0644]
arch/arm/cpu/armv7/mx5/lowlevel_init.S
arch/arm/cpu/armv7/mx5/soc.c
arch/arm/cpu/armv7/mx6/clock.c
arch/arm/cpu/armv7/mx6/lowlevel_init.S
arch/arm/cpu/armv7/mx6/soc.c
arch/arm/cpu/armv7/omap-common/boot-common.c
arch/arm/cpu/armv7/omap-common/emif-common.c
arch/arm/cpu/armv7/omap-common/hwinit-common.c
arch/arm/cpu/armv7/omap-common/lowlevel_init.S
arch/arm/cpu/armv7/omap-common/reset.c [moved from arch/arm/cpu/armv7/omap-common/reset.S with 70% similarity]
arch/arm/cpu/armv7/omap-common/spl_ymodem.c
arch/arm/cpu/armv7/omap-common/timer.c
arch/arm/cpu/armv7/omap3/board.c
arch/arm/cpu/armv7/omap3/clock.c
arch/arm/cpu/armv7/omap3/lowlevel_init.S
arch/arm/cpu/armv7/omap4/clocks.c
arch/arm/cpu/armv7/omap5/hwinit.c
arch/arm/cpu/armv7/s5pc1xx/cache.S
arch/arm/cpu/armv7/s5pc1xx/reset.S
arch/arm/cpu/armv7/start.S
arch/arm/cpu/armv7/tegra2/Makefile
arch/arm/cpu/armv7/tegra2/ap20.c
arch/arm/cpu/armv7/tegra2/board.c
arch/arm/cpu/armv7/tegra2/clock.c
arch/arm/cpu/armv7/tegra2/crypto.c [new file with mode: 0644]
arch/arm/cpu/armv7/tegra2/crypto.h [new file with mode: 0644]
arch/arm/cpu/armv7/tegra2/emc.c [new file with mode: 0644]
arch/arm/cpu/armv7/tegra2/funcmux.c
arch/arm/cpu/armv7/tegra2/lowlevel_init.S
arch/arm/cpu/armv7/tegra2/pmu.c [new file with mode: 0644]
arch/arm/cpu/armv7/tegra2/warmboot.c [new file with mode: 0644]
arch/arm/cpu/armv7/tegra2/warmboot_avp.c [new file with mode: 0644]
arch/arm/cpu/armv7/tegra2/warmboot_avp.h [new file with mode: 0644]
arch/arm/cpu/armv7/u8500/lowlevel.S
arch/arm/dts/am33xx.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/tegra20.dtsi
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/ddr3_defs.h [new file with mode: 0644]
arch/arm/include/asm/arch-am33xx/ddr_defs.h
arch/arm/include/asm/arch-am33xx/gpio.h [new file with mode: 0644]
arch/arm/include/asm/arch-am33xx/hardware.h
arch/arm/include/asm/arch-am33xx/mem.h [new file with mode: 0644]
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-am33xx/sys_proto.h
arch/arm/include/asm/arch-exynos/clk.h
arch/arm/include/asm/arch-exynos/cpu.h
arch/arm/include/asm/arch-exynos/dsim.h [new file with mode: 0644]
arch/arm/include/asm/arch-exynos/fb.h [new file with mode: 0644]
arch/arm/include/asm/arch-exynos/mipi_dsim.h [new file with mode: 0644]
arch/arm/include/asm/arch-exynos/power.h
arch/arm/include/asm/arch-exynos/system.h [new file with mode: 0644]
arch/arm/include/asm/arch-exynos/tzpc.h
arch/arm/include/asm/arch-mx25/clock.h
arch/arm/include/asm/arch-mx25/imx-regs.h
arch/arm/include/asm/arch-mx28/imx-regs.h
arch/arm/include/asm/arch-mx28/mxsfb.h [new file with mode: 0644]
arch/arm/include/asm/arch-mx28/regs-lcdif.h [new file with mode: 0644]
arch/arm/include/asm/arch-mx28/regs-lradc.h [new file with mode: 0644]
arch/arm/include/asm/arch-mx28/sys_proto.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/imx_iim.h [new file with mode: 0644]
arch/arm/include/asm/arch-mx5/iomux-mx51.h [new file with mode: 0644]
arch/arm/include/asm/arch-mx5/iomux-mx53.h [new file with mode: 0644]
arch/arm/include/asm/arch-mx5/iomux-v3.h [new file with mode: 0644]
arch/arm/include/asm/arch-mx5/iomux.h
arch/arm/include/asm/arch-mx5/mx5x_pins.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 [moved from arch/arm/include/asm/arch-mx6/ccm_regs.h with 99% similarity]
arch/arm/include/asm/arch-mx6/imx-regs.h
arch/arm/include/asm/arch-mx6/iomux-v3.h
arch/arm/include/asm/arch-mx6/sys_proto.h
arch/arm/include/asm/arch-omap3/cpu.h
arch/arm/include/asm/arch-omap3/mux.h
arch/arm/include/asm/arch-omap4/cpu.h
arch/arm/include/asm/arch-omap4/mux_omap4.h
arch/arm/include/asm/arch-omap4/omap.h
arch/arm/include/asm/arch-omap5/cpu.h
arch/arm/include/asm/arch-omap5/mux_omap5.h
arch/arm/include/asm/arch-omap5/omap.h
arch/arm/include/asm/arch-tegra2/ap20.h [moved from arch/arm/cpu/armv7/tegra2/ap20.h with 96% similarity]
arch/arm/include/asm/arch-tegra2/apb_misc.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra2/clk_rst.h
arch/arm/include/asm/arch-tegra2/clock.h
arch/arm/include/asm/arch-tegra2/emc.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra2/flow.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra2/fuse.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra2/gp_padctrl.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra2/pmu.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra2/sdram_param.h [new file with mode: 0644]
arch/arm/include/asm/arch-tegra2/tegra2.h
arch/arm/include/asm/arch-tegra2/tegra_i2c.h
arch/arm/include/asm/arch-tegra2/warmboot.h [new file with mode: 0644]
arch/arm/include/asm/linkage.h [new file with mode: 0644]
arch/arm/include/asm/system.h
arch/arm/lib/cache-cp15.c
arch/arm/lib/cache.c
board/cm_t35/cm_t35.c
board/davinci/ea20/ea20.c
board/denx/m28evk/m28evk.c
board/denx/m28evk/spl_boot.c
board/esg/ima3-mx53/Makefile [new file with mode: 0644]
board/esg/ima3-mx53/ima3-mx53.c [new file with mode: 0644]
board/esg/ima3-mx53/imximage.cfg [new file with mode: 0644]
board/freescale/mx28evk/iomux.c
board/freescale/mx53loco/mx53loco.c
board/freescale/mx6qsabrelite/mx6qsabrelite.c
board/htkw/mcx/mcx.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/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/logicpd/omap3som/omap3logic.c
board/nvidia/common/Makefile
board/nvidia/common/board.c
board/nvidia/common/emc.c [new file with mode: 0644]
board/nvidia/common/emc.h [new file with mode: 0644]
board/nvidia/dts/tegra2-seaboard.dts
board/pandora/pandora.c
board/pandora/pandora.h
board/samsung/smdk5250/tzpc_init.c
board/samsung/trats/trats.c
board/samsung/universal_c210/universal.c
board/teejet/mt_ventoux/mt_ventoux.c
board/ti/am335x/evm.c
board/ti/omap5912osk/omap5912osk.c
board/ti/omap5_evm/evm.c
board/ti/omap730p2/omap730p2.c
board/ti/panda/panda_mux_data.h
board/ttcontrol/vision2/vision2.c
boards.cfg
common/Makefile
common/cmd_bootce.c [new file with mode: 0644]
common/cmd_fdt.c
common/cmd_iim.c [new file with mode: 0644]
common/cmd_nand.c
common/cmd_pata.c [new file with mode: 0644]
common/cmd_sata.c
common/cmd_time.c
common/env_nand.c
common/lcd.c
common/main.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]
doc/SPL/README.omap3
drivers/bios_emulator/x86emu/prim_ops.c
drivers/block/Makefile
drivers/block/dwc_ahsata.c [new file with mode: 0644]
drivers/block/dwc_ahsata.h [new file with mode: 0644]
drivers/block/mxc_ata.h [new file with mode: 0644]
drivers/gpio/Makefile
drivers/gpio/am33xx_gpio.c [new file with mode: 0644]
drivers/gpio/gpiolib.c [new file with mode: 0644]
drivers/gpio/mxc_gpio.c
drivers/i2c/tegra_i2c.c
drivers/input/Makefile
drivers/input/input.c [new file with mode: 0644]
drivers/input/key_matrix.c [new file with mode: 0644]
drivers/input/mxc_keyb.c [new file with mode: 0644]
drivers/input/tegra-kbc.c [new file with mode: 0644]
drivers/misc/Makefile
drivers/misc/imx_iim.c [new file with mode: 0644]
drivers/misc/pmic_dialog.c [new file with mode: 0644]
drivers/misc/pmic_max8997.c [new file with mode: 0644]
drivers/mmc/fsl_esdhc.c
drivers/mmc/imx_ssp_mmc.c [new file with mode: 0644]
drivers/mmc/mxsmmc.c
drivers/mmc/omap_hsmmc.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_base.c
drivers/mtd/nand/nand_bbt.c
drivers/mtd/nand/nand_spl_simple.c
drivers/mtd/spi/Makefile
drivers/mtd/spi/imx_spi_nor_atmel.c [new file with mode: 0644]
drivers/mtd/spi/imx_spi_nor_sst.c [new file with mode: 0644]
drivers/net/Makefile
drivers/net/cpsw.c [new file with mode: 0644]
drivers/net/fec_mxc.c
drivers/net/fec_mxc.h
drivers/net/phy/phy.c
drivers/net/smc911x.h
drivers/power/Makefile
drivers/power/tps6586x.c [new file with mode: 0644]
drivers/power/twl6035.c [new file with mode: 0644]
drivers/serial/serial.c
drivers/serial/stmp3xxx_dbguart.c [new file with mode: 0644]
drivers/serial/stmp3xxx_dbguart.h [new file with mode: 0644]
drivers/spi/imx_cspi.c [new file with mode: 0644]
drivers/spi/imx_ecspi.c [new file with mode: 0644]
drivers/spi/imx_spi_cpld.c [new file with mode: 0644]
drivers/spi/imx_spi_pmic.c [new file with mode: 0644]
drivers/spi/mxs_spi.c
drivers/usb/host/ehci-mx6.c
drivers/usb/host/ehci-mxc.c
drivers/video/Makefile
drivers/video/da8xx-fb.c
drivers/video/exynos_fb.c [new file with mode: 0644]
drivers/video/exynos_fb.h [new file with mode: 0644]
drivers/video/exynos_fimd.c [new file with mode: 0644]
drivers/video/exynos_mipi_dsi.c [new file with mode: 0644]
drivers/video/exynos_mipi_dsi_common.c [new file with mode: 0644]
drivers/video/exynos_mipi_dsi_common.h [new file with mode: 0644]
drivers/video/exynos_mipi_dsi_lowlevel.c [new file with mode: 0644]
drivers/video/exynos_mipi_dsi_lowlevel.h [new file with mode: 0644]
drivers/video/ipu_common.c
drivers/video/ipu_disp.c
drivers/video/ipu_regs.h
drivers/video/mx2fb.c [new file with mode: 0644]
drivers/video/mxc_epdc_fb.c [new file with mode: 0644]
drivers/video/mxc_epdc_fb.h [new file with mode: 0644]
drivers/video/mxc_ipuv3_fb.c
drivers/video/mxsfb.c [new file with mode: 0644]
drivers/video/s6e8ax0.c [new file with mode: 0644]
dts/Makefile
include/aes.h [new file with mode: 0644]
include/ahci.h
include/asm-arm/fec.h [new file with mode: 0644]
include/asm-arm/mmu.h [new file with mode: 0644]
include/asm-generic/gpio.h
include/common.h
include/configs/P1023RDS.h
include/configs/P2020COME.h
include/configs/am3517_crane.h
include/configs/am3517_evm.h
include/configs/at91sam9263ek.h
include/configs/cam_enc_4xx.h
include/configs/cm_t35.h
include/configs/da830evm.h
include/configs/devkit8000.h
include/configs/ea20.h
include/configs/eb_cpux9k2.h
include/configs/flea3.h
include/configs/hawkboard.h
include/configs/igep00x0.h
include/configs/ima3-mx53.h [new file with mode: 0644]
include/configs/imx27lite-common.h
include/configs/m28evk.h
include/configs/mcx.h
include/configs/meesc.h
include/configs/mv-common.h
include/configs/mx23_evk.h [new file with mode: 0644]
include/configs/mx25_3stack.h [new file with mode: 0644]
include/configs/mx25_3stack_mfg.h [new file with mode: 0644]
include/configs/mx25pdk.h
include/configs/mx28_evk.h [new file with mode: 0644]
include/configs/mx28evk.h
include/configs/mx31_3stack.h [new file with mode: 0644]
include/configs/mx31pdk.h
include/configs/mx35_3stack.h [new file with mode: 0644]
include/configs/mx35_3stack_mfg.h [new file with mode: 0644]
include/configs/mx35_3stack_mmc.h [new file with mode: 0644]
include/configs/mx35pdk.h
include/configs/mx50_arm2.h [new file with mode: 0644]
include/configs/mx50_arm2_iram.h [new file with mode: 0644]
include/configs/mx50_arm2_lpddr2.h [new file with mode: 0644]
include/configs/mx50_arm2_mfg.h [new file with mode: 0644]
include/configs/mx51_3stack.h [new file with mode: 0644]
include/configs/mx51_3stack_android.h [new file with mode: 0644]
include/configs/mx51_bbg.h [new file with mode: 0644]
include/configs/mx51_bbg_android.h [new file with mode: 0644]
include/configs/mx51_bbg_mfg.h [new file with mode: 0644]
include/configs/mx53_arm2.h [new file with mode: 0644]
include/configs/mx53_arm2_ddr3.h [new file with mode: 0644]
include/configs/mx53_evk.h [new file with mode: 0644]
include/configs/mx53_evk_mfg.h [new file with mode: 0644]
include/configs/mx53loco.h
include/configs/mx6qarm2.h
include/configs/mx6qsabrelite.h
include/configs/omap3_beagle.h
include/configs/omap3_evm_common.h
include/configs/omap3_overo.h
include/configs/omap3_pandora.h
include/configs/omap4_common.h
include/configs/omap5912osk.h
include/configs/omap5_evm.h
include/configs/omap730p2.h
include/configs/otc570.h
include/configs/p1_p2_rdb_pc.h
include/configs/seaboard.h
include/configs/spear-common.h
include/configs/tam3517-common.h
include/configs/tegra2-common.h
include/configs/trats.h
include/configs/tricorder.h
include/configs/triton320.h [new file with mode: 0644]
include/configs/tx25.h
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/zmx25.h
include/dialog_pmic.h [new file with mode: 0644]
include/environment.h
include/fdtdec.h
include/fsl_esdhc.h
include/fsl_pmic.h
include/imx_spi.h [new file with mode: 0644]
include/imx_spi_nor.h [new file with mode: 0644]
include/imx_ssp_mmc.h [new file with mode: 0644]
include/input.h [new file with mode: 0644]
include/ipu_pixfmt.h
include/key_matrix.h [new file with mode: 0644]
include/lcd.h
include/linux/input.h [new file with mode: 0644]
include/linux/linkage.h
include/linux/mtd/bbm.h
include/max8997_pmic.h [new file with mode: 0644]
include/max8998_pmic.h
include/mx2fb.h [new file with mode: 0644]
include/mxc_keyb.h [new file with mode: 0644]
include/nand.h
include/netdev.h
include/pata.h [new file with mode: 0644]
include/pmic.h
include/tegra-kbc.h [new file with mode: 0644]
include/tps6586x.h [new file with mode: 0644]
include/twl6035.h [new file with mode: 0644]
include/wince.h [new file with mode: 0644]
lib/Makefile
lib/aes.c [new file with mode: 0644]
lib/fdtdec.c
net/bootp.c
net/bootp.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/gcc-version.sh [new file with mode: 0755]
tools/logos/karo.bmp [new file with mode: 0644]

index 0f32fd8..e8ba851 100644 (file)
@@ -59,6 +59,7 @@ patches-*
 # quilt's files
 patches
 series
+.pc
 
 # gdb files
 .gdb_history
index a28967f..f796872 100644 (file)
@@ -796,6 +796,12 @@ Dave Purdy <david.c.purdy@gmail.com>
 
        pogo_e02        ARM926EJS (Kirkwood SoC)
 
+Sricharan R <r.sricharan@ti.com>
+
+       omap4_panda     ARM ARMV7 (OMAP4xx SoC)
+       omap4_sdp4430   ARM ARMV7 (OMAP4xx SoC)
+       omap5_evm       ARM ARMV7 (OMAP5xx Soc)
+
 Thierry Reding <thierry.reding@avionic-design.de>
 
        plutux          Tegra2 (ARM7 & A9 Dual Core)
@@ -868,12 +874,6 @@ Greg Ungerer <greg.ungerer@opengear.com>
        cm4116          ks8695p
        cm4148          ks8695p
 
-Aneesh V <aneesh@ti.com>
-
-       omap4_panda     ARM ARMV7 (OMAP4xx SoC)
-       omap4_sdp4430   ARM ARMV7 (OMAP4xx SoC)
-       omap5_evm       ARM ARMV7 (OMAP5xx Soc)
-
 Marek Vasut <marek.vasut@gmail.com>
 
        balloon3        xscale/pxa
index 023ea23..be62a69 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -30,8 +30,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/ \
@@ -130,6 +128,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
 
@@ -449,9 +450,11 @@ $(obj)u-boot.ais:       $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin
                        $(obj)u-boot.ais
                rm $(obj)spl/u-boot-spl{,-pad}.ais
 
-$(obj)u-boot.sb:       $(obj)u-boot.bin $(obj)spl/u-boot-spl.bin
-               elftosb -zdf imx28 -c $(TOPDIR)/board/$(BOARDDIR)/u-boot.bd \
-                       -o $(obj)u-boot.sb
+$(obj)u-boot.bd:       $(TOPDIR)/board/$(BOARDDIR)/u-boot.bd
+               sed "s:@@BUILD_DIR@@:$(obj):g" $< > $@
+
+$(obj)u-boot.sb:       $(obj)u-boot.bd elftosb $(obj)u-boot.bin $(obj)spl/u-boot-spl.bin
+               $(TOPDIR)/tools/elftosb/bld/linux/elftosb -zdf imx28 -c $< -o $@
 
 ifeq ($(CONFIG_SANDBOX),y)
 GEN_UBOOT = \
@@ -515,6 +518,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.
@@ -556,6 +561,13 @@ SYSTEM_MAP = \
 $(obj)System.map:      $(obj)u-boot
                @$(call SYSTEM_MAP,$<) > $(obj)System.map
 
+checkthumb:
+       @if test $(call cc-version) -lt 0404; then \
+               echo -n '*** Your GCC does not produce working '; \
+               echo 'binaries in THUMB mode.'; \
+               echo '*** Your board is configured for THUMB mode.'; \
+               false; \
+       fi
 #
 # Auto-generate the autoconf.mk file (which is included by all makefiles)
 #
diff --git a/README b/README
index 79016e6..6919392 100644 (file)
--- a/README
+++ b/README
@@ -432,6 +432,14 @@ The following options need to be configured:
                Select high exception vectors of the ARM core, e.g., do not
                clear the V bit of the c1 register of CP15.
 
+               CONFIG_SYS_THUMB_BUILD
+
+               Use this flag to build U-Boot using the Thumb instruction
+               set for ARM architectures. Thumb instruction set provides
+               better code density. For ARM architectures that support
+               Thumb2 this flag will result in Thumb2 code generated by
+               GCC.
+
 - Linux Kernel Interface:
                CONFIG_CLOCKS_IN_MHZ
 
index 3c5f987..6d6109e 100644 (file)
@@ -33,25 +33,38 @@ endif
 
 PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__
 
-# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb:
-PF_CPPFLAGS_ARM := $(call cc-option,-marm,)
+# Choose between ARM/Thumb instruction sets
+ifeq ($(CONFIG_SYS_THUMB_BUILD),y)
+PF_CPPFLAGS_ARM := $(call cc-option, -mthumb -mthumb-interwork,\
+                       $(call cc-option,-marm,)\
+                       $(call cc-option,-mno-thumb-interwork,)\
+               )
+else
+PF_CPPFLAGS_ARM := $(call cc-option,-marm,) \
+               $(call cc-option,-mno-thumb-interwork,)
+endif
+
+# Only test once
+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 -mno-thumb-interwork
+#      -mabi=aapcs-linux
 # - with ELDK 4.1 (gcc 4.x, no EABI), use:
-#      -mabi=apcs-gnu -mno-thumb-interwork
+#      -mabi=apcs-gnu
 # - with ELDK 3.1 (gcc 3.x), use:
-#      -mapcs-32 -mno-thumb-interwork
+#      -mapcs-32
 PF_CPPFLAGS_ABI := $(call cc-option,\
-                       -mabi=aapcs-linux -mno-thumb-interwork,\
+                       -mabi=aapcs-linux,\
                        $(call cc-option,\
                                -mapcs-32,\
                                $(call cc-option,\
                                        -mabi=apcs-gnu,\
                                )\
-                       ) $(call cc-option,-mno-thumb-interwork,)\
+                       )\
                )
 PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_ARM) $(PF_CPPFLAGS_ABI)
 
index ffb2e6c..6a3a1bb 100644 (file)
@@ -31,3 +31,9 @@ PLATFORM_CPPFLAGS += -march=armv5te
 # =========================================================================
 PF_RELFLAGS_SLB_AT := $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
 PLATFORM_RELFLAGS += $(PF_RELFLAGS_SLB_AT)
+
+ifneq ($(CONFIG_IMX_CONFIG),)
+
+ALL-y  += $(obj)u-boot.imx
+
+endif
index 626384c..a56432e 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <lcd.h>
 #include <asm/system.h>
 
 static void cache_flush(void);
@@ -46,6 +47,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 9cadb7c..8b07dae 100644 (file)
 #include <asm/io.h>
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/imx25-pinmux.h>
+#include <asm/arch/clock.h>
 #ifdef CONFIG_MXC_MMC
 #include <asm/arch/mxcmmc.h>
 #endif
 
+#ifdef CONFIG_FSL_ESDHC
+DECLARE_GLOBAL_DATA_PTR;
+#endif
+
 /*
  *  get the system pll clock in Hz
  *
@@ -105,6 +110,20 @@ ulong imx_get_perclk(int clk)
        return lldiv(fref, div);
 }
 
+unsigned int mxc_get_clock(enum mxc_clock clk)
+{
+       if (clk >= MXC_CLK_NUM)
+               return -1;
+       switch (clk) {
+       case MXC_ARM_CLK:
+               return imx_get_armclk();
+       case MXC_FEC_CLK:
+               return imx_get_ahbclk();
+       default:
+               return imx_get_perclk(clk);
+       }
+}
+
 u32 get_cpu_rev(void)
 {
        u32 srev;
@@ -182,6 +201,14 @@ int cpu_eth_init(bd_t *bis)
 #endif
 }
 
+int get_clocks(void)
+{
+#ifdef CONFIG_FSL_ESDHC
+       gd->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
+#endif
+       return 0;
+}
+
 /*
  * Initializes on-chip MMC controllers.
  * to override, implement board_mmc_init()
index a2e3f77..674a3af 100644 (file)
@@ -28,7 +28,7 @@ LIB   = $(obj)lib$(SOC).o
 COBJS  = clock.o mx28.o iomux.o timer.o
 
 ifdef  CONFIG_SPL_BUILD
-COBJS  += spl_boot.o spl_mem_init.o spl_power_init.o
+COBJS  += spl_boot.o spl_lradc_init.o spl_mem_init.o spl_power_init.o
 endif
 
 SRCS   := $(START:.o=.S) $(COBJS:.o=.c)
diff --git a/arch/arm/cpu/arm926ejs/mx28/debug.c b/arch/arm/cpu/arm926ejs/mx28/debug.c
new file mode 100644 (file)
index 0000000..8444ba7
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Boot Prep common file
+ *
+ * Copyright 2008-2009 Freescale Semiconductor
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <stdarg.h>
+//#include <stdlib.h>
+
+#include <common.h>
+
+void printhex(int data)
+{
+       int i;
+       char c;
+
+       for (i = sizeof(int) * 2 - 1; i >= 0; i--) {
+               c = data >> (i * 4);
+               c &= 0xf;
+               if (c > 9)
+                       serial_putc(c - 10 + 'a');
+               else
+                       serial_putc(c + '0');
+       }
+}
+
+void printdec(int data)
+{
+       unsigned int m;
+       char str[10] = { 0, };
+       int i;
+
+       if (data == 0) {
+               serial_putc('0');
+               return;
+       } else if (data < 0) {
+               serial_putc('-');
+               data = -data;
+       }
+       m = data;
+       for (i = 0; m > 0; i++) {
+               str[i] = m % 10 + '0';
+               m /= 10;
+       }
+       for (i--; i >= 0; i--) {
+               serial_putc(str[i]);
+       }
+}
+
+void dprintf(const char *fmt, ...)
+{
+       va_list args;
+       const char *fp = fmt;
+
+       if (!fmt)
+               return;
+
+       va_start(args, fmt);
+       while (*fp) {
+               if (*fp == '%') {
+                       fp++;
+                       switch (*fp) {
+                       case 'c':
+                               serial_putc(va_arg(args, int));
+                               break;
+
+                       case 's':
+                               serial_puts(va_arg(args, const char *));
+                               break;
+
+                       case 'd':
+                       case 'u':
+                       case 'i':
+                               printdec(va_arg(args, int));
+                               break;
+
+                       case 'p':
+                               serial_puts("0x");
+                       case 'x':
+                       case 'X':
+                               printhex(va_arg(args, int));
+                               break;
+
+                       case '%':
+                               serial_putc('%');
+                               break;
+
+                       default:
+                               dprintf("\nUnsupported format string token '%c'(%x) in '%s'\n",
+                                       *fp, *fp, fmt);
+                       }
+               } else {
+                       if (*fp == '\n')
+                               serial_putc('\r');
+                       serial_putc(*fp);
+               }
+               fp++;
+       }
+       va_end(args);
+}
diff --git a/arch/arm/cpu/arm926ejs/mx28/debug.h b/arch/arm/cpu/arm926ejs/mx28/debug.h
new file mode 100644 (file)
index 0000000..0a7588f
--- /dev/null
@@ -0,0 +1,14 @@
+#ifdef DEBUG
+extern void printhex(int data);
+extern void printdec(int data);
+extern void dprintf(const char *fmt, ...);
+static int debug = 1;
+#define dbg_lvl(lvl)           (debug > (lvl))
+#else
+#define dbg_lvl(lvl)           0
+#define printhex(d)            do { } while (0)
+#define printdec(d)            do { } while (0)
+#define dprintf(lvl, fmt...)   do { } while (0)
+#endif
+
+#define dbg(lvl, fmt...)       do { if (dbg_lvl(lvl)) dprintf(fmt); } while (0)
index dc0338d..887ab71 100644 (file)
@@ -51,9 +51,16 @@ void reset_cpu(ulong ignored) __attribute__((noreturn));
 
 void reset_cpu(ulong ignored)
 {
-
        struct mx28_rtc_regs *rtc_regs =
                (struct mx28_rtc_regs *)MXS_RTC_BASE;
+       struct mx28_lcdif_regs *lcdif_regs =
+               (struct mx28_lcdif_regs *)MXS_LCDIF_BASE;
+
+       /*
+        * Shut down the LCD controller as it interferes with BootROM boot mode
+        * pads sampling.
+        */
+       writel(LCDIF_CTRL_RUN, &lcdif_regs->hw_lcdif_ctrl_clr);
 
        /* Wait 1 uS before doing the actual watchdog reset */
        writel(1, &rtc_regs->hw_rtc_watchdog);
@@ -74,11 +81,19 @@ void enable_caches(void)
 #endif
 }
 
+#define        MX28_HW_DIGCTL_MICROSECONDS     (void *)0x8001c0c0
+
 int mx28_wait_mask_set(struct mx28_register_32 *reg, uint32_t mask, int timeout)
 {
-       while (--timeout) {
-               if ((readl(&reg->reg) & mask) == mask)
-                       break;
+       uint32_t start = readl(MX28_HW_DIGCTL_MICROSECONDS);
+
+       /* Wait for at least one microsecond for the bit mask to be set */
+       while (readl(MX28_HW_DIGCTL_MICROSECONDS) - start <= 1 || --timeout) {
+               if ((readl(&reg->reg) & mask) == mask) {
+                       while (readl(MX28_HW_DIGCTL_MICROSECONDS) - start <= 1)
+                               ;
+                       return 0;
+               }
                udelay(1);
        }
 
@@ -87,9 +102,15 @@ int mx28_wait_mask_set(struct mx28_register_32 *reg, uint32_t mask, int timeout)
 
 int mx28_wait_mask_clr(struct mx28_register_32 *reg, uint32_t mask, int timeout)
 {
-       while (--timeout) {
-               if ((readl(&reg->reg) & mask) == 0)
-                       break;
+       uint32_t start = readl(MX28_HW_DIGCTL_MICROSECONDS);
+
+       /* Wait for at least one microsecond for the bit mask to be cleared */
+       while (readl(MX28_HW_DIGCTL_MICROSECONDS) - start <= 1 || --timeout) {
+               if ((readl(&reg->reg) & mask) == 0) {
+                       while (readl(MX28_HW_DIGCTL_MICROSECONDS) - start <= 1)
+                               ;
+                       return 0;
+               }
                udelay(1);
        }
 
@@ -101,8 +122,11 @@ int mx28_reset_block(struct mx28_register_32 *reg)
        /* Clear SFTRST */
        writel(MX28_BLOCK_SFTRST, &reg->reg_clr);
 
-       if (mx28_wait_mask_clr(reg, MX28_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
+       if (mx28_wait_mask_clr(reg, MX28_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) {
+               printf("TIMEOUT waiting for SFTRST[%p] to clear: %08x\n",
+                       reg, readl(&reg->reg));
                return 1;
+       }
 
        /* Clear CLKGATE */
        writel(MX28_BLOCK_CLKGATE, &reg->reg_clr);
@@ -111,20 +135,29 @@ int mx28_reset_block(struct mx28_register_32 *reg)
        writel(MX28_BLOCK_SFTRST, &reg->reg_set);
 
        /* Wait for CLKGATE being set */
-       if (mx28_wait_mask_set(reg, MX28_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
+       if (mx28_wait_mask_set(reg, MX28_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) {
+               printf("TIMEOUT waiting for CLKGATE[%p] to set: %08x\n",
+                       reg, readl(&reg->reg));
                return 1;
+       }
 
        /* Clear SFTRST */
        writel(MX28_BLOCK_SFTRST, &reg->reg_clr);
 
-       if (mx28_wait_mask_clr(reg, MX28_BLOCK_SFTRST, RESET_MAX_TIMEOUT))
+       if (mx28_wait_mask_clr(reg, MX28_BLOCK_SFTRST, RESET_MAX_TIMEOUT)) {
+               printf("TIMEOUT waiting for SFTRST[%p] to clear: %08x\n",
+                       reg, readl(&reg->reg));
                return 1;
+       }
 
        /* Clear CLKGATE */
        writel(MX28_BLOCK_CLKGATE, &reg->reg_clr);
 
-       if (mx28_wait_mask_clr(reg, MX28_BLOCK_CLKGATE, RESET_MAX_TIMEOUT))
+       if (mx28_wait_mask_clr(reg, MX28_BLOCK_CLKGATE, RESET_MAX_TIMEOUT)) {
+               printf("TIMEOUT waiting for CLKGATE[%p] to clear: %08x\n",
+                       reg, readl(&reg->reg));
                return 1;
+       }
 
        return 0;
 }
@@ -185,8 +218,12 @@ int arch_cpu_init(void)
 #if defined(CONFIG_DISPLAY_CPUINFO)
 int print_cpuinfo(void)
 {
+       struct mx28_spl_data *data = (struct mx28_spl_data *)
+               ((CONFIG_SYS_TEXT_BASE - sizeof(struct mx28_spl_data)) & ~0xf);
+
        printf("Freescale i.MX28 family at %d MHz\n",
                        mxc_get_clock(MXC_ARM_CLK) / 1000000);
+       printf("BOOT:  %s\n", mx28_boot_modes[data->boot_mode_idx].mode);
        return 0;
 }
 #endif
@@ -220,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
@@ -279,22 +319,16 @@ void imx_get_mac_from_fuse(int dev_id, unsigned char *mac)
 
 int mx28_dram_init(void)
 {
-       struct mx28_digctl_regs *digctl_regs =
-               (struct mx28_digctl_regs *)MXS_DIGCTL_BASE;
-       uint32_t sz[2];
-
-       sz[0] = readl(&digctl_regs->hw_digctl_scratch0);
-       sz[1] = readl(&digctl_regs->hw_digctl_scratch1);
+       struct mx28_spl_data *data = (struct mx28_spl_data *)
+               ((CONFIG_SYS_TEXT_BASE - sizeof(struct mx28_spl_data)) & ~0xf);
 
-       if (sz[0] != sz[1]) {
+       if (data->mem_dram_size == 0) {
                printf("MX28:\n"
-                       "Error, the RAM size in HW_DIGCTRL_SCRATCH0 and\n"
-                       "HW_DIGCTRL_SCRATCH1 is not the same. Please\n"
-                       "verify these two registers contain valid RAM size!\n");
+                       "Error, the RAM size passed up from SPL is 0!\n");
                hang();
        }
 
-       gd->ram_size = sz[0];
+       gd->ram_size = data->mem_dram_size;
        return 0;
 }
 
index 98d3631..e3a4493 100644 (file)
@@ -37,5 +37,9 @@ static inline void mx28_power_wait_pswitch(void) { }
 #endif
 
 void mx28_mem_init(void);
+uint32_t mx28_mem_get_size(void);
+
+void mx28_lradc_init(void);
+void mx28_lradc_enable_batt_measurement(void);
 
 #endif /* __M28_INIT_H__ */
index dfb8309..f0d012d 100644 (file)
@@ -28,6 +28,8 @@
 #include <asm/io.h>
 #include <asm/arch/iomux-mx28.h>
 #include <asm/arch/imx-regs.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/gpio.h>
 
 #include "mx28_init.h"
 
  * 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 the magic automagically.
+ */
 #define        HW_DIGCTRL_MICROSECONDS 0x8001c0c0
 void early_delay(int delay)
 {
        uint32_t st = readl(HW_DIGCTRL_MICROSECONDS);
-       st += delay;
-       while (st > readl(HW_DIGCTRL_MICROSECONDS))
-               ;
+
+       while (readl(HW_DIGCTRL_MICROSECONDS) - st < delay);
+}
+
+#define        MUX_CONFIG_BOOTMODE_PAD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
+const iomux_cfg_t iomux_boot[] = {
+       MX28_PAD_LCD_D00__GPIO_1_0 | MUX_CONFIG_BOOTMODE_PAD,
+       MX28_PAD_LCD_D01__GPIO_1_1 | MUX_CONFIG_BOOTMODE_PAD,
+       MX28_PAD_LCD_D02__GPIO_1_2 | MUX_CONFIG_BOOTMODE_PAD,
+       MX28_PAD_LCD_D03__GPIO_1_3 | MUX_CONFIG_BOOTMODE_PAD,
+       MX28_PAD_LCD_D04__GPIO_1_4 | MUX_CONFIG_BOOTMODE_PAD,
+       MX28_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD,
+};
+
+uint8_t mx28_get_bootmode_index(void)
+{
+       uint8_t bootmode = 0;
+       int i;
+       uint8_t masked;
+
+       /* Setup IOMUX of bootmode pads to GPIO */
+       mxs_iomux_setup_multiple_pads(iomux_boot, ARRAY_SIZE(iomux_boot));
+
+       /* Setup bootmode pins as GPIO input */
+       gpio_direction_input(MX28_PAD_LCD_D00__GPIO_1_0);
+       gpio_direction_input(MX28_PAD_LCD_D01__GPIO_1_1);
+       gpio_direction_input(MX28_PAD_LCD_D02__GPIO_1_2);
+       gpio_direction_input(MX28_PAD_LCD_D03__GPIO_1_3);
+       gpio_direction_input(MX28_PAD_LCD_D04__GPIO_1_4);
+       gpio_direction_input(MX28_PAD_LCD_D05__GPIO_1_5);
+
+       /* Read bootmode pads */
+       bootmode |= (gpio_get_value(MX28_PAD_LCD_D00__GPIO_1_0) ? 1 : 0) << 0;
+       bootmode |= (gpio_get_value(MX28_PAD_LCD_D01__GPIO_1_1) ? 1 : 0) << 1;
+       bootmode |= (gpio_get_value(MX28_PAD_LCD_D02__GPIO_1_2) ? 1 : 0) << 2;
+       bootmode |= (gpio_get_value(MX28_PAD_LCD_D03__GPIO_1_3) ? 1 : 0) << 3;
+       bootmode |= (gpio_get_value(MX28_PAD_LCD_D04__GPIO_1_4) ? 1 : 0) << 4;
+       bootmode |= (gpio_get_value(MX28_PAD_LCD_D05__GPIO_1_5) ? 1 : 0) << 5;
+
+       for (i = 0; i < ARRAY_SIZE(mx28_boot_modes); i++) {
+               masked = bootmode & mx28_boot_modes[i].boot_mask;
+               if (masked == mx28_boot_modes[i].boot_pads)
+                       break;
+       }
+
+       return i;
 }
 
 void mx28_common_spl_init(const iomux_cfg_t *iomux_setup,
                        const unsigned int iomux_size)
 {
+       struct mx28_spl_data *data = (struct mx28_spl_data *)
+               ((CONFIG_SYS_TEXT_BASE - sizeof(struct mx28_spl_data)) & ~0xf);
+       uint8_t bootmode = mx28_get_bootmode_index();
+
        mxs_iomux_setup_multiple_pads(iomux_setup, iomux_size);
        mx28_power_init();
+
        mx28_mem_init();
+       data->mem_dram_size = mx28_mem_get_size();
+
+       data->boot_mode_idx = bootmode;
+
        mx28_power_wait_pswitch();
 }
 
-/* Support aparatus */
+/* Support apparatus */
 inline void board_init_f(unsigned long bootflag)
 {
        for (;;)
@@ -68,11 +126,14 @@ inline void board_init_r(gd_t *id, ulong dest_addr)
                ;
 }
 
+#ifndef CONFIG_SPL_SERIAL_SUPPORT
 void serial_putc(const char c) {}
 void serial_puts(const char *s) {}
+#endif
 void hang(void) __attribute__ ((noreturn));
 void hang(void)
 {
+       serial_puts("ERROR: please reset the target\n");
        for (;;)
                ;
 }
diff --git a/arch/arm/cpu/arm926ejs/mx28/spl_lradc_init.c b/arch/arm/cpu/arm926ejs/mx28/spl_lradc_init.c
new file mode 100644 (file)
index 0000000..88a603c
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * Freescale i.MX28 Battery measurement init
+ *
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * on behalf of DENX Software Engineering GmbH
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <config.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+
+#include "mx28_init.h"
+
+void mx28_lradc_init(void)
+{
+       struct mx28_lradc_regs *regs = (struct mx28_lradc_regs *)MXS_LRADC_BASE;
+
+       writel(LRADC_CTRL0_SFTRST, &regs->hw_lradc_ctrl0_clr);
+       writel(LRADC_CTRL0_CLKGATE, &regs->hw_lradc_ctrl0_clr);
+       writel(LRADC_CTRL0_ONCHIP_GROUNDREF, &regs->hw_lradc_ctrl0_clr);
+
+       clrsetbits_le32(&regs->hw_lradc_ctrl3,
+                       LRADC_CTRL3_CYCLE_TIME_MASK,
+                       LRADC_CTRL3_CYCLE_TIME_6MHZ);
+
+       clrsetbits_le32(&regs->hw_lradc_ctrl4,
+                       LRADC_CTRL4_LRADC7SELECT_MASK |
+                       LRADC_CTRL4_LRADC6SELECT_MASK,
+                       LRADC_CTRL4_LRADC7SELECT_CHANNEL7 |
+                       LRADC_CTRL4_LRADC6SELECT_CHANNEL10);
+}
+
+void mx28_lradc_enable_batt_measurement(void)
+{
+       struct mx28_lradc_regs *regs = (struct mx28_lradc_regs *)MXS_LRADC_BASE;
+
+       /* Check if the channel is present at all. */
+       if (!(readl(&regs->hw_lradc_status) & LRADC_STATUS_CHANNEL7_PRESENT))
+               return;
+
+       writel(LRADC_CTRL1_LRADC7_IRQ_EN, &regs->hw_lradc_ctrl1_clr);
+       writel(LRADC_CTRL1_LRADC7_IRQ, &regs->hw_lradc_ctrl1_clr);
+
+       clrsetbits_le32(&regs->hw_lradc_conversion,
+                       LRADC_CONVERSION_SCALE_FACTOR_MASK,
+                       LRADC_CONVERSION_SCALE_FACTOR_LI_ION);
+       writel(LRADC_CONVERSION_AUTOMATIC, &regs->hw_lradc_conversion_set);
+
+       /* Configure the channel. */
+       writel((1 << 7) << LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET,
+               &regs->hw_lradc_ctrl2_clr);
+       writel(0xffffffff, &regs->hw_lradc_ch7_clr);
+       clrbits_le32(&regs->hw_lradc_ch7, LRADC_CH_NUM_SAMPLES_MASK);
+       writel(LRADC_CH_ACCUMULATE, &regs->hw_lradc_ch7_clr);
+
+       /* Schedule the channel. */
+       writel(1 << 7, &regs->hw_lradc_ctrl0_set);
+
+       /* Start the channel sampling. */
+       writel(((1 << 7) << LRADC_DELAY_TRIGGER_LRADCS_OFFSET) |
+               ((1 << 3) << LRADC_DELAY_TRIGGER_DELAYS_OFFSET) |
+               100, &regs->hw_lradc_delay3);
+
+       writel(0xffffffff, &regs->hw_lradc_ch7_clr);
+
+       writel(LRADC_DELAY_KICK, &regs->hw_lradc_delay3_set);
+}
index 911bbef..88a1259 100644 (file)
 
 #include "mx28_init.h"
 
-uint32_t dram_vals[] = {
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000100, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00010101, 0x01010101,
-       0x000f0f01, 0x0f02010a, 0x00000000, 0x00010101,
-       0x00000100, 0x00000100, 0x00000000, 0x00000002,
-       0x01010000, 0x05060302, 0x06005003, 0x0a0000c8,
-       0x02009c40, 0x0000030c, 0x0036a609, 0x031a0612,
-       0x02030202, 0x00c8001c, 0x00000000, 0x00000000,
-       0x00012100, 0xffff0303, 0x00012100, 0xffff0303,
-       0x00012100, 0xffff0303, 0x00012100, 0xffff0303,
-       0x00000003, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000612, 0x01000F02,
-       0x06120612, 0x00000200, 0x00020007, 0xf5014b27,
-       0xf5014b27, 0xf5014b27, 0xf5014b27, 0x07000300,
-       0x07000300, 0x07000300, 0x07000300, 0x00000006,
-       0x00000000, 0x00000000, 0x01000000, 0x01020408,
-       0x08040201, 0x000f1133, 0x00000000, 0x00001f04,
-       0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04,
-       0x00001f04, 0x00001f04, 0x00001f04, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00010000, 0x00020304,
-       0x00000004, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00000000, 0x00000000, 0x01010000,
-       0x01000000, 0x03030000, 0x00010303, 0x01020202,
-       0x00000000, 0x02040303, 0x21002103, 0x00061200,
-       0x06120612, 0x04320432, 0x04320432, 0x00040004,
-       0x00040004, 0x00000000, 0x00000000, 0x00000000,
-       0x00000000, 0x00010001
-};
-
-void init_m28_200mhz_ddr2(void)
-{
-       int i;
+extern void mx28_ddr2_setup(void) __attribute__((weak,
+               alias("mx28_ddr2_setup_missing")));
 
-       for (i = 0; i < ARRAY_SIZE(dram_vals); i++)
-               writel(dram_vals[i], MXS_DRAM_BASE + (4 * i));
+static void mx28_ddr2_setup_missing(void)
+{
+       serial_puts("platform specific mx28_ddr_setup() is missing\n");
 }
 
-void mx28_mem_init_clock(void)
+static void mx28_mem_init_clock(void)
 {
        struct mx28_clkctrl_regs *clkctrl_regs =
                (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
@@ -107,21 +56,20 @@ void mx28_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);
 }
 
-void mx28_mem_setup_cpu_and_hbus(void)
+static void mx28_mem_setup_cpu_and_hbus(void)
 {
        struct mx28_clkctrl_regs *clkctrl_regs =
                (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
@@ -136,62 +84,49 @@ void mx28_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);
-}
 
-void mx28_mem_setup_vdda(void)
-{
-       struct mx28_power_regs *power_regs =
-               (struct mx28_power_regs *)MXS_POWER_BASE;
-
-       writel((0xc << POWER_VDDACTRL_TRG_OFFSET) |
-               (0x7 << POWER_VDDACTRL_BO_OFFSET_OFFSET) |
-               POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW,
-               &power_regs->hw_power_vddactrl);
+       early_delay(15000);
 }
 
-void mx28_mem_setup_vddd(void)
+#define        HW_DIGCTRL_SCRATCH0     0x8001c280
+#define        HW_DIGCTRL_SCRATCH1     0x8001c290
+static void data_abort_memdetect_handler(void) __attribute__((naked));
+static void data_abort_memdetect_handler(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_power_regs *)MXS_POWER_BASE;
-
-       writel((0x1c << POWER_VDDDCTRL_TRG_OFFSET) |
-               (0x7 << POWER_VDDDCTRL_BO_OFFSET_OFFSET) |
-               POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW,
-               &power_regs->hw_power_vdddctrl);
+       asm volatile("subs pc, r14, #4");
 }
 
-void mx28_mem_get_size(void)
+uint32_t mx28_mem_get_size(void)
 {
-       struct mx28_digctl_regs *digctl_regs =
-               (struct mx28_digctl_regs *)MXS_DIGCTL_BASE;
        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;
+       vt[4] = (uint32_t)data_abort_memdetect_handler;
 
        sz = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
-       writel(sz, &digctl_regs->hw_digctl_scratch0);
-       writel(sz, &digctl_regs->hw_digctl_scratch1);
 
        /* Restore the old DABT handler. */
        vt[4] = da;
+
+       return sz;
 }
 
 void mx28_mem_init(void)
@@ -209,12 +144,11 @@ void mx28_mem_init(void)
        writel(CLKCTRL_PLL0CTRL0_POWER,
                &clkctrl_regs->hw_clkctrl_pll0ctrl0_set);
 
-       early_delay(11000);
+       /* enabling the PLL requires a 10µs delay before use as clk source */
+       early_delay(11);
 
        mx28_mem_init_clock();
 
-       mx28_mem_setup_vdda();
-
        /*
         * Configure the DRAM registers
         */
@@ -222,7 +156,7 @@ void mx28_mem_init(void)
        /* Clear START bit from DRAM_CTL16 */
        clrbits_le32(MXS_DRAM_BASE + 0x40, 1);
 
-       init_m28_200mhz_ddr2();
+       mx28_ddr2_setup();
 
        /* Clear SREFRESH bit from DRAM_CTL17 */
        clrbits_le32(MXS_DRAM_BASE + 0x44, 1);
@@ -234,11 +168,5 @@ void mx28_mem_init(void)
        while (!(readl(MXS_DRAM_BASE + 0xe8) & (1 << 20)))
                ;
 
-       mx28_mem_setup_vddd();
-
-       early_delay(10000);
-
        mx28_mem_setup_cpu_and_hbus();
-
-       mx28_mem_get_size();
 }
index aa4117d..6b74e2e 100644 (file)
 
 #include "mx28_init.h"
 
-void mx28_power_clock2xtal(void)
+#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     1500
+#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 mx28_power_regs *power_regs = (void *)MXS_POWER_BASE;
+
+static void mx28_power_clock2xtal(void)
 {
        struct mx28_clkctrl_regs *clkctrl_regs =
                (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
@@ -40,19 +100,19 @@ void mx28_power_clock2xtal(void)
                &clkctrl_regs->hw_clkctrl_clkseq_set);
 }
 
-void mx28_power_clock2pll(void)
+static void mx28_power_clock2pll(void)
 {
        struct mx28_clkctrl_regs *clkctrl_regs =
                (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
 
-       writel(CLKCTRL_PLL0CTRL0_POWER,
-               &clkctrl_regs->hw_clkctrl_pll0ctrl0_set);
+       setbits_le32(&clkctrl_regs->hw_clkctrl_pll0ctrl0,
+                       CLKCTRL_PLL0CTRL0_POWER);
        early_delay(100);
-       writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
-               &clkctrl_regs->hw_clkctrl_clkseq_clr);
+       setbits_le32(&clkctrl_regs->hw_clkctrl_clkseq,
+                       CLKCTRL_CLKSEQ_BYPASS_CPU);
 }
 
-void mx28_power_clear_auto_restart(void)
+static void mx28_power_clear_auto_restart(void)
 {
        struct mx28_rtc_regs *rtc_regs =
                (struct mx28_rtc_regs *)MXS_RTC_BASE;
@@ -85,11 +145,8 @@ void mx28_power_clear_auto_restart(void)
                ;
 }
 
-void mx28_power_set_linreg(void)
+static void mx28_power_set_linreg(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_power_regs *)MXS_POWER_BASE;
-
        /* Set linear regulator 25mV below switching converter */
        clrsetbits_le32(&power_regs->hw_power_vdddctrl,
                        POWER_VDDDCTRL_LINREG_OFFSET_MASK,
@@ -104,11 +161,64 @@ void mx28_power_set_linreg(void)
                        POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
 }
 
-void mx28_power_setup_5v_detect(void)
+int mx28_get_batt_volt(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_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;
+       return volt;
+}
+
+int mx28_is_batt_ready(void)
+{
+       return (mx28_get_batt_volt() >= 3600);
+}
+
+int mx28_is_batt_good(void)
+{
+       struct mx28_power_regs *power_regs =
+               (struct mx28_power_regs *)MXS_POWER_BASE;
+       uint32_t volt = mx28_get_batt_volt();
+
+       if ((volt >= 2400) && (volt <= 4300))
+               return 1;
+
+       clrsetbits_le32(&power_regs->hw_power_5vctrl,
+               POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
+               0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
+       writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
+               &power_regs->hw_power_5vctrl_clr);
 
+       clrsetbits_le32(&power_regs->hw_power_charge,
+               POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
+               POWER_CHARGE_STOP_ILIMIT_10MA | 0x3);
+
+       writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_clr);
+       writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
+               &power_regs->hw_power_5vctrl_clr);
+
+       early_delay(500000);
+
+       volt = mx28_get_batt_volt();
+
+       if (volt >= 3500)
+               return 0;
+
+       if (volt >= 2400)
+               return 1;
+
+       writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
+               &power_regs->hw_power_charge_clr);
+       writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
+
+       return 0;
+}
+
+static void mx28_power_setup_5v_detect(void)
+{
        /* Start 5V detection */
        clrsetbits_le32(&power_regs->hw_power_5vctrl,
                        POWER_5VCTRL_VBUSVALID_TRSH_MASK,
@@ -116,11 +226,8 @@ void mx28_power_setup_5v_detect(void)
                        POWER_5VCTRL_PWRUP_VBUS_CMPS);
 }
 
-void mx28_src_power_init(void)
+static void mx28_src_power_init(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_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);
@@ -129,8 +236,14 @@ void mx28_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,
@@ -141,17 +254,16 @@ void mx28_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);
+       }
 }
 
-void mx28_power_init_4p2_params(void)
+static void mx28_power_init_4p2_params(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_power_regs *)MXS_POWER_BASE;
-
        /* Setup 4P2 parameters */
        clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
                POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK,
@@ -171,10 +283,8 @@ void mx28_power_init_4p2_params(void)
                0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
 }
 
-void mx28_enable_4p2_dcdc_input(int xfer)
+static void mx28_enable_4p2_dcdc_input(int xfer)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_power_regs *)MXS_POWER_BASE;
        uint32_t tmp, vbus_thresh, vbus_5vdetect, pwd_bo;
        uint32_t prev_5v_brnout, prev_5v_droop;
 
@@ -267,10 +377,8 @@ void mx28_enable_4p2_dcdc_input(int xfer)
                                POWER_CTRL_ENIRQ_VDD5V_DROOP);
 }
 
-void mx28_power_init_4p2_regulator(void)
+static void mx28_power_init_4p2_regulator(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_power_regs *)MXS_POWER_BASE;
        uint32_t tmp, tmp2;
 
        setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2);
@@ -351,11 +459,8 @@ void mx28_power_init_4p2_regulator(void)
        writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
 }
 
-void mx28_power_init_dcdc_4p2_source(void)
+static void mx28_power_init_dcdc_4p2_source(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_power_regs *)MXS_POWER_BASE;
-
        if (!(readl(&power_regs->hw_power_dcdc4p2) &
                POWER_DCDC4P2_ENABLE_DCDC)) {
                hang();
@@ -373,10 +478,8 @@ void mx28_power_init_dcdc_4p2_source(void)
        }
 }
 
-void mx28_power_enable_4p2(void)
+static void mx28_power_enable_4p2(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_power_regs *)MXS_POWER_BASE;
        uint32_t vdddctrl, vddactrl, vddioctrl;
        uint32_t tmp;
 
@@ -399,9 +502,14 @@ void mx28_power_enable_4p2(void)
        mx28_power_init_4p2_regulator();
 
        /* Shutdown battery (none present) */
-       clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK);
-       writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
-       writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr);
+       if (!mx28_is_batt_ready()) {
+               clrbits_le32(&power_regs->hw_power_dcdc4p2,
+                               POWER_DCDC4P2_BO_MASK);
+               writel(POWER_CTRL_DCDC4P2_BO_IRQ,
+                               &power_regs->hw_power_ctrl_clr);
+               writel(POWER_CTRL_ENIRQ_DCDC4P2_BO,
+                               &power_regs->hw_power_ctrl_clr);
+       }
 
        mx28_power_init_dcdc_4p2_source();
 
@@ -427,11 +535,8 @@ void mx28_power_enable_4p2(void)
                        &power_regs->hw_power_charge_clr);
 }
 
-void mx28_boot_valid_5v(void)
+static void mx28_boot_valid_5v(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_power_regs *)MXS_POWER_BASE;
-
        /*
         * Use VBUSVALID level instead of VDD5V_GT_VDDIO level to trigger a 5V
         * disconnect event. FIXME
@@ -450,19 +555,59 @@ void mx28_boot_valid_5v(void)
        mx28_power_enable_4p2();
 }
 
-void mx28_powerdown(void)
+static void mx28_powerdown(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_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);
 }
 
-void mx28_handle_5v_conflict(void)
+void mx28_batt_boot(void)
 {
        struct mx28_power_regs *power_regs =
                (struct mx28_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);
+
+       clrbits_le32(&power_regs->hw_power_dcdc4p2,
+                       POWER_DCDC4P2_ENABLE_DCDC | POWER_DCDC4P2_ENABLE_4P2);
+       writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_clr);
+
+       /* 5V to battery handoff. */
+       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);
+
+       writel(POWER_CTRL_ENIRQ_DCDC4P2_BO, &power_regs->hw_power_ctrl_clr);
+
+       clrsetbits_le32(&power_regs->hw_power_minpwr,
+                       POWER_MINPWR_HALFFETS, POWER_MINPWR_DOUBLE_FETS);
+
+       mx28_power_set_linreg();
+
+       clrbits_le32(&power_regs->hw_power_vdddctrl,
+               POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG);
+
+       clrbits_le32(&power_regs->hw_power_vddactrl,
+               POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG);
+
+       clrbits_le32(&power_regs->hw_power_vddioctrl,
+               POWER_VDDIOCTRL_DISABLE_FET);
+
+       setbits_le32(&power_regs->hw_power_5vctrl,
+               POWER_5VCTRL_PWD_CHARGE_4P2_MASK);
+
+       setbits_le32(&power_regs->hw_power_5vctrl,
+               POWER_5VCTRL_ENABLE_DCDC);
+
+       clrsetbits_le32(&power_regs->hw_power_5vctrl,
+               POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
+               0x8 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
+}
+
+void mx28_handle_5v_conflict(void)
+{
        uint32_t tmp;
 
        setbits_le32(&power_regs->hw_power_vddioctrl,
@@ -483,30 +628,16 @@ void mx28_handle_5v_conflict(void)
                        mx28_powerdown();
                        break;
                }
-       }
-}
 
-int mx28_get_batt_volt(void)
-{
-       struct mx28_power_regs *power_regs =
-               (struct mx28_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;
-       return volt;
-}
-
-int mx28_is_batt_ready(void)
-{
-       return (mx28_get_batt_volt() >= 3600);
+               if (tmp & POWER_STS_PSWITCH_MASK) {
+                       mx28_batt_boot();
+                       break;
+               }
+       }
 }
 
-void mx28_5v_boot(void)
+static void mx28_5v_boot(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_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.
@@ -525,25 +656,49 @@ void mx28_5v_boot(void)
        mx28_handle_5v_conflict();
 }
 
-void mx28_init_batt_bo(void)
+static void mx28_fixed_batt_boot(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_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);
 
-       /* Brownout at 3V */
+       clrbits_le32(&power_regs->hw_power_vddactrl,
+               POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG |
+               POWER_VDDACTRL_DISABLE_STEPPING);
+
+       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 mx28_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);
 }
 
-void mx28_switch_vddd_to_dcdc_source(void)
+static void mx28_switch_vddd_to_dcdc_source(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_power_regs *)MXS_POWER_BASE;
-
        clrsetbits_le32(&power_regs->hw_power_vdddctrl,
                POWER_VDDDCTRL_LINREG_OFFSET_MASK,
                POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
@@ -553,70 +708,24 @@ void mx28_switch_vddd_to_dcdc_source(void)
                POWER_VDDDCTRL_DISABLE_STEPPING);
 }
 
-int mx28_is_batt_good(void)
-{
-       struct mx28_power_regs *power_regs =
-               (struct mx28_power_regs *)MXS_POWER_BASE;
-       uint32_t volt;
-
-       volt = readl(&power_regs->hw_power_battmonitor);
-       volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
-       volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
-       volt *= 8;
-
-       if ((volt >= 2400) && (volt <= 4300))
-               return 1;
-
-       clrsetbits_le32(&power_regs->hw_power_5vctrl,
-               POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
-               0x3 << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
-       writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
-               &power_regs->hw_power_5vctrl_clr);
-
-       clrsetbits_le32(&power_regs->hw_power_charge,
-               POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
-               POWER_CHARGE_STOP_ILIMIT_10MA | 0x3);
-
-       writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_clr);
-       writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
-               &power_regs->hw_power_5vctrl_clr);
-
-       early_delay(500000);
-
-       volt = readl(&power_regs->hw_power_battmonitor);
-       volt &= POWER_BATTMONITOR_BATT_VAL_MASK;
-       volt >>= POWER_BATTMONITOR_BATT_VAL_OFFSET;
-       volt *= 8;
-
-       if (volt >= 3500)
-               return 0;
-
-       if (volt >= 2400)
-               return 1;
-
-       writel(POWER_CHARGE_STOP_ILIMIT_MASK | POWER_CHARGE_BATTCHRG_I_MASK,
-               &power_regs->hw_power_charge_clr);
-       writel(POWER_CHARGE_PWD_BATTCHRG, &power_regs->hw_power_charge_set);
-
-       return 0;
-}
-
-void mx28_power_configure_power_source(void)
+static void mx28_power_configure_power_source(void)
 {
        mx28_src_power_init();
 
-       mx28_5v_boot();
+       if (!fixed_batt_supply)
+               mx28_5v_boot();
+       else
+               mx28_fixed_batt_boot();
+
        mx28_power_clock2pll();
 
        mx28_init_batt_bo();
+
        mx28_switch_vddd_to_dcdc_source();
 }
 
-void mx28_enable_output_rail_protection(void)
+static void mx28_enable_output_rail_protection(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_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);
 
@@ -630,13 +739,14 @@ void mx28_enable_output_rail_protection(void)
                        POWER_VDDIOCTRL_PWDN_BRNOUT);
 }
 
-int mx28_get_vddio_power_source_off(void)
+static inline int mx28_get_vddio_power_source_off(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_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) ==
@@ -655,13 +765,10 @@ int mx28_get_vddio_power_source_off(void)
        }
 
        return 0;
-
 }
 
-int mx28_get_vddd_power_source_off(void)
+static inline int mx28_get_vddd_power_source_off(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_power_regs *)MXS_POWER_BASE;
        uint32_t tmp;
 
        tmp = readl(&power_regs->hw_power_vdddctrl);
@@ -689,67 +796,89 @@ int mx28_get_vddd_power_source_off(void)
        return 0;
 }
 
-void mx28_power_set_vddio(uint32_t new_target, uint32_t new_brownout)
+static inline int mx28_get_vdda_power_source_off(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_power_regs *)MXS_POWER_BASE;
-       uint32_t cur_target, diff, bo_int = 0;
-       uint32_t powered_by_linreg = 0;
+       uint32_t tmp;
 
-       new_brownout = new_target - new_brownout;
+       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;
+       }
 
-       cur_target = readl(&power_regs->hw_power_vddioctrl);
-       cur_target &= POWER_VDDIOCTRL_TRG_MASK;
-       cur_target *= 50;       /* 50 mV step*/
-       cur_target += 2800;     /* 2800 mV lowest */
+       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;
+       }
 
-       powered_by_linreg = mx28_get_vddio_power_source_off();
-       if (new_target > cur_target) {
+       if (!(tmp & POWER_VDDACTRL_ENABLE_LINREG)) {
+               if ((tmp & POWER_VDDACTRL_LINREG_OFFSET_MASK) ==
+                       POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW)
+                       return 1;
+       }
+       return 0;
+}
 
-               if (powered_by_linreg) {
-                       bo_int = readl(&power_regs->hw_power_vddioctrl);
-                       clrbits_le32(&power_regs->hw_power_vddioctrl,
-                                       POWER_CTRL_ENIRQ_VDDIO_BO);
-               }
+static inline void mx28_power_set_vddx(
+       uint32_t new_target, uint32_t new_brownout,
+       uint32_t *reg, const char *name,
+       uint32_t min_trg, uint32_t max_trg,
+       uint8_t step_size,
+       uint32_t trg_mask, uint32_t trg_shift,
+       uint32_t bo_mask, uint32_t bo_shift,
+       int powered_by_linreg)
+{
+       uint32_t cur_target, cur_brownout;
+       uint32_t diff;
+
+       if (new_target < min_trg || new_target > max_trg)
+               new_target = (new_target > max_trg) ? max_trg : min_trg;
+
+       if (new_brownout / step_size > 7)
+               new_brownout = 7 * step_size;
+
+       cur_target = readl(reg);
+
+       cur_brownout = (cur_target & bo_mask) >> bo_shift;
+       cur_brownout *= step_size;
 
-               setbits_le32(&power_regs->hw_power_vddioctrl,
-                               POWER_VDDIOCTRL_BO_OFFSET_MASK);
+       cur_target = (cur_target & trg_mask) >> trg_shift;
+       cur_target *= step_size;
+       cur_target += min_trg;
+       if (cur_target > max_trg)
+               cur_target = max_trg;
+
+       if (new_target == cur_target && new_brownout == cur_brownout)
+               return;
+
+       if (new_target > cur_target) {
+               setbits_le32(reg, bo_mask);
                do {
                        if (new_target - cur_target > 100)
                                diff = cur_target + 100;
                        else
                                diff = new_target;
 
-                       diff -= 2800;
-                       diff /= 50;
+                       diff -= min_trg;
+                       diff /= step_size;
 
-                       clrsetbits_le32(&power_regs->hw_power_vddioctrl,
-                               POWER_VDDIOCTRL_TRG_MASK, diff);
+                       clrsetbits_le32(reg, trg_mask, diff);
 
-                       if (powered_by_linreg ||
-                               (readl(&power_regs->hw_power_sts) &
-                                       POWER_STS_VDD5V_GT_VDDIO))
-                               early_delay(500);
-                       else {
+                       if (powered_by_linreg) {
+                               early_delay(1500);
+                       } else {
                                while (!(readl(&power_regs->hw_power_sts) &
-                                       POWER_STS_DC_OK))
-                                       ;
-
+                                       POWER_STS_DC_OK)) {
+                               }
                        }
 
-                       cur_target = readl(&power_regs->hw_power_vddioctrl);
-                       cur_target &= POWER_VDDIOCTRL_TRG_MASK;
-                       cur_target *= 50;       /* 50 mV step*/
-                       cur_target += 2800;     /* 2800 mV lowest */
+                       cur_target = readl(reg);
+                       cur_target &= trg_mask;
+                       cur_target *= step_size;
+                       cur_target += min_trg;
                } while (new_target > cur_target);
-
-               if (powered_by_linreg) {
-                       writel(POWER_CTRL_VDDIO_BO_IRQ,
-                               &power_regs->hw_power_ctrl_clr);
-                       if (bo_int & POWER_CTRL_ENIRQ_VDDIO_BO)
-                               setbits_le32(&power_regs->hw_power_vddioctrl,
-                                               POWER_CTRL_ENIRQ_VDDIO_BO);
-               }
        } else {
                do {
                        if (cur_target - new_target > 100)
@@ -757,164 +886,151 @@ void mx28_power_set_vddio(uint32_t new_target, uint32_t new_brownout)
                        else
                                diff = new_target;
 
-                       diff -= 2800;
-                       diff /= 50;
+                       diff -= min_trg;
+                       diff /= step_size;
 
-                       clrsetbits_le32(&power_regs->hw_power_vddioctrl,
-                               POWER_VDDIOCTRL_TRG_MASK, diff);
+                       clrsetbits_le32(reg, trg_mask, diff);
 
-                       if (powered_by_linreg ||
-                               (readl(&power_regs->hw_power_sts) &
-                                       POWER_STS_VDD5V_GT_VDDIO))
-                               early_delay(500);
-                       else {
+                       if (powered_by_linreg) {
+                               early_delay(1500);
+                       } else {
                                while (!(readl(&power_regs->hw_power_sts) &
-                                       POWER_STS_DC_OK))
-                                       ;
-
+                                       POWER_STS_DC_OK)) {
+                               }
                        }
 
-                       cur_target = readl(&power_regs->hw_power_vddioctrl);
-                       cur_target &= POWER_VDDIOCTRL_TRG_MASK;
-                       cur_target *= 50;       /* 50 mV step*/
-                       cur_target += 2800;     /* 2800 mV lowest */
+                       cur_target = readl(reg);
+                       cur_target &= trg_mask;
+                       cur_target *= step_size;
+                       cur_target += min_trg;
                } while (new_target < cur_target);
        }
 
-       clrsetbits_le32(&power_regs->hw_power_vddioctrl,
-                       POWER_VDDDCTRL_BO_OFFSET_MASK,
-                       new_brownout << POWER_VDDDCTRL_BO_OFFSET_OFFSET);
+       clrsetbits_le32(reg, bo_mask, (new_brownout / step_size) << bo_shift);
 }
 
-void mx28_power_set_vddd(uint32_t new_target, uint32_t new_brownout)
-{
-       struct mx28_power_regs *power_regs =
-               (struct mx28_power_regs *)MXS_POWER_BASE;
-       uint32_t cur_target, diff, bo_int = 0;
-       uint32_t powered_by_linreg = 0;
+#define __mx28_power_set_vddx(trg, bo, min, max, step, reg, name, lr)  \
+       mx28_power_set_vddx(trg, bo,                                    \
+                       &power_regs->hw_power_##reg##ctrl, #name,       \
+                       min, max, step,                                 \
+                       POWER_##name##CTRL_TRG_MASK,                    \
+                       POWER_##name##CTRL_TRG_OFFSET,                  \
+                       POWER_##name##CTRL_BO_OFFSET_MASK,              \
+                       POWER_##name##CTRL_BO_OFFSET_OFFSET, lr)
 
-       new_brownout = new_target - new_brownout;
-
-       cur_target = readl(&power_regs->hw_power_vdddctrl);
-       cur_target &= POWER_VDDDCTRL_TRG_MASK;
-       cur_target *= 25;       /* 25 mV step*/
-       cur_target += 800;      /* 800 mV lowest */
-
-       powered_by_linreg = mx28_get_vddd_power_source_off();
-       if (new_target > cur_target) {
-               if (powered_by_linreg) {
-                       bo_int = readl(&power_regs->hw_power_vdddctrl);
-                       clrbits_le32(&power_regs->hw_power_vdddctrl,
-                                       POWER_CTRL_ENIRQ_VDDD_BO);
-               }
-
-               setbits_le32(&power_regs->hw_power_vdddctrl,
-                               POWER_VDDDCTRL_BO_OFFSET_MASK);
-
-               do {
-                       if (new_target - cur_target > 100)
-                               diff = cur_target + 100;
-                       else
-                               diff = new_target;
-
-                       diff -= 800;
-                       diff /= 25;
-
-                       clrsetbits_le32(&power_regs->hw_power_vdddctrl,
-                               POWER_VDDDCTRL_TRG_MASK, diff);
+static inline void mx28_power_set_vddd(uint32_t target, uint32_t brownout)
+{
+       int powered_by_linreg = mx28_get_vddd_power_source_off();
+       uint32_t bo_int = 0;
 
-                       if (powered_by_linreg ||
-                               (readl(&power_regs->hw_power_sts) &
-                                       POWER_STS_VDD5V_GT_VDDIO))
-                               early_delay(500);
-                       else {
-                               while (!(readl(&power_regs->hw_power_sts) &
-                                       POWER_STS_DC_OK))
-                                       ;
+       if (powered_by_linreg) {
+               bo_int = readl(&power_regs->hw_power_vdddctrl);
+               clrbits_le32(&power_regs->hw_power_vdddctrl,
+                       POWER_CTRL_ENIRQ_VDDD_BO);
+       }
 
-                       }
+       __mx28_power_set_vddx(target, brownout, 800, 1575, 25, vddd, VDDD,
+                       powered_by_linreg);
 
-                       cur_target = readl(&power_regs->hw_power_vdddctrl);
-                       cur_target &= POWER_VDDDCTRL_TRG_MASK;
-                       cur_target *= 25;       /* 25 mV step*/
-                       cur_target += 800;      /* 800 mV lowest */
-               } while (new_target > cur_target);
+       if (powered_by_linreg) {
+               writel(POWER_CTRL_VDDD_BO_IRQ,
+                       &power_regs->hw_power_ctrl_clr);
+               if (bo_int & POWER_CTRL_ENIRQ_VDDD_BO)
+                       setbits_le32(&power_regs->hw_power_vdddctrl,
+                               POWER_CTRL_ENIRQ_VDDD_BO);
+       }
+}
 
-               if (powered_by_linreg) {
-                       writel(POWER_CTRL_VDDD_BO_IRQ,
-                               &power_regs->hw_power_ctrl_clr);
-                       if (bo_int & POWER_CTRL_ENIRQ_VDDD_BO)
-                               setbits_le32(&power_regs->hw_power_vdddctrl,
-                                               POWER_CTRL_ENIRQ_VDDD_BO);
-               }
-       } else {
-               do {
-                       if (cur_target - new_target > 100)
-                               diff = cur_target - 100;
-                       else
-                               diff = new_target;
+static inline void mx28_power_set_vddio(uint32_t target, uint32_t brownout)
+{
+       int powered_by_linreg = mx28_get_vddio_power_source_off();
+       uint32_t bo_int = 0;
 
-                       diff -= 800;
-                       diff /= 25;
+       if (powered_by_linreg) {
+               bo_int = readl(&power_regs->hw_power_vddioctrl);
+               clrbits_le32(&power_regs->hw_power_vddioctrl,
+                       POWER_CTRL_ENIRQ_VDDIO_BO);
+       }
+       __mx28_power_set_vddx(target, brownout, 2800, 3600, 50, vddio, VDDIO,
+                       powered_by_linreg);
+       if (powered_by_linreg) {
+               writel(POWER_CTRL_VDDIO_BO_IRQ,
+                       &power_regs->hw_power_ctrl_clr);
+               if (bo_int & POWER_CTRL_ENIRQ_VDDIO_BO)
+                       setbits_le32(&power_regs->hw_power_vddioctrl,
+                               POWER_CTRL_ENIRQ_VDDIO_BO);
+       }
+}
 
-                       clrsetbits_le32(&power_regs->hw_power_vdddctrl,
-                                       POWER_VDDDCTRL_TRG_MASK, diff);
+static inline void mx28_power_set_vdda(uint32_t target, uint32_t brownout)
+{
+       int powered_by_linreg = mx28_get_vdda_power_source_off();
+       uint32_t bo_int = 0;
 
-                       if (powered_by_linreg ||
-                               (readl(&power_regs->hw_power_sts) &
-                                       POWER_STS_VDD5V_GT_VDDIO))
-                               early_delay(500);
-                       else {
-                               while (!(readl(&power_regs->hw_power_sts) &
-                                       POWER_STS_DC_OK))
-                                       ;
+       if (powered_by_linreg) {
+               bo_int = readl(&power_regs->hw_power_vddioctrl);
+               clrbits_le32(&power_regs->hw_power_vddioctrl,
+                       POWER_CTRL_ENIRQ_VDDIO_BO);
+       }
+       __mx28_power_set_vddx(target, brownout, 1500, 2275, 25, vdda, VDDA,
+               powered_by_linreg);
+       if (powered_by_linreg) {
+               writel(POWER_CTRL_VDDIO_BO_IRQ,
+                       &power_regs->hw_power_ctrl_clr);
+               if (bo_int & POWER_CTRL_ENIRQ_VDDIO_BO)
+                       setbits_le32(&power_regs->hw_power_vddioctrl,
+                               POWER_CTRL_ENIRQ_VDDIO_BO);
+       }
+}
 
-                       }
+static inline void mx28_power_set_vddmem(uint32_t target, uint32_t brownout)
+{
+       __mx28_power_set_vddx(target, brownout, 1100, 1750, 25, vddmem, VDDMEM,
+                       0);
 
-                       cur_target = readl(&power_regs->hw_power_vdddctrl);
-                       cur_target &= POWER_VDDDCTRL_TRG_MASK;
-                       cur_target *= 25;       /* 25 mV step*/
-                       cur_target += 800;      /* 800 mV lowest */
-               } while (new_target < cur_target);
-       }
+       clrbits_le32(&power_regs->hw_power_vddmemctrl,
+               POWER_VDDMEMCTRL_ENABLE_LINREG |
+               POWER_VDDMEMCTRL_ENABLE_ILIMIT);
+}
 
-       clrsetbits_le32(&power_regs->hw_power_vdddctrl,
-                       POWER_VDDDCTRL_BO_OFFSET_MASK,
-                       new_brownout << POWER_VDDDCTRL_BO_OFFSET_OFFSET);
+void mx28_setup_batt_detect(void)
+{
+       mx28_lradc_init();
+       mx28_lradc_enable_batt_measurement();
+       early_delay(10);
 }
 
 void mx28_power_init(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_power_regs *)MXS_POWER_BASE;
-
        mx28_power_clock2xtal();
        mx28_power_clear_auto_restart();
        mx28_power_set_linreg();
-       mx28_power_setup_5v_detect();
+       if (!fixed_batt_supply)
+               mx28_power_setup_5v_detect();
+
        mx28_power_configure_power_source();
        mx28_enable_output_rail_protection();
 
-       mx28_power_set_vddio(3300, 3150);
+       mx28_power_set_vddio(VDDIO_VAL, VDDIO_BO_VAL);
 
-       mx28_power_set_vddd(1350, 1200);
+       mx28_power_set_vddd(VDDD_VAL, VDDD_BO_VAL);
+
+       mx28_power_set_vdda(VDDA_VAL, VDDA_BO_VAL);
+
+       mx28_power_set_vddmem(VDDMEM_VAL, VDDMEM_BO_VAL);
 
        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_MX28_PSWITCH_WAIT
 void mx28_power_wait_pswitch(void)
 {
-       struct mx28_power_regs *power_regs =
-               (struct mx28_power_regs *)MXS_POWER_BASE;
-
        while (!(readl(&power_regs->hw_power_sts) & POWER_STS_PSWITCH_MASK))
                ;
 }
index 5b73f4a..116932c 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define timestamp (gd->tbl)
-#define lastdec (gd->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.
@@ -54,12 +66,6 @@ static inline unsigned long time_to_tick(unsigned long time)
        return time * (MX28_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 * MX28_INCREMENTER_HZ) / 1000000;
-}
-
 int timer_init(void)
 {
        struct mx28_timrot_regs *timrot_regs =
@@ -76,34 +82,70 @@ int timer_init(void)
                TIMROT_TIMCTRLn_SELECT_1KHZ_XTAL,
                &timrot_regs->hw_timrot_timctrl0);
 
-       /* Set fixed_count to maximal value */
+#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 * MX28_INCREMENTER_HZ,
+               &timrot_regs->hw_timrot_fixed_count0);
+       gd->lastinc = TIMER_LOAD_VAL - 20 * MX28_INCREMENTER_HZ;
+#endif
+#ifdef DEBUG_TIMER_WRAP
+       /* Make the usec counter roll over 30 seconds after startup */
+       writel(-30000000, MX28_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->timer_rate_hz = MX28_INCREMENTER_HZ;
+       gd->tbl = TIMER_START;
+       gd->tbu = 0;
        return 0;
 }
 
+/* We use the HW_DIGCTL_MICROSECONDS register for sub-millisecond timer. */
+#define        MX28_HW_DIGCTL_MICROSECONDS     0x8001c0c0
+
+void __udelay(unsigned long usec)
+{
+       uint32_t start = readl(MX28_HW_DIGCTL_MICROSECONDS);
+
+       while (readl(MX28_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!
+                */
+               ;
+}
+
+/* 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 mx28_timrot_regs *timrot_regs =
                (struct mx28_timrot_regs *)MXS_TIMROT_BASE;
-
-       /* Current tick value */
-       uint32_t now = readl(&timrot_regs->hw_timrot_running_count0);
-
-       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;
+       /* The timer is counting down, so subtract the register value from
+        * the counter period length to get an incrementing timestamp
+        */
+       unsigned long now = -readl(&timrot_regs->hw_timrot_running_count0);
+       ulong inc = now - gd->lastinc;
+
+       gd->tbl += inc;
+       gd->lastinc = now;
+       /* Since the get_timer() function only uses a 32bit value
+        * it doesn't make sense to return a real 64 bit value here.
+        */
+       return gd->tbl;
 }
 
 ulong get_timer_masked(void)
@@ -113,44 +155,15 @@ ulong get_timer_masked(void)
 
 ulong get_timer(ulong base)
 {
-       return get_timer_masked() - base;
-}
-
-/* We use the HW_DIGCTL_MICROSECONDS register for sub-millisecond timer. */
-#define        MX28_HW_DIGCTL_MICROSECONDS     0x8001c0c0
-
-void __udelay(unsigned long usec)
-{
-       uint32_t old, new, incr;
-       uint32_t counter = 0;
-
-       old = readl(MX28_HW_DIGCTL_MICROSECONDS);
-
-       while (counter < usec) {
-               new = readl(MX28_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.
-                */
-               if (counter + incr < counter)
-                       break;
-
-               counter += incr;
-               old = new;
-       }
+       /* NOTE: time_to_tick(base) is required to correctly handle rollover! */
+       return tick_to_time(get_ticks() - time_to_tick(base));
 }
 
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
 ulong get_tbclk(void)
 {
-       return MX28_INCREMENTER_HZ;
+       return gd->timer_rate_hz;
 }
index 7768912..0ad202d 100644 (file)
@@ -18,9 +18,12 @@ LIB  = $(obj)lib$(SOC).o
 
 COBJS  += clock.o
 COBJS  += sys_info.o
-COBJS  += ddr.o
+COBJS-$(CONFIG_SYS_SDRAM_DDR3) += ddr3.o
+COBJS-$(CONFIG_SYS_SDRAM_DDR2) += ddr2.o
+COBJS  += mem.o
 COBJS  += emif4.o
 COBJS  += board.o
+COBJS-$(CONFIG_NAND_AM33XX) += elm.o
 
 SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS))
index 6b7a494..4613489 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
-struct gptimer *timer_base = (struct gptimer *)CONFIG_SYS_TIMERBASE;
-struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;
-
 /* UART Defines */
 #ifdef CONFIG_SPL_BUILD
 #define UART_RESET             (0x1 << 1)
@@ -40,11 +36,68 @@ struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;
 #define UART_SMART_IDLE_EN     (0x1 << 0x3)
 #endif
 
+void reset_cpu(unsigned long ignored)
+{
+       /* clear RESET flags */
+       writel(~0, PRM_RSTST);
+       writel(PRM_RSTCTRL_RESET, PRM_RSTCTRL);
+}
+
+#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
+
 /*
  * early system init of muxing and clocks.
  */
 void s_init(void)
 {
+#ifdef CONFIG_SPL_BUILD
+#ifndef CONFIG_HW_WATCHDOG
+       struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE;
+
        /* WDT1 is already running when the bootloader gets control
         * Disable it to avoid "random" resets
         */
@@ -54,13 +107,13 @@ void s_init(void)
        writel(0x5555, &wdtimer->wdtwspr);
        while (readl(&wdtimer->wdtwwps) != 0x0)
                ;
-
-#ifdef CONFIG_SPL_BUILD
+#endif
        /* Setup the PLLs and the clocks for the peripherals */
        pll_init();
 
        /* UART softreset */
        u32 regVal;
+       struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;
 
        enable_uart0_pin_mux();
 
@@ -77,40 +130,61 @@ void s_init(void)
        writel(regVal, &uart_base->uartsyscfg);
 
        /* Initialize the Timer */
-       init_timer();
+       timer_init();
 
        preloader_console_init();
 
        config_ddr();
-#endif
 
        /* Enable MMC0 */
        enable_mmc0_pin_mux();
+#endif
 }
 
-/* Initialize timer */
-void init_timer(void)
+#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
+int board_mmc_init(bd_t *bis)
 {
-       /* Reset the Timer */
-       writel(0x2, (&timer_base->tscir));
-
-       /* Wait until the reset is done */
-       while (readl(&timer_base->tiocp_cfg) & 1)
-               ;
-
-       /* Start the Timer */
-       writel(0x1, (&timer_base->tclr));
+       int ret = 0;
+#ifdef CONFIG_OMAP_MMC_DEV_0
+       ret = omap_mmc_init(0, 0, 0);
+       if (ret)
+               printf("Error %d while initializing MMC dev 0\n", ret);
+#endif
+#ifdef CONFIG_OMAP_MMC_DEV_1
+       ret = omap_mmc_init(1, 0, 0);
+       if (ret)
+               printf("Error %d while initializing MMC dev 1\n", ret);
+#endif
+       return ret;
 }
+#endif
 
-#if defined(CONFIG_OMAP_HSMMC) && !defined(CONFIG_SPL_BUILD)
-int board_mmc_init(bd_t *bis)
+#ifndef CONFIG_SYS_DCACHE_OFF
+void enable_caches(void)
 {
-       return omap_mmc_init(0, 0, 0);
+       /* Enable D-cache. I-cache is already enabled in start.S */
+       dcache_enable();
 }
 #endif
 
-void setup_clocks_for_console(void)
+static u32 cortex_rev(void)
+{
+
+       unsigned int rev;
+
+       /* Read Main ID Register (MIDR) */
+       asm ("mrc p15, 0, %0, c0, c0, 0" : "=r" (rev));
+
+       return rev;
+}
+
+void omap_rev_string(void)
 {
-       /* Not yet implemented */
-       return;
+       u32 omap_rev = cortex_rev();
+       u32 omap_variant = (omap_rev & 0xFFFF0000) >> 16;
+       u32 major_rev = (omap_rev & 0x00000F00) >> 8;
+       u32 minor_rev = (omap_rev & 0x000000F0) >> 4;
+
+       printf("OMAP%x ES%x.%x\n", omap_variant, major_rev,
+               minor_rev);
 }
index bbb9c13..b489da0 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
 
 
 const struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
 const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
 const struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL;
 
+#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)
-               ;
+       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->gpio0clkctrl, PRCM_MOD_EN);
 }
 
 /*
@@ -92,32 +94,58 @@ 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)
-               ;
-
-       /* MMC0*/
-       writel(PRCM_MOD_EN, &cmper->mmc0clkctrl);
-       while (readl(&cmper->mmc0clkctrl) != PRCM_MOD_EN)
-               ;
-
+       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 */
+       enable_clk(cmper->gpmcclkctrl, PRCM_MOD_EN);
+
+       /* ELM */
+       enable_clk(cmper->elmclkctrl, PRCM_MOD_EN);
+
+       /* Ethernet */
+       enable_clk(cmper->cpswclkctrl, 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
+#ifdef CONFIG_LCD
+       enable_clk(cmper->lcdcclkctrl, PRCM_MOD_EN);
+#endif
        /* 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-3 */
+       enable_clk(cmper->gpio1clkctrl, PRCM_MOD_EN);
+       enable_clk(cmper->gpio2clkctrl, PRCM_MOD_EN);
+       enable_clk(cmper->gpio3clkctrl, PRCM_MOD_EN);
 }
 
 static void mpu_pll_config(void)
@@ -133,15 +161,16 @@ static void mpu_pll_config(void)
        while (readl(&cmwkup->idlestdpllmpu) != ST_MN_BYPASS)
                ;
 
-       clksel = clksel & (~CLK_SEL_MASK);
-       clksel = clksel | ((MPUPLL_M << CLK_SEL_SHIFT) | MPUPLL_N);
+       clksel &= ~CLK_SEL_MASK;
+       clksel |= (MPUPLL_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)
@@ -164,23 +193,24 @@ 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 |= ((COREPLL_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)
@@ -201,21 +231,54 @@ 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 |= (PERPLL_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)
                ;
 }
 
+static void disp_pll_config(void)
+{
+#ifdef CONFIG_LCD
+       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 |= (DISPPLL_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))
+               ;
+#endif
+}
+
 static void ddr_pll_config(void)
 {
        u32 clkmode, clksel, div_m2;
@@ -225,23 +288,24 @@ static void ddr_pll_config(void)
        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 */
@@ -274,6 +338,7 @@ void pll_init()
        core_pll_config();
        per_pll_config();
        ddr_pll_config();
+       disp_pll_config();
 
        /* Enable the required interconnect clocks */
        enable_interface_clocks();
@@ -284,3 +349,23 @@ 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);
+}
diff --git a/arch/arm/cpu/armv7/am33xx/ddr.c b/arch/arm/cpu/armv7/am33xx/ddr.c
deleted file mode 100644 (file)
index ed982c1..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * DDR Configuration for AM33xx devices.
- *
- * Copyright (C) 2011 Texas Instruments Incorporated -
-http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed .as is. WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
-
-#include <asm/arch/cpu.h>
-#include <asm/arch/ddr_defs.h>
-#include <asm/io.h>
-
-/**
- * Base address for EMIF instances
- */
-static struct emif_regs *emif_reg = {
-                               (struct emif_regs *)EMIF4_0_CFG_BASE};
-
-/**
- * Base address for DDR instance
- */
-static struct ddr_regs *ddr_reg[2] = {
-                               (struct ddr_regs *)DDR_PHY_BASE_ADDR,
-                               (struct ddr_regs *)DDR_PHY_BASE_ADDR2};
-
-/**
- * Base address for ddr io control instances
- */
-static struct ddr_cmdtctrl *ioctrl_reg = {
-                       (struct ddr_cmdtctrl *)DDR_CONTROL_BASE_ADDR};
-
-/**
- * As a convention, all functions here return 0 on success
- * -1 on failure.
- */
-
-/**
- * Configure SDRAM
- */
-int config_sdram(struct sdram_config *cfg)
-{
-       writel(cfg->sdrcr, &emif_reg->sdrcr);
-       writel(cfg->sdrcr2, &emif_reg->sdrcr2);
-       writel(cfg->refresh, &emif_reg->sdrrcr);
-       writel(cfg->refresh_sh, &emif_reg->sdrrcsr);
-
-       return 0;
-}
-
-/**
- * Set SDRAM timings
- */
-int set_sdram_timings(struct sdram_timing *t)
-{
-       writel(t->time1, &emif_reg->sdrtim1);
-       writel(t->time1_sh, &emif_reg->sdrtim1sr);
-       writel(t->time2, &emif_reg->sdrtim2);
-       writel(t->time2_sh, &emif_reg->sdrtim2sr);
-       writel(t->time3, &emif_reg->sdrtim3);
-       writel(t->time3_sh, &emif_reg->sdrtim3sr);
-
-       return 0;
-}
-
-/**
- * Configure DDR PHY
- */
-int config_ddr_phy(struct ddr_phy_control *p)
-{
-       writel(p->reg, &emif_reg->ddrphycr);
-       writel(p->reg_sh, &emif_reg->ddrphycsr);
-
-       return 0;
-}
-
-/**
- * Configure DDR CMD control registers
- */
-int config_cmd_ctrl(struct cmd_control *cmd)
-{
-       writel(cmd->cmd0csratio, &ddr_reg[0]->cm0csratio);
-       writel(cmd->cmd0csforce, &ddr_reg[0]->cm0csforce);
-       writel(cmd->cmd0csdelay, &ddr_reg[0]->cm0csdelay);
-       writel(cmd->cmd0dldiff, &ddr_reg[0]->cm0dldiff);
-       writel(cmd->cmd0iclkout, &ddr_reg[0]->cm0iclkout);
-
-       writel(cmd->cmd1csratio, &ddr_reg[0]->cm1csratio);
-       writel(cmd->cmd1csforce, &ddr_reg[0]->cm1csforce);
-       writel(cmd->cmd1csdelay, &ddr_reg[0]->cm1csdelay);
-       writel(cmd->cmd1dldiff, &ddr_reg[0]->cm1dldiff);
-       writel(cmd->cmd1iclkout, &ddr_reg[0]->cm1iclkout);
-
-       writel(cmd->cmd2csratio, &ddr_reg[0]->cm2csratio);
-       writel(cmd->cmd2csforce, &ddr_reg[0]->cm2csforce);
-       writel(cmd->cmd2csdelay, &ddr_reg[0]->cm2csdelay);
-       writel(cmd->cmd2dldiff, &ddr_reg[0]->cm2dldiff);
-       writel(cmd->cmd2iclkout, &ddr_reg[0]->cm2iclkout);
-
-       return 0;
-}
-
-/**
- * Configure DDR DATA registers
- */
-int config_ddr_data(int macrono, struct ddr_data *data)
-{
-       writel(data->datardsratio0, &ddr_reg[macrono]->dt0rdsratio0);
-       writel(data->datardsratio1, &ddr_reg[macrono]->dt0rdsratio1);
-
-       writel(data->datawdsratio0, &ddr_reg[macrono]->dt0wdsratio0);
-       writel(data->datawdsratio1, &ddr_reg[macrono]->dt0wdsratio1);
-
-       writel(data->datawiratio0, &ddr_reg[macrono]->dt0wiratio0);
-       writel(data->datawiratio1, &ddr_reg[macrono]->dt0wiratio1);
-       writel(data->datagiratio0, &ddr_reg[macrono]->dt0giratio0);
-       writel(data->datagiratio1, &ddr_reg[macrono]->dt0giratio1);
-
-       writel(data->datafwsratio0, &ddr_reg[macrono]->dt0fwsratio0);
-       writel(data->datafwsratio1, &ddr_reg[macrono]->dt0fwsratio1);
-
-       writel(data->datawrsratio0, &ddr_reg[macrono]->dt0wrsratio0);
-       writel(data->datawrsratio1, &ddr_reg[macrono]->dt0wrsratio1);
-
-       writel(data->datadldiff0, &ddr_reg[macrono]->dt0dldiff0);
-
-       return 0;
-}
-
-int config_io_ctrl(struct ddr_ioctrl *ioctrl)
-{
-       writel(ioctrl->cmd1ctl, &ioctrl_reg->cm0ioctl);
-       writel(ioctrl->cmd2ctl, &ioctrl_reg->cm1ioctl);
-       writel(ioctrl->cmd3ctl, &ioctrl_reg->cm2ioctl);
-       writel(ioctrl->data1ctl, &ioctrl_reg->dt0ioctl);
-       writel(ioctrl->data2ctl, &ioctrl_reg->dt1ioctl);
-
-       return 0;
-}
diff --git a/arch/arm/cpu/armv7/am33xx/ddr2.c b/arch/arm/cpu/armv7/am33xx/ddr2.c
new file mode 100644 (file)
index 0000000..0d2d9f9
--- /dev/null
@@ -0,0 +1,229 @@
+/*
+ * ddr2.c
+ * renamed from emif4.c Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * AM33XX emif4 configuration file
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <asm/sizes.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/clock.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct ddr_regs *ddrregs = (struct ddr_regs *)DDR_PHY_BASE_ADDR;
+struct vtp_reg *vtpreg = (struct vtp_reg *)VTP0_CTRL_ADDR;
+struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR;
+
+#define EMIF_PHYCFG            0x2
+#define EMIF_SDMGT             0x80000000
+#define EMIF_SDRAM             0x00004650
+#define DDR2_RATIO             0x80
+#define CMD_FORCE              0x00
+#define CMD_DELAY              0x00
+
+#define EMIF_READ_LATENCY      0x05
+#define EMIF_TIM1              0x0666B3D6
+#define EMIF_TIM2              0x143731DA
+#define EMIF_TIM3              0x00000347
+#define EMIF_SDCFG             0x43805332
+#define EMIF_SDREF             0x0000081a
+#define DDR2_DLL_LOCK_DIFF     0x0f
+#define DDR2_RD_DQS            0x12
+#define DDR2_PHY_FIFO_WE       0x80
+
+#define DDR2_INVERT_CLKOUT     0x00
+#define DDR2_WR_DQS            0x00
+#define DDR2_PHY_WRLVL         0x00
+#define DDR2_PHY_GATELVL       0x00
+#define DDR2_PHY_WR_DATA       0x40
+#define PHY_RANK0_DELAY                0x01
+#define PHY_DLL_LOCK_DIFF      0x0
+#define DDR_IOCTRL_VALUE       0x18B
+
+int dram_init(void)
+{
+       /* dram_init must store complete ramsize in gd->ram_size */
+       gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
+                               CONFIG_MAX_RAM_BANK_SIZE);
+       debug("SDRAM size: 0x%08x\n", gd->ram_size);
+       return 0;
+}
+
+void dram_init_banksize(void)
+{
+       gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+       gd->bd->bi_dram[0].size = gd->ram_size;
+}
+
+
+#ifdef CONFIG_SPL_BUILD
+static void data_macro_config(void)
+{
+       struct ddr_data data;
+
+       data.datardsratio0 = ((DDR2_RD_DQS << 30) | (DDR2_RD_DQS << 20) |
+                       (DDR2_RD_DQS << 10) | (DDR2_RD_DQS << 0));
+       data.datardsratio1 = DDR2_RD_DQS >> 2;
+       data.datawdsratio0 = ((DDR2_WR_DQS << 30) | (DDR2_WR_DQS << 20) |
+                       (DDR2_WR_DQS << 10) | (DDR2_WR_DQS << 0));
+       data.datawdsratio1 = DDR2_WR_DQS >> 2;
+       data.datawiratio0 = ((DDR2_PHY_WRLVL << 30) | (DDR2_PHY_WRLVL << 20) |
+                       (DDR2_PHY_WRLVL << 10) | (DDR2_PHY_WRLVL << 0));
+       data.datawiratio1 = DDR2_PHY_WRLVL >> 2;
+       data.datagiratio0 = ((DDR2_PHY_GATELVL << 30) | (DDR2_PHY_GATELVL << 20) |
+                       (DDR2_PHY_GATELVL << 10) | (DDR2_PHY_GATELVL << 0));
+       data.datagiratio1 = DDR2_PHY_GATELVL >> 2;
+       data.datafwsratio0 = ((DDR2_PHY_FIFO_WE << 30) | (DDR2_PHY_FIFO_WE << 20) |
+                       (DDR2_PHY_FIFO_WE << 10) | (DDR2_PHY_FIFO_WE << 0));
+       data.datafwsratio1 = DDR2_PHY_FIFO_WE >> 2;
+       data.datawrsratio0 = ((DDR2_PHY_WR_DATA << 30) | (DDR2_PHY_WR_DATA << 20) |
+                       (DDR2_PHY_WR_DATA << 10) | (DDR2_PHY_WR_DATA << 0));
+       data.datawrsratio1 = DDR2_PHY_WR_DATA >> 2;
+       data.datadldiff0 = PHY_DLL_LOCK_DIFF;
+
+       config_ddr_data(0, &data);
+       config_ddr_data(1, &data);
+}
+
+static void cmd_macro_config(void)
+{
+       struct cmd_control cmd;
+
+       cmd.cmd0csratio = DDR2_RATIO;
+       cmd.cmd0csforce = CMD_FORCE;
+       cmd.cmd0csdelay = CMD_DELAY;
+       cmd.cmd0dldiff = DDR2_DLL_LOCK_DIFF;
+       cmd.cmd0iclkout = DDR2_INVERT_CLKOUT;
+
+       cmd.cmd1csratio = DDR2_RATIO;
+       cmd.cmd1csforce = CMD_FORCE;
+       cmd.cmd1csdelay = CMD_DELAY;
+       cmd.cmd1dldiff = DDR2_DLL_LOCK_DIFF;
+       cmd.cmd1iclkout = DDR2_INVERT_CLKOUT;
+
+       cmd.cmd2csratio = DDR2_RATIO;
+       cmd.cmd2csforce = CMD_FORCE;
+       cmd.cmd2csdelay = CMD_DELAY;
+       cmd.cmd2dldiff = DDR2_DLL_LOCK_DIFF;
+       cmd.cmd2iclkout = DDR2_INVERT_CLKOUT;
+
+       config_cmd_ctrl(&cmd);
+}
+
+static void config_vtp(void)
+{
+       writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_ENABLE,
+                       &vtpreg->vtp0ctrlreg);
+       writel(readl(&vtpreg->vtp0ctrlreg) & ~VTP_CTRL_START_EN,
+                       &vtpreg->vtp0ctrlreg);
+       writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_START_EN,
+                       &vtpreg->vtp0ctrlreg);
+
+       /* Poll for READY */
+       while ((readl(&vtpreg->vtp0ctrlreg) & VTP_CTRL_READY) !=
+                       VTP_CTRL_READY)
+               ;
+}
+
+static void config_emif_ddr2(void)
+{
+       int i;
+       int ret;
+       struct sdram_config cfg;
+       struct sdram_timing tmg;
+       struct ddr_phy_control phyc;
+
+debug("%s\n", __func__);
+
+       /* Program EMIF0 CFG Registers */
+       phyc.reg = EMIF_READ_LATENCY;
+       phyc.reg_sh = EMIF_READ_LATENCY;
+       phyc.reg2 = EMIF_READ_LATENCY;
+
+       tmg.time1 = EMIF_TIM1;
+       tmg.time1_sh = EMIF_TIM1;
+       tmg.time2 = EMIF_TIM2;
+       tmg.time2_sh = EMIF_TIM2;
+       tmg.time3 = EMIF_TIM3;
+       tmg.time3_sh = EMIF_TIM3;
+
+       cfg.sdrcr = EMIF_SDCFG;
+       cfg.sdrcr2 = EMIF_SDCFG;
+       cfg.refresh = 0x00004650;
+       cfg.refresh_sh = 0x00004650;
+
+       /* Program EMIF instance */
+       ret = config_ddr_phy(&phyc);
+       if (ret < 0)
+               printf("Couldn't configure phyc\n");
+
+       ret = config_sdram(&cfg);
+       if (ret < 0)
+               printf("Couldn't configure SDRAM\n");
+
+       ret = set_sdram_timings(&tmg);
+       if (ret < 0)
+               printf("Couldn't configure timings\n");
+
+       /* Delay */
+       for (i = 0; i < 5000; i++)
+               ;
+
+       cfg.refresh = EMIF_SDREF;
+       cfg.refresh_sh = EMIF_SDREF;
+       cfg.sdrcr = EMIF_SDCFG;
+       cfg.sdrcr2 = EMIF_SDCFG;
+
+       ret = config_sdram(&cfg);
+       if (ret < 0)
+               printf("Couldn't configure SDRAM\n");
+}
+
+void config_ddr(void)
+{
+       struct ddr_ioctrl ioctrl;
+
+debug("%s\n", __func__);
+
+       enable_emif_clocks();
+
+       config_vtp();
+
+       cmd_macro_config();
+
+       data_macro_config();
+
+       writel(PHY_RANK0_DELAY, &ddrregs->dt0rdelays0);
+       writel(PHY_RANK0_DELAY, &ddrregs->dt1rdelays0);
+
+       ioctrl.cmd1ctl = DDR_IOCTRL_VALUE;
+       ioctrl.cmd2ctl = DDR_IOCTRL_VALUE;
+       ioctrl.cmd3ctl = DDR_IOCTRL_VALUE;
+       ioctrl.data1ctl = DDR_IOCTRL_VALUE;
+       ioctrl.data2ctl = DDR_IOCTRL_VALUE;
+
+       config_io_ctrl(&ioctrl);
+
+       writel(readl(&ddrctrl->ddrioctrl) & 0xefffffff, &ddrctrl->ddrioctrl);
+       writel(readl(&ddrctrl->ddrckectrl) | 0x00000001, &ddrctrl->ddrckectrl);
+
+       config_emif_ddr2();
+}
+#endif
diff --git a/arch/arm/cpu/armv7/am33xx/ddr3.c b/arch/arm/cpu/armv7/am33xx/ddr3.c
new file mode 100644 (file)
index 0000000..c58453b
--- /dev/null
@@ -0,0 +1,297 @@
+/*
+ * ddr3.c
+ *
+ * AM33XX emif4 configuration file
+ *
+ * Copyright (C) 2012 Lothar Waßmann <LW@KARO-electronics.de>
+ *
+ * based on emif4.c
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <common.h>
+#include <asm/sizes.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/ddr3_defs.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/clock.h>
+#include <asm/io.h>
+
+/* AM335X EMIF Register values */
+#define        VTP_CTRL_READY          (0x1 << 5)
+#define VTP_CTRL_ENABLE                (0x1 << 6)
+#define VTP_CTRL_LOCK_EN       (0x1 << 4)
+#define VTP_CTRL_START_EN      (0x1 << 0)
+
+/*
+ * DDR3 force values.  These are board dependent
+ */
+/*
+ * Invert clock adds an additional half cycle delay on the command
+ * interface.  The additional half cycle, is usually meant to enable
+ * leveling in the situation that DQS is later than CK on the board.  It
+ * also helps provide some additional margin for leveling.
+ *
+ * For the EVM this is helping us with additional room for the write
+ * leveling.  Since the dqs delays are very small.
+ */
+#define INVERT_CLOCK           0
+
+/*
+ * This represents the initial value for the leveling process.  The
+ * value is a ratio - so 0x100 represents one cycle.  The real delay
+ * is determined through the leveling process.
+ *
+ * During the leveling process, 0x20 is subtracted from the value, so
+ * we have added that to the value we want to set.  We also set the
+ * values such that byte3 completes leveling after byte2 and byte1
+ * after byte0.
+ */
+#define WR_DQS_RATIO_0         0x20
+#define WR_DQS_RATIO_1         0x20
+
+/*
+ * This represents the initial value for the leveling process.  The
+ * value is a ratio - so 0x100 represents one cycle.  The real delay
+ * is determined through the leveling process.
+ *
+ * During the leveling process, 0x20 is subtracted from the value, so
+ * we have added that to the value we want to set.  We also set the
+ * values such that byte3 completes leveling after byte2 and byte1
+ * after byte0.
+ */
+#define RD_GATE_RATIO_0                0x20
+#define RD_GATE_RATIO_1                0x20
+
+/*
+ * CMD_SLAVE_RATIO determines where is the command placed with respect
+ * to the clock edge.  This is a ratio, implying 0x100 is one cycle.
+ * Ideally the command is centered so - this should be half cycle
+ * delay (0x80).  But if invert clock is in use, an additional half
+ * cycle must be added
+ */
+#define CMD_SLAVE_FROM_INV_CLOCK(i) (((i) == 0) ? 0x80 : 0x100)
+#define CMD_SLAVE_RATIO                CMD_SLAVE_FROM_INV_CLOCK(INVERT_CLOCK)
+
+/*
+ * EMIF Paramters.  Refer the EMIF register documentation and the
+ * memory datasheet for details
+ */
+/* For 303 MHz m_clk 3.3ns */
+#define EMIF_TIM1    0x0668A3DB
+/*
+ * 000 0011 0011 0100 01010 001111 011 011
+ *
+ *28-25   reg_t_rp      3 - 13ns
+ *24-21   reg_t_rcd     3 - 13ns
+ *20-17   reg_t_wr      4 - 16ns
+ *16-12   reg_t_ras    10 - 36ns
+ *11-6    reg_t_rc     15 - 52ns
+ *5-3     reg_t_rrd     3
+ *2-0     reg_t_wtr     3
+ */
+
+#define EMIF_TIM2    0x2A04011A
+/*
+ * 0 010 101 000000100 0000000100 011 010
+ *
+ *30-28   reg_t_xp     2 - 3nCK
+ *27-25   reg_t_odt    5 - 6nCK
+ *24-16   reg_t_xsnr   4 - 5nCK
+ *15-6    reg_t_xsrd   4 - 5nCK
+ *5-3     reg_t_rtp    3 - 4nCK
+ *2-0     reg_t_cke    2 - 3nCK
+ */
+
+#define EMIF_TIM3    0x001F8309
+/*
+ * 00000000 000 111111 00 000110000 1001
+ *
+ *23-21   reg_t_ckesr      0  - LPDDR2
+ *20-15   reg_zq_zqcs      63 - 64nCK
+ *14-13   reg_t_tdqsckmax  0  - LPDDR2
+ *12-4    reg_t_rfc        48 - 161ns
+ *3-0     reg_t_ras_max    9
+ */
+
+#define EMIF_SDREF   0x20000C1A
+/*
+ * 0 0 1 0 0 000 00000000 C1A
+ *
+ *31    reg_initref_dis   0 Initialization
+ *30    Reserved          0
+ *29    reg_srt           1 extended temp.
+ *28    reg_asr           0 manual Self Refresh
+ *27    Reserved          0
+ *26-24 reg_pasr          0
+ *23-16 Reserved          0
+ *15-0  reg_refresh_rate  C1A
+ */
+
+#define EMIF_SDCFG   0x62A44AB2 /* 0x62A45032 */
+/*
+ * 011 00 010 1 01 0 01 00 01 0010 101 011 0 010
+ *
+ *31-29 reg_sdram_type      3 - DDR3
+ *28-27 reg_ibank_pos       0
+ *26-24 reg_ddr_term        2 - RZQ/2
+ *23    reg_ddr2_ddqs       1 - differential DQS
+ *22-21 reg_dyn_odt         1 - Dynamic ODT RZQ/4
+ *20    reg_ddr_disable_dll 0 - enable DLL
+ *19-18 reg_sdram_drive     1 - drive strength RZQ/7
+ *17-16 reg_cwl             0 - CAS write latency 5
+ *15-14 reg_narrow_mode     1 - 16-bit data bus width
+ *13-10 reg_cl              2 - CAS latency of 5
+ *9-7   reg_rowsize         5 - 14 row bits
+ *6-4   reg_ibank           3 - 8 banks
+ *3     reg_ebank           0 - 1 chip select
+ *2-0   reg_pagesize        2 - 10 column bits
+ */
+
+#define EMIF_PHYCFG            0x0000010B
+
+#define        PHY_RANK_DELAY          0x01
+#define DDR_IOCTRL_VALUE       0x18B
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define PHY_DLL_LOCK_DIFF 0x0f
+
+struct ddr_regs *ddrregs = (struct ddr_regs *)DDR_PHY_BASE_ADDR;
+struct vtp_reg *vtpreg = (struct vtp_reg *)VTP0_CTRL_ADDR;
+struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR;
+
+int dram_init(void)
+{
+       /* dram_init must store complete ramsize in gd->ram_size */
+       gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
+                               CONFIG_MAX_RAM_BANK_SIZE);
+       return 0;
+}
+
+void dram_init_banksize(void)
+{
+       gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+       gd->bd->bi_dram[0].size = gd->ram_size;
+}
+
+#ifdef CONFIG_SPL_BUILD
+/**
+ * Base address for EMIF instances
+ */
+static struct emif_regs *emif_reg = {
+                               (struct emif_regs *)EMIF4_0_CFG_BASE};
+
+/**
+ * Base address for DDR instance
+ */
+static struct ddr_regs *ddr_reg = (struct ddr_regs *)DDR_PHY_BASE_ADDR;
+
+/**
+ * Base address for ddr io control instances
+ */
+static struct ddr_cmdtctrl *ioctrl_reg = {
+                       (struct ddr_cmdtctrl *)DDR_CONTROL_BASE_ADDR};
+
+static void data_macro_config(void)
+{
+       writel((WR_DQS_RATIO_0 << 10) | (WR_DQS_RATIO_0 << 0),
+               &ddr_reg->dt0.wiratio0);
+       writel((WR_DQS_RATIO_1 << 10) | (WR_DQS_RATIO_1 << 0),
+               &ddr_reg->dt1.wiratio0);
+       writel((RD_GATE_RATIO_0 << 10) | (RD_GATE_RATIO_0 << 0),
+               &ddr_reg->dt0.giratio0);
+       writel((RD_GATE_RATIO_1 << 10) | (RD_GATE_RATIO_1 << 0),
+               &ddr_reg->dt1.giratio0);
+
+       writel(PHY_DLL_LOCK_DIFF, &ddr_reg->dt0.dldiff0);
+       writel(PHY_DLL_LOCK_DIFF, &ddr_reg->dt1.dldiff0);
+}
+
+static void cmd_macro_config(void)
+{
+       writel(PHY_DLL_LOCK_DIFF, &ddr_reg->cm0dldiff);
+       writel(PHY_DLL_LOCK_DIFF, &ddr_reg->cm1dldiff);
+       writel(PHY_DLL_LOCK_DIFF, &ddr_reg->cm2dldiff);
+
+       writel(INVERT_CLOCK, &ddr_reg->cm0iclkout);
+       writel(INVERT_CLOCK, &ddr_reg->cm1iclkout);
+       writel(INVERT_CLOCK, &ddr_reg->cm2iclkout);
+}
+
+static void config_vtp(void)
+{
+       writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_ENABLE,
+                       &vtpreg->vtp0ctrlreg);
+       writel(readl(&vtpreg->vtp0ctrlreg) & ~VTP_CTRL_START_EN,
+                       &vtpreg->vtp0ctrlreg);
+       writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_START_EN,
+                       &vtpreg->vtp0ctrlreg);
+
+       /* Poll for READY */
+       while ((readl(&vtpreg->vtp0ctrlreg) & VTP_CTRL_READY) !=
+                       VTP_CTRL_READY)
+               ;
+}
+
+static void config_emif_ddr3(void)
+{
+       /* Program EMIF0 CFG Registers */
+       writel(EMIF_PHYCFG, &emif_reg->ddrphycr);
+       writel(EMIF_PHYCFG, &emif_reg->ddrphycsr);
+
+       writel(EMIF_TIM1, &emif_reg->sdrtim1);
+       writel(EMIF_TIM1, &emif_reg->sdrtim1sr);
+       writel(EMIF_TIM2, &emif_reg->sdrtim2);
+       writel(EMIF_TIM2, &emif_reg->sdrtim2sr);
+       writel(EMIF_TIM3, &emif_reg->sdrtim3);
+       writel(EMIF_TIM3, &emif_reg->sdrtim3sr);
+
+       writel(EMIF_SDCFG, &emif_reg->sdrcr);
+       writel(EMIF_SDCFG, &emif_reg->sdrcr2);
+       writel(0x00004650, &emif_reg->sdrrcr);
+       writel(0x00004650, &emif_reg->sdrrcsr);
+
+       udelay(50);
+
+       writel(EMIF_SDREF, &emif_reg->sdrrcr);
+       writel(EMIF_SDREF, &emif_reg->sdrrcsr);
+}
+
+void config_ddr(void)
+{
+       enable_emif_clocks();
+
+       config_vtp();
+
+       cmd_macro_config();
+
+       data_macro_config();
+
+       writel(PHY_RANK_DELAY, &ddrregs->dt0.rdelays0);
+       writel(PHY_RANK_DELAY, &ddrregs->dt1.rdelays0);
+
+       writel(DDR_IOCTRL_VALUE, &ioctrl_reg->cm0ioctl);
+       writel(DDR_IOCTRL_VALUE, &ioctrl_reg->cm1ioctl);
+       writel(DDR_IOCTRL_VALUE, &ioctrl_reg->cm2ioctl);
+
+       writel(DDR_IOCTRL_VALUE, &ioctrl_reg->dt0ioctl);
+       writel(DDR_IOCTRL_VALUE, &ioctrl_reg->dt1ioctl);
+
+       writel(readl(&ddrctrl->ddrioctrl) & 0xefffffff, &ddrctrl->ddrioctrl);
+       writel(readl(&ddrctrl->ddrckectrl) | 0x00000001, &ddrctrl->ddrckectrl);
+
+       config_emif_ddr3();
+}
+#endif
diff --git a/arch/arm/cpu/armv7/am33xx/elm.c b/arch/arm/cpu/armv7/am33xx/elm.c
new file mode 100644 (file)
index 0000000..91d6336
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+ * (C) Copyright 2010-2011 Texas Instruments, <www.ti.com>
+ * Mansoor Ahamed <mansoor.ahamed@ti.com>
+ *
+ * BCH Error Location Module (ELM) support.
+ *
+ * NOTE:
+ * 1. Supports only continuous mode. Dont see need for page mode in uboot
+ * 2. Supports only syndrome polynomial 0. i.e. poly local variable is
+ *    always set to ELM_DEFAULT_POLY. Dont see need for other polynomial
+ *    sets in uboot
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/nand.h>
+
+#define ELM_DEFAULT_POLY 0
+
+/* 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
+ * @syndrome: BCH syndrome
+ * @nibbles:
+ * @poly: Syndrome Polynomial set to use
+ *
+ * Load BCH syndromes based on nibble selection
+ */
+static void elm_load_syndromes(u8 *syndrome, u32 nibbles, u8 poly)
+{
+       u32 val;
+       struct  syndrome *sf = &elm_cfg->syndrome_fragments[poly];
+
+       /* reg 0 */
+       val = syndrome[0] | (syndrome[1] << 8) | (syndrome[2] << 16) |
+                               (syndrome[3] << 24);
+       writel(val, &sf->syndrome_fragment_x[0]);
+
+       /* reg 1 */
+       val = syndrome[4] | (syndrome[5] << 8) | (syndrome[6] << 16) |
+                               (syndrome[7] << 24);
+       writel(val, &sf->syndrome_fragment_x[1]);
+
+       /* BCH 8-bit with 26 nibbles (4*8=32) */
+       if (nibbles > 13) {
+               /* reg 2 */
+               val = syndrome[8] | (syndrome[9] << 8) | (syndrome[10] << 16) |
+                               (syndrome[11] << 24);
+               writel(val, &sf->syndrome_fragment_x[2]);
+
+               /* reg 3 */
+               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 */
+               val = syndrome[16] | (syndrome[17] << 8) | (syndrome[18] << 16) |
+                               (syndrome[19] << 24);
+               writel(val, &sf->syndrome_fragment_x[4]);
+
+               /* reg 5 */
+               val = syndrome[20] | (syndrome[21] << 8) | (syndrome[22] << 16) |
+                               (syndrome[23] << 24);
+               writel(val, &sf->syndrome_fragment_x[5]);
+
+               /* reg 6 */
+               val = syndrome[24] | (syndrome[25] << 8) | (syndrome[26] << 16) |
+                               (syndrome[27] << 24);
+               writel(val, &sf->syndrome_fragment_x[6]);
+       }
+}
+
+/**
+ * elm_check_error - Check for BCH errors and return error locations
+ * @syndrome: BCH syndrome
+ * @nibbles:
+ * @error_count: Returns number of errrors in the syndrome
+ * @error_locations: Returns error locations (in decimal) in this array
+ *
+ * Check the provided syndrome for BCH errors and return error count
+ * and locations in the array passed. Returns -1 if error is not correctable,
+ * else returns 0
+ */
+int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count,
+               u32 *error_locations)
+{
+       u8 poly = ELM_DEFAULT_POLY;
+       s8 i;
+       u32 location_status;
+
+       elm_load_syndromes(syndrome, nibbles, poly);
+
+       /* 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]);
+
+       /* wait for processing to complete */
+       while (!(readl(&elm_cfg->irqstatus) & (0x1 << poly)));
+       /* clear status */
+       writel((readl(&elm_cfg->irqstatus) & ~(0x1 << poly)),
+               &elm_cfg->irqstatus);
+
+       /* check if correctable */
+       location_status = readl(&elm_cfg->error_location[poly].location_status);
+       if (!(location_status & ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK))
+               return -1;
+
+       /* get error count */
+       *error_count = readl(&elm_cfg->error_location[poly].location_status) &
+                                               ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK;
+
+       for (i = 0; i < *error_count; i++)
+               error_locations[i] =
+                       readl(&elm_cfg->error_location[poly].error_location_x[i]);
+
+       return 0;
+}
+
+
+/**
+ * elm_config - Configure ELM module
+ * @level: 4 / 8 / 16 bit BCH
+ * @buffer_size: Buffer size in bytes
+ *
+ * Configure ELM module based on BCH level and buffer size passed.
+ * Set mode as continuous mode.
+ * Currently we are using only syndrome 0 and syndromes 1 to 6 are not used.
+ * Also, the mode is set only for syndrome 0
+ */
+/* int elm_config(enum bch_level level, u32 buffer_size) */
+int elm_config(enum bch_level level)
+{
+       u32 val;
+       u8 poly = ELM_DEFAULT_POLY;
+       u32 buffer_size= 0x7FF;
+
+       /* config size and level */
+       val = (u32)(level) & ELM_LOCATION_CONFIG_ECC_BCH_LEVEL_MASK;
+       val |= ((buffer_size << ELM_LOCATION_CONFIG_ECC_SIZE_POS) &
+                               ELM_LOCATION_CONFIG_ECC_SIZE_MASK);
+       writel(val, &elm_cfg->location_config);
+
+       /* config continuous mode */
+       /* enable interrupt generation for syndrome polynomial set */
+       writel((readl(&elm_cfg->irqenable) | (0x1 << poly)), &elm_cfg->irqenable);
+       /* set continuous mode for the syndrome polynomial set */
+       writel((readl(&elm_cfg->page_ctrl) & ~(0x1 << poly)), &elm_cfg->page_ctrl);
+
+       return 0;
+}
+
+/**
+ * elm_reset - Do a soft reset of ELM
+ *
+ * Perform a soft reset of ELM and return after reset is done.
+ */
+void elm_reset(void)
+{
+       /* initiate reset */
+       writel((readl(&elm_cfg->sysconfig) | ELM_SYSCONFIG_SOFTRESET),
+                               &elm_cfg->sysconfig);
+
+       /* wait for reset complete and normal operation */
+       while((readl(&elm_cfg->sysstatus) & ELM_SYSSTATUS_RESETDONE) !=
+               ELM_SYSSTATUS_RESETDONE);
+}
+
+/**
+ * elm_init - Initialize ELM module
+ *
+ * Initialize ELM support. Currently it does only base address init
+ * and ELM reset.
+ */
+void elm_init(void)
+{
+       elm_cfg = (struct elm *)ELM_BASE;
+       elm_reset();
+}
+
index 2f4164d..fe917c1 100644 (file)
 /*
- * emif4.c
+ * DDR Configuration for AM33xx devices.
  *
- * AM33XX emif4 configuration file
- *
- * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * published by the Free Software Foundation; either version 2 of
  * the License, or (at your option) any later version.
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE.  See the
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  */
 
 #include <common.h>
 #include <asm/arch/cpu.h>
 #include <asm/arch/ddr_defs.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/clock.h>
 #include <asm/io.h>
 
-DECLARE_GLOBAL_DATA_PTR;
+/**
+ * Base address for EMIF instances
+ */
+static struct emif_regs *emif_reg = {
+                               (struct emif_regs *)EMIF4_0_CFG_BASE};
 
-struct ddr_regs *ddrregs = (struct ddr_regs *)DDR_PHY_BASE_ADDR;
-struct vtp_reg *vtpreg = (struct vtp_reg *)VTP0_CTRL_ADDR;
-struct ddr_ctrl *ddrctrl = (struct ddr_ctrl *)DDR_CTRL_ADDR;
+/**
+ * Base address for DDR instance
+ */
+static struct ddr_regs *ddr_reg[2] = {
+                               (struct ddr_regs *)DDR_PHY_BASE_ADDR,
+                               (struct ddr_regs *)DDR_PHY_BASE_ADDR2};
 
+/**
+ * Base address for ddr io control instances
+ */
+static struct ddr_cmdtctrl *ioctrl_reg = {
+                       (struct ddr_cmdtctrl *)DDR_CONTROL_BASE_ADDR};
 
-int dram_init(void)
+/**
+ * As a convention, all functions here return 0 on success
+ * -1 on failure.
+ */
+
+/**
+ * Configure SDRAM
+ */
+int config_sdram(struct sdram_config *cfg)
 {
-       /* dram_init must store complete ramsize in gd->ram_size */
-       gd->ram_size = get_ram_size(
-                       (void *)CONFIG_SYS_SDRAM_BASE,
-                       CONFIG_MAX_RAM_BANK_SIZE);
+       writel(cfg->sdrcr, &emif_reg->sdrcr);
+       writel(cfg->sdrcr2, &emif_reg->sdrcr2);
+       writel(cfg->refresh, &emif_reg->sdrrcr);
+       writel(cfg->refresh_sh, &emif_reg->sdrrcsr);
+
        return 0;
 }
 
-void dram_init_banksize(void)
+/**
+ * Set SDRAM timings
+ */
+int set_sdram_timings(struct sdram_timing *t)
 {
-       gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
-       gd->bd->bi_dram[0].size = gd->ram_size;
-}
-
+       writel(t->time1, &emif_reg->sdrtim1);
+       writel(t->time1_sh, &emif_reg->sdrtim1sr);
+       writel(t->time2, &emif_reg->sdrtim2);
+       writel(t->time2_sh, &emif_reg->sdrtim2sr);
+       writel(t->time3, &emif_reg->sdrtim3);
+       writel(t->time3_sh, &emif_reg->sdrtim3sr);
 
-#ifdef CONFIG_SPL_BUILD
-static void data_macro_config(int dataMacroNum)
-{
-       struct ddr_data data;
-
-       data.datardsratio0 = ((DDR2_RD_DQS<<30)|(DDR2_RD_DQS<<20)
-                               |(DDR2_RD_DQS<<10)|(DDR2_RD_DQS<<0));
-       data.datardsratio1 = DDR2_RD_DQS>>2;
-       data.datawdsratio0 = ((DDR2_WR_DQS<<30)|(DDR2_WR_DQS<<20)
-                               |(DDR2_WR_DQS<<10)|(DDR2_WR_DQS<<0));
-       data.datawdsratio1 = DDR2_WR_DQS>>2;
-       data.datawiratio0 = ((DDR2_PHY_WRLVL<<30)|(DDR2_PHY_WRLVL<<20)
-                               |(DDR2_PHY_WRLVL<<10)|(DDR2_PHY_WRLVL<<0));
-       data.datawiratio1 = DDR2_PHY_WRLVL>>2;
-       data.datagiratio0 = ((DDR2_PHY_GATELVL<<30)|(DDR2_PHY_GATELVL<<20)
-                               |(DDR2_PHY_GATELVL<<10)|(DDR2_PHY_GATELVL<<0));
-       data.datagiratio1 = DDR2_PHY_GATELVL>>2;
-       data.datafwsratio0 = ((DDR2_PHY_FIFO_WE<<30)|(DDR2_PHY_FIFO_WE<<20)
-                               |(DDR2_PHY_FIFO_WE<<10)|(DDR2_PHY_FIFO_WE<<0));
-       data.datafwsratio1 = DDR2_PHY_FIFO_WE>>2;
-       data.datawrsratio0 = ((DDR2_PHY_WR_DATA<<30)|(DDR2_PHY_WR_DATA<<20)
-                               |(DDR2_PHY_WR_DATA<<10)|(DDR2_PHY_WR_DATA<<0));
-       data.datawrsratio1 = DDR2_PHY_WR_DATA>>2;
-       data.datadldiff0 = PHY_DLL_LOCK_DIFF;
-
-       config_ddr_data(dataMacroNum, &data);
+       return 0;
 }
 
-static void cmd_macro_config(void)
+/**
+ * Configure DDR PHY
+ */
+int config_ddr_phy(struct ddr_phy_control *p)
 {
-       struct cmd_control cmd;
-
-       cmd.cmd0csratio = DDR2_RATIO;
-       cmd.cmd0csforce = CMD_FORCE;
-       cmd.cmd0csdelay = CMD_DELAY;
-       cmd.cmd0dldiff = DDR2_DLL_LOCK_DIFF;
-       cmd.cmd0iclkout = DDR2_INVERT_CLKOUT;
-
-       cmd.cmd1csratio = DDR2_RATIO;
-       cmd.cmd1csforce = CMD_FORCE;
-       cmd.cmd1csdelay = CMD_DELAY;
-       cmd.cmd1dldiff = DDR2_DLL_LOCK_DIFF;
-       cmd.cmd1iclkout = DDR2_INVERT_CLKOUT;
-
-       cmd.cmd2csratio = DDR2_RATIO;
-       cmd.cmd2csforce = CMD_FORCE;
-       cmd.cmd2csdelay = CMD_DELAY;
-       cmd.cmd2dldiff = DDR2_DLL_LOCK_DIFF;
-       cmd.cmd2iclkout = DDR2_INVERT_CLKOUT;
-
-       config_cmd_ctrl(&cmd);
+       writel(p->reg, &emif_reg->ddrphycr);
+       writel(p->reg_sh, &emif_reg->ddrphycsr);
 
+       return 0;
 }
 
-static void config_vtp(void)
+/**
+ * Configure DDR CMD control registers
+ */
+int config_cmd_ctrl(struct cmd_control *cmd)
 {
-       writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_ENABLE,
-                       &vtpreg->vtp0ctrlreg);
-       writel(readl(&vtpreg->vtp0ctrlreg) & (~VTP_CTRL_START_EN),
-                       &vtpreg->vtp0ctrlreg);
-       writel(readl(&vtpreg->vtp0ctrlreg) | VTP_CTRL_START_EN,
-                       &vtpreg->vtp0ctrlreg);
-
-       /* Poll for READY */
-       while ((readl(&vtpreg->vtp0ctrlreg) & VTP_CTRL_READY) !=
-                       VTP_CTRL_READY)
-               ;
-}
+       writel(cmd->cmd0csratio, &ddr_reg[0]->cm0csratio);
+       writel(cmd->cmd0csforce, &ddr_reg[0]->cm0csforce);
+       writel(cmd->cmd0csdelay, &ddr_reg[0]->cm0csdelay);
+       writel(cmd->cmd0dldiff, &ddr_reg[0]->cm0dldiff);
+       writel(cmd->cmd0iclkout, &ddr_reg[0]->cm0iclkout);
+
+       writel(cmd->cmd1csratio, &ddr_reg[0]->cm1csratio);
+       writel(cmd->cmd1csforce, &ddr_reg[0]->cm1csforce);
+       writel(cmd->cmd1csdelay, &ddr_reg[0]->cm1csdelay);
+       writel(cmd->cmd1dldiff, &ddr_reg[0]->cm1dldiff);
+       writel(cmd->cmd1iclkout, &ddr_reg[0]->cm1iclkout);
+
+       writel(cmd->cmd2csratio, &ddr_reg[0]->cm2csratio);
+       writel(cmd->cmd2csforce, &ddr_reg[0]->cm2csforce);
+       writel(cmd->cmd2csdelay, &ddr_reg[0]->cm2csdelay);
+       writel(cmd->cmd2dldiff, &ddr_reg[0]->cm2dldiff);
+       writel(cmd->cmd2iclkout, &ddr_reg[0]->cm2iclkout);
 
-static void config_emif_ddr2(void)
-{
-       int i;
-       int ret;
-       struct sdram_config cfg;
-       struct sdram_timing tmg;
-       struct ddr_phy_control phyc;
-
-       /*Program EMIF0 CFG Registers*/
-       phyc.reg = EMIF_READ_LATENCY;
-       phyc.reg_sh = EMIF_READ_LATENCY;
-       phyc.reg2 = EMIF_READ_LATENCY;
-
-       tmg.time1 = EMIF_TIM1;
-       tmg.time1_sh = EMIF_TIM1;
-       tmg.time2 = EMIF_TIM2;
-       tmg.time2_sh = EMIF_TIM2;
-       tmg.time3 = EMIF_TIM3;
-       tmg.time3_sh = EMIF_TIM3;
-
-       cfg.sdrcr = EMIF_SDCFG;
-       cfg.sdrcr2 = EMIF_SDCFG;
-       cfg.refresh = 0x00004650;
-       cfg.refresh_sh = 0x00004650;
-
-       /* Program EMIF instance */
-       ret = config_ddr_phy(&phyc);
-       if (ret < 0)
-               printf("Couldn't configure phyc\n");
-
-       ret = config_sdram(&cfg);
-       if (ret < 0)
-               printf("Couldn't configure SDRAM\n");
-
-       ret = set_sdram_timings(&tmg);
-       if (ret < 0)
-               printf("Couldn't configure timings\n");
-
-       /* Delay */
-       for (i = 0; i < 5000; i++)
-               ;
-
-       cfg.refresh = EMIF_SDREF;
-       cfg.refresh_sh = EMIF_SDREF;
-       cfg.sdrcr = EMIF_SDCFG;
-       cfg.sdrcr2 = EMIF_SDCFG;
-
-       ret = config_sdram(&cfg);
-       if (ret < 0)
-               printf("Couldn't configure SDRAM\n");
+       return 0;
 }
 
-void config_ddr(void)
+/**
+ * Configure DDR DATA registers
+ */
+int config_ddr_data(int macrono, struct ddr_data *data)
 {
-       int data_macro_0 = 0;
-       int data_macro_1 = 1;
-       struct ddr_ioctrl ioctrl;
+       writel(data->datardsratio0, &ddr_reg[macrono]->dt0.rdsratio0);
+       writel(data->datardsratio1, &ddr_reg[macrono]->dt0.rdsratio1);
 
-       enable_emif_clocks();
+       writel(data->datawdsratio0, &ddr_reg[macrono]->dt0.wdsratio0);
+       writel(data->datawdsratio1, &ddr_reg[macrono]->dt0.wdsratio1);
 
-       config_vtp();
+       writel(data->datawiratio0, &ddr_reg[macrono]->dt0.wiratio0);
+       writel(data->datawiratio1, &ddr_reg[macrono]->dt0.wiratio1);
 
-       cmd_macro_config();
+       writel(data->datagiratio0, &ddr_reg[macrono]->dt0.giratio0);
+       writel(data->datagiratio1, &ddr_reg[macrono]->dt0.giratio1);
 
-       data_macro_config(data_macro_0);
-       data_macro_config(data_macro_1);
+       writel(data->datafwsratio0, &ddr_reg[macrono]->dt0.fwsratio0);
+       writel(data->datafwsratio1, &ddr_reg[macrono]->dt0.fwsratio1);
 
-       writel(PHY_RANK0_DELAY, &ddrregs->dt0rdelays0);
-       writel(PHY_RANK0_DELAY, &ddrregs->dt1rdelays0);
+       writel(data->datawrsratio0, &ddr_reg[macrono]->dt0.wrsratio0);
+       writel(data->datawrsratio1, &ddr_reg[macrono]->dt0.wrsratio1);
 
-       ioctrl.cmd1ctl = DDR_IOCTRL_VALUE;
-       ioctrl.cmd2ctl = DDR_IOCTRL_VALUE;
-       ioctrl.cmd3ctl = DDR_IOCTRL_VALUE;
-       ioctrl.data1ctl = DDR_IOCTRL_VALUE;
-       ioctrl.data2ctl = DDR_IOCTRL_VALUE;
+       writel(data->datadldiff0, &ddr_reg[macrono]->dt0.dldiff0);
 
-       config_io_ctrl(&ioctrl);
+       return 0;
+}
 
-       writel(readl(&ddrctrl->ddrioctrl) & 0xefffffff, &ddrctrl->ddrioctrl);
-       writel(readl(&ddrctrl->ddrckectrl) | 0x00000001, &ddrctrl->ddrckectrl);
+int config_io_ctrl(struct ddr_ioctrl *ioctrl)
+{
+       writel(ioctrl->cmd1ctl, &ioctrl_reg->cm0ioctl);
+       writel(ioctrl->cmd2ctl, &ioctrl_reg->cm1ioctl);
+       writel(ioctrl->cmd3ctl, &ioctrl_reg->cm2ioctl);
+       writel(ioctrl->data1ctl, &ioctrl_reg->dt0ioctl);
+       writel(ioctrl->data2ctl, &ioctrl_reg->dt1ioctl);
 
-       config_emif_ddr2();
+       return 0;
 }
-#endif
diff --git a/arch/arm/cpu/armv7/am33xx/mem.c b/arch/arm/cpu/armv7/am33xx/mem.c
new file mode 100644 (file)
index 0000000..e7f1cf7
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ *     Mansoor Ahamed <mansoor.ahamed@ti.com>
+ *
+ * Initial Code from:
+ *     Manikandan Pillai <mani.pillai@ti.com>
+ *     Richard Woodruff <r-woodruff2@ti.com>
+ *     Syed Mohammed Khasim <khasim@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/mem.h>
+#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,
+       M_NAND_GPMC_CONFIG2,
+       M_NAND_GPMC_CONFIG3,
+       M_NAND_GPMC_CONFIG4,
+       M_NAND_GPMC_CONFIG5,
+       M_NAND_GPMC_CONFIG6, 0
+};
+
+#define GPMC_CS 0
+
+#endif
+
+
+void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
+                       u32 size)
+{
+       writel(0, &cs->config7);
+       sdelay(1000);
+       /* Delay for settling */
+       writel(gpmc_config[0], &cs->config1);
+       writel(gpmc_config[1], &cs->config2);
+       writel(gpmc_config[2], &cs->config3);
+       writel(gpmc_config[3], &cs->config4);
+       writel(gpmc_config[4], &cs->config5);
+       writel(gpmc_config[5], &cs->config6);
+       /* Enable the config */
+       writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) |
+               (1 << 6)), &cs->config7);
+       sdelay(2000);
+}
+
+/*****************************************************
+ * gpmc_init(): init gpmc bus
+ * Init GPMC for x16, MuxMode (SDRAM in x32).
+ * This code can only be executed from SRAM or SDRAM.
+ *****************************************************/
+void gpmc_init(void)
+{
+       /* putting a blanket check on GPMC based on ZeBu for now */
+       gpmc_cfg = (struct gpmc *)GPMC_BASE;
+
+#if defined(CONFIG_CMD_NAND) || defined(CONFIG_CMD_ONENAND)
+       const u32 *gpmc_config = NULL;
+       u32 base = 0;
+       u32 size = 0;
+#endif
+       /* global settings */
+       writel(0x00000008, &gpmc_cfg->sysconfig);
+       writel(0x00000100, &gpmc_cfg->irqstatus);
+       writel(0x00000200, &gpmc_cfg->irqenable);
+       writel(0x00000012, &gpmc_cfg->config);
+       /*
+        * Disable the GPMC0 config set by ROM code
+        */
+       writel(0, &gpmc_cfg->cs[0].config7);
+       sdelay(1000);
+
+#if defined(CONFIG_CMD_NAND)   /* CS 0 */
+       gpmc_config = gpmc_m_nand;
+
+       base = PISMO1_NAND_BASE;
+       size = PISMO1_NAND_SIZE;
+       enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size);
+#endif
+}
index 507b618..5eb7de7 100644 (file)
@@ -26,7 +26,7 @@
 #include <asm/arch/cpu.h>
 #include <asm/arch/clock.h>
 
-struct ctrl_stat *cstat = (struct ctrl_stat *)CTRL_BASE;
+static struct ctrl_stat *cstat = (struct ctrl_stat *)CTRL_BASE;
 
 /**
  * get_cpu_rev(void) - extract rev info
@@ -71,7 +71,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;
 }
 
@@ -81,10 +81,27 @@ 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;
 }
 
+#define SYSBOOT_FREQ_SHIFT     22
+#define SYSBOOT_FREQ_MASK      (3 << SYSBOOT_FREQ_SHIFT)
+
+static unsigned long bootfreqs[] = {
+       19200000,
+       24000000,
+       25000000,
+       26000000,
+};
+
+u32 get_sysboot_freq(void)
+{
+       int mode;
+       mode = readl(&cstat->statusreg) & SYSBOOT_FREQ_MASK;
+       return bootfreqs[mode >> SYSBOOT_FREQ_SHIFT];
+}
+
 #ifdef CONFIG_DISPLAY_CPUINFO
 /**
  * Print CPU information
@@ -92,15 +109,15 @@ u32 get_sysboot_value(void)
 int print_cpuinfo(void)
 {
        char *cpu_s, *sec_s;
-       int arm_freq, ddr_freq;
+       unsigned long clk;
+       const struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
 
        switch (get_cpu_type()) {
-       case AM335X:
+       case AM335X_ID:
                cpu_s = "AM335X";
                break;
        default:
                cpu_s = "Unknown cpu type";
-               break;
        }
 
        switch (get_device_type()) {
@@ -120,10 +137,26 @@ int print_cpuinfo(void)
                sec_s = "?";
        }
 
-       printf("AM%s-%s rev %d\n",
+       printf("%s-%s rev %d\n",
                        cpu_s, sec_s, get_cpu_rev());
 
-       /* TODO: Print ARM and DDR frequencies  */
+       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;
 }
index 1b4e808..0923a6f 100644 (file)
@@ -236,16 +236,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)
@@ -339,16 +341,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 f532d62..5407cb6 100644 (file)
 #
 PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float
 
-# Make ARMv5 to allow more compilers to work, even though its v7a.
-PLATFORM_CPPFLAGS += -march=armv5
+# If armv7-a is not supported by GCC fall-back to armv5, which is
+# supported by more tool-chains
+PF_CPPFLAGS_ARMV7 := $(call cc-option, -march=armv7-a, -march=armv5)
+PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_ARMV7)
+
 # =========================================================================
 #
 # Supply options according to compiler version
index c6fa8ef..b44d92c 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <common.h>
 #include <command.h>
+#include <lcd.h>
 #include <asm/system.h>
 #include <asm/cache.h>
 #include <asm/armv7.h>
@@ -54,7 +55,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 124c380..90ec2bd 100644 (file)
@@ -22,7 +22,7 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(SOC).o
 
-COBJS  += clock.o soc.o
+COBJS  += clock.o power.o soc.o system.o
 
 SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS   := $(addprefix $(obj),$(COBJS) $(SOBJS))
index 2f7048b..330bd75 100644 (file)
@@ -414,6 +414,170 @@ static void exynos5_set_mmc_clk(int dev_index, unsigned int div)
        writel(val, addr);
 }
 
+/* get_lcd_clk: return lcd clock frequency */
+static unsigned long exynos4_get_lcd_clk(void)
+{
+       struct exynos4_clock *clk =
+               (struct exynos4_clock *)samsung_get_base_clock();
+       unsigned long pclk, sclk;
+       unsigned int sel;
+       unsigned int ratio;
+
+       /*
+        * CLK_SRC_LCD0
+        * FIMD0_SEL [3:0]
+        */
+       sel = readl(&clk->src_lcd0);
+       sel = sel & 0xf;
+
+       /*
+        * 0x6: SCLK_MPLL
+        * 0x7: SCLK_EPLL
+        * 0x8: SCLK_VPLL
+        */
+       if (sel == 0x6)
+               sclk = get_pll_clk(MPLL);
+       else if (sel == 0x7)
+               sclk = get_pll_clk(EPLL);
+       else if (sel == 0x8)
+               sclk = get_pll_clk(VPLL);
+       else
+               return 0;
+
+       /*
+        * CLK_DIV_LCD0
+        * FIMD0_RATIO [3:0]
+        */
+       ratio = readl(&clk->div_lcd0);
+       ratio = ratio & 0xf;
+
+       pclk = sclk / (ratio + 1);
+
+       return pclk;
+}
+
+void exynos4_set_lcd_clk(void)
+{
+       struct exynos4_clock *clk =
+           (struct exynos4_clock *)samsung_get_base_clock();
+       unsigned int cfg = 0;
+
+       /*
+        * CLK_GATE_BLOCK
+        * CLK_CAM      [0]
+        * CLK_TV       [1]
+        * CLK_MFC      [2]
+        * CLK_G3D      [3]
+        * CLK_LCD0     [4]
+        * CLK_LCD1     [5]
+        * CLK_GPS      [7]
+        */
+       cfg = readl(&clk->gate_block);
+       cfg |= 1 << 4;
+       writel(cfg, &clk->gate_block);
+
+       /*
+        * CLK_SRC_LCD0
+        * FIMD0_SEL            [3:0]
+        * MDNIE0_SEL           [7:4]
+        * MDNIE_PWM0_SEL       [8:11]
+        * MIPI0_SEL            [12:15]
+        * set lcd0 src clock 0x6: SCLK_MPLL
+        */
+       cfg = readl(&clk->src_lcd0);
+       cfg &= ~(0xf);
+       cfg |= 0x6;
+       writel(cfg, &clk->src_lcd0);
+
+       /*
+        * CLK_GATE_IP_LCD0
+        * CLK_FIMD0            [0]
+        * CLK_MIE0             [1]
+        * CLK_MDNIE0           [2]
+        * CLK_DSIM0            [3]
+        * CLK_SMMUFIMD0        [4]
+        * CLK_PPMULCD0         [5]
+        * Gating all clocks for FIMD0
+        */
+       cfg = readl(&clk->gate_ip_lcd0);
+       cfg |= 1 << 0;
+       writel(cfg, &clk->gate_ip_lcd0);
+
+       /*
+        * CLK_DIV_LCD0
+        * FIMD0_RATIO          [3:0]
+        * MDNIE0_RATIO         [7:4]
+        * MDNIE_PWM0_RATIO     [11:8]
+        * MDNIE_PWM_PRE_RATIO  [15:12]
+        * MIPI0_RATIO          [19:16]
+        * MIPI0_PRE_RATIO      [23:20]
+        * set fimd ratio
+        */
+       cfg &= ~(0xf);
+       cfg |= 0x1;
+       writel(cfg, &clk->div_lcd0);
+}
+
+void exynos4_set_mipi_clk(void)
+{
+       struct exynos4_clock *clk =
+           (struct exynos4_clock *)samsung_get_base_clock();
+       unsigned int cfg = 0;
+
+       /*
+        * CLK_SRC_LCD0
+        * FIMD0_SEL            [3:0]
+        * MDNIE0_SEL           [7:4]
+        * MDNIE_PWM0_SEL       [8:11]
+        * MIPI0_SEL            [12:15]
+        * set mipi0 src clock 0x6: SCLK_MPLL
+        */
+       cfg = readl(&clk->src_lcd0);
+       cfg &= ~(0xf << 12);
+       cfg |= (0x6 << 12);
+       writel(cfg, &clk->src_lcd0);
+
+       /*
+        * CLK_SRC_MASK_LCD0
+        * FIMD0_MASK           [0]
+        * MDNIE0_MASK          [4]
+        * MDNIE_PWM0_MASK      [8]
+        * MIPI0_MASK           [12]
+        * set src mask mipi0 0x1: Unmask
+        */
+       cfg = readl(&clk->src_mask_lcd0);
+       cfg |= (0x1 << 12);
+       writel(cfg, &clk->src_mask_lcd0);
+
+       /*
+        * CLK_GATE_IP_LCD0
+        * CLK_FIMD0            [0]
+        * CLK_MIE0             [1]
+        * CLK_MDNIE0           [2]
+        * CLK_DSIM0            [3]
+        * CLK_SMMUFIMD0        [4]
+        * CLK_PPMULCD0         [5]
+        * Gating all clocks for MIPI0
+        */
+       cfg = readl(&clk->gate_ip_lcd0);
+       cfg |= 1 << 3;
+       writel(cfg, &clk->gate_ip_lcd0);
+
+       /*
+        * CLK_DIV_LCD0
+        * FIMD0_RATIO          [3:0]
+        * MDNIE0_RATIO         [7:4]
+        * MDNIE_PWM0_RATIO     [11:8]
+        * MDNIE_PWM_PRE_RATIO  [15:12]
+        * MIPI0_RATIO          [19:16]
+        * MIPI0_PRE_RATIO      [23:20]
+        * set mipi ratio
+        */
+       cfg &= ~(0xf << 16);
+       cfg |= (0x1 << 16);
+       writel(cfg, &clk->div_lcd0);
+}
+
 unsigned long get_pll_clk(int pllreg)
 {
        if (cpu_is_exynos5())
@@ -453,3 +617,23 @@ void set_mmc_clk(int dev_index, unsigned int div)
        else
                exynos4_set_mmc_clk(dev_index, div);
 }
+
+unsigned long get_lcd_clk(void)
+{
+       if (cpu_is_exynos4())
+               return exynos4_get_lcd_clk();
+       else
+               return 0;
+}
+
+void set_lcd_clk(void)
+{
+       if (cpu_is_exynos4())
+               exynos4_set_lcd_clk();
+}
+
+void set_mipi_clk(void)
+{
+       if (cpu_is_exynos4())
+               exynos4_set_mipi_clk();
+}
diff --git a/arch/arm/cpu/armv7/exynos/power.c b/arch/arm/cpu/armv7/exynos/power.c
new file mode 100644 (file)
index 0000000..c765304
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ * Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/power.h>
+
+static void exynos4_mipi_phy_control(unsigned int dev_index,
+                                       unsigned int enable)
+{
+       struct exynos4_power *pmu =
+           (struct exynos4_power *)samsung_get_base_power();
+       unsigned int addr, cfg = 0;
+
+       if (dev_index == 0)
+               addr = (unsigned int)&pmu->mipi_phy0_control;
+       else
+               addr = (unsigned int)&pmu->mipi_phy1_control;
+
+
+       cfg = readl(addr);
+       if (enable)
+               cfg |= (EXYNOS_MIPI_PHY_MRESETN | EXYNOS_MIPI_PHY_ENABLE);
+       else
+               cfg &= ~(EXYNOS_MIPI_PHY_MRESETN | EXYNOS_MIPI_PHY_ENABLE);
+
+       writel(cfg, addr);
+}
+
+void set_mipi_phy_ctrl(unsigned int dev_index, unsigned int enable)
+{
+       if (cpu_is_exynos4())
+               exynos4_mipi_phy_control(dev_index, enable);
+}
diff --git a/arch/arm/cpu/armv7/exynos/system.c b/arch/arm/cpu/armv7/exynos/system.c
new file mode 100644 (file)
index 0000000..6c34730
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics
+ * Donghwa Lee <dh09.lee@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/system.h>
+
+static void exynos4_set_system_display(void)
+{
+       struct exynos4_sysreg *sysreg =
+           (struct exynos4_sysreg *)samsung_get_base_sysreg();
+       unsigned int cfg = 0;
+
+       /*
+        * system register path set
+        * 0: MIE/MDNIE
+        * 1: FIMD Bypass
+        */
+       cfg = readl(&sysreg->display_ctrl);
+       cfg |= (1 << 1);
+       writel(cfg, &sysreg->display_ctrl);
+}
+
+void set_system_display_ctrl(void)
+{
+       if (cpu_is_exynos4())
+               exynos4_set_system_display();
+}
index 3d58d8a..9aad798 100644 (file)
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/sys_proto.h>
+#include <asm/arch/crm_regs.h>
 
 #ifdef CONFIG_FSL_ESDHC
 #include <fsl_esdhc.h>
 #endif
 
-static char *get_reset_cause(void)
+char *get_reset_cause(void)
 {
        u32 cause;
        struct src *src_regs = (struct src *)SRC_BASE_ADDR;
@@ -125,5 +126,22 @@ int cpu_mmc_init(bd_t *bis)
 
 void reset_cpu(ulong addr)
 {
+       struct src *src_regs = (struct src *)SRC_BASE_ADDR;
+
+       /* Clear the reset status flags */
+       writel(readl(&src_regs->srsr), &src_regs->srsr);
+
        __raw_writew(4, WDOG1_BASE_ADDR);
 }
+
+u32 get_ahb_clk(void)
+{
+       struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
+       u32 reg, ahb_podf;
+
+       reg = __raw_readl(&imx_ccm->cbcdr);
+       reg &= MXC_CCM_CBCDR_AHB_PODF_MASK;
+       ahb_podf = reg >> MXC_CCM_CBCDR_AHB_PODF_OFFSET;
+
+       return get_periph_clk() / (ahb_podf + 1);
+}
index 1645ff8..39d2862 100644 (file)
@@ -42,29 +42,53 @@ static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR;
 /* General purpose timers bitfields */
 #define GPTCR_SWR              (1 << 15)       /* Software reset */
 #define GPTCR_FRR              (1 << 9)        /* Freerun / restart */
-#define GPTCR_CLKSOURCE_32     (4 << 6)        /* Clock source */
+#define GPTCR_CLKSOURCE_IPG    (1 << 6)        /* Clock source */
+#define GPTCR_CLKSOURCE_CKIH   (2 << 6)
+#define GPTCR_CLKSOURCE_32kHz  (4 << 6)
+#define GPTCR_CLKSOURCE_OSC    (5 << 6)
+#define GPTCR_CLKSOURCE_MASK   (7 << 6)
 #define GPTCR_TEN              1               /* Timer enable */
-#define CLK_32KHZ              32768           /* 32Khz input */
+
+#define GPT_CLKSOURCE          GPTCR_CLKSOURCE_32kHz
+#define GPT_REFCLK             32768
+#define GPT_PRESCALER          1
+#define GPT_CLK                        (GPT_REFCLK / GPT_PRESCALER)
+
+#ifdef DEBUG_TIMER_WRAP
+/*
+ * Let the timer wrap 30 seconds after start to catch misbehaving
+ * timer related code early
+ */
+#define TIMER_START            (-time_to_tick(30 * CONFIG_SYS_HZ))
+#else
+#define TIMER_START            0UL
+#endif
 
 DECLARE_GLOBAL_DATA_PTR;
 
-#define timestamp (gd->tbl)
-#define lastinc (gd->lastinc)
+static inline unsigned long tick_to_time(unsigned long tick)
+{
+       unsigned long long t = (unsigned long long)tick * CONFIG_SYS_HZ;
+       do_div(t, GPT_CLK);
+       return t;
+}
 
-static inline unsigned long long tick_to_time(unsigned long long tick)
+static inline unsigned long time_to_tick(unsigned long time)
 {
-       tick *= CONFIG_SYS_HZ;
-       do_div(tick, CLK_32KHZ);
+       unsigned long long ticks = (unsigned long long)time;
 
-       return tick;
+       ticks *= GPT_CLK;
+       do_div(ticks, CONFIG_SYS_HZ);
+       return ticks;
 }
 
-static inline unsigned long long us_to_tick(unsigned long long usec)
+static inline unsigned long us_to_tick(unsigned long usec)
 {
-       usec *= CLK_32KHZ;
-       do_div(usec, 1000000);
+       unsigned long long ticks = (unsigned long long)usec;
 
-       return usec;
+       ticks *= GPT_CLK;
+       do_div(ticks, 1000 * CONFIG_SYS_HZ);
+       return ticks;
 }
 
 int timer_init(void)
@@ -79,15 +103,18 @@ int timer_init(void)
        for (i = 0; i < 100; i++)
                __raw_writel(0, &cur_gpt->control);
 
-       __raw_writel(0, &cur_gpt->prescaler); /* 32Khz */
+       __raw_writel(0, &cur_gpt->prescaler);
 
        /* Freerun Mode, PERCLK1 input */
        i = __raw_readl(&cur_gpt->control);
-       __raw_writel(i | GPTCR_CLKSOURCE_32 | GPTCR_TEN, &cur_gpt->control);
+       i &= ~GPTCR_CLKSOURCE_MASK;
+       __raw_writel(i | GPT_CLKSOURCE | GPTCR_TEN, &cur_gpt->control);
 
        val = __raw_readl(&cur_gpt->counter);
-       lastinc = val / (CLK_32KHZ / CONFIG_SYS_HZ);
-       timestamp = 0;
+       gd->lastinc = val;
+       gd->tbu = 0;
+       gd->tbl = TIMER_START;
+       gd->timer_rate_hz = GPT_CLK;
 
        return 0;
 }
@@ -95,19 +122,11 @@ int timer_init(void)
 unsigned long long get_ticks(void)
 {
        ulong now = __raw_readl(&cur_gpt->counter); /* current tick value */
+       ulong inc = now - gd->lastinc;
 
-       if (now >= lastinc) {
-               /*
-                * normal mode (non roll)
-                * move stamp forward with absolut diff ticks
-                */
-               timestamp += (now - lastinc);
-       } else {
-               /* we have rollover of incrementer */
-               timestamp += (0xFFFFFFFF - lastinc) + now;
-       }
-       lastinc = now;
-       return timestamp;
+       gd->tbl += inc;
+       gd->lastinc = now;
+       return gd->tbl;
 }
 
 ulong get_timer_masked(void)
@@ -118,25 +137,36 @@ ulong get_timer_masked(void)
         * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in
         * 5 * 10^6 days - long enough.
         */
+       /*
+        * LW: get_ticks() returns a long long with the top 32 bits always ZERO!
+        * Thus the calculation above is not true.
+        * A 64bit timer value would only make sense if it was
+        * consistently used throughout the code. Thus also the parameter
+        * to get_timer() and its return value would need to be 64bit wide!
+        */
        return tick_to_time(get_ticks());
 }
 
 ulong get_timer(ulong base)
 {
-       return get_timer_masked() - base;
+       return tick_to_time(get_ticks() - time_to_tick(base));
 }
 
 /* delay x useconds AND preserve advance timstamp value */
 void __udelay(unsigned long usec)
 {
-       unsigned long long tmp;
-       ulong tmo;
+       unsigned long start = __raw_readl(&cur_gpt->counter);
+       unsigned long ticks;
+
+       if (usec == 0)
+               return;
 
-       tmo = us_to_tick(usec);
-       tmp = get_ticks() + tmo;        /* get current timestamp */
+       ticks = us_to_tick(usec);
+       if (ticks == 0)
+               ticks++;
 
-       while (get_ticks() < tmp)       /* loop till event */
-                /*NOP*/;
+       while (__raw_readl(&cur_gpt->counter) - start < ticks)
+               /* loop till event */;
 }
 
 /*
@@ -145,5 +175,5 @@ void __udelay(unsigned long usec)
  */
 ulong get_tbclk(void)
 {
-       return CLK_32KHZ;
+       return gd->timer_rate_hz;
 }
index ecd1184..c84ea05 100644 (file)
@@ -27,7 +27,12 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(SOC).o
 
-COBJS  = soc.o clock.o iomux.o
+COBJS  = soc.o clock.o
+ifneq ($(CONFIG_SYS_MX5_IOMUX_V3),)
+       COBJS +=  iomux-v3.o
+else
+       COBJS +=  iomux.o
+endif
 SOBJS = lowlevel_init.o
 
 SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
index e92f106..c4c8fbe 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/arch/crm_regs.h>
 #include <asm/arch/clock.h>
 #include <div64.h>
+#include <asm/arch/sys_proto.h>
 
 enum pll_clocks {
        PLL1_CLOCK = 0,
@@ -48,6 +49,39 @@ struct mxc_pll_reg *mxc_plls[PLL_CLOCKS] = {
 #endif
 };
 
+#define AHB_CLK_ROOT    133333333
+#define SZ_DEC_1M       1000000
+#define PLL_PD_MAX      16      /* Actual pd+1 */
+#define PLL_MFI_MAX     15
+#define PLL_MFI_MIN     5
+#define ARM_DIV_MAX     8
+#define IPG_DIV_MAX     4
+#define AHB_DIV_MAX     8
+#define EMI_DIV_MAX     8
+#define NFC_DIV_MAX     8
+
+struct fixed_pll_mfd {
+       u32 ref_clk_hz;
+       u32 mfd;
+};
+
+const struct fixed_pll_mfd fixed_mfd[] = {
+       {CONFIG_SYS_MX5_HCLK, 24 * 16},
+};
+
+struct pll_param {
+       u32 pd;
+       u32 mfi;
+       u32 mfn;
+       u32 mfd;
+};
+
+#define PLL_FREQ_MAX(ref_clk)  (4 * (ref_clk) * PLL_MFI_MAX)
+#define PLL_FREQ_MIN(ref_clk) \
+               ((2 * (ref_clk) * (PLL_MFI_MIN - 1)) / PLL_PD_MAX)
+#define MAX_DDR_CLK     420000000
+#define NFC_CLK_MAX     34000000
+
 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
 
 void set_usboh3_clk(void)
@@ -192,7 +226,7 @@ u32 get_mcu_main_clk(void)
 /*
  * Get the rate of peripheral's root clock.
  */
-static u32 get_periph_clk(void)
+u32 get_periph_clk(void)
 {
        u32 reg;
 
@@ -212,22 +246,6 @@ static u32 get_periph_clk(void)
        /* NOTREACHED */
 }
 
-/*
- * Get the rate of ahb clock.
- */
-static u32 get_ahb_clk(void)
-{
-       uint32_t freq, div, reg;
-
-       freq = get_periph_clk();
-
-       reg = __raw_readl(&mxc_ccm->cbcdr);
-       div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
-                       MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
-
-       return freq / div;
-}
-
 /*
  * Get the rate of ipg clock.
  */
@@ -306,7 +324,7 @@ static u32 get_uart_clk(void)
 /*
  * This function returns the low power audio clock.
  */
-u32 get_lp_apm(void)
+static u32 get_lp_apm(void)
 {
        u32 ret_val = 0;
        u32 ccsr = __raw_readl(&mxc_ccm->ccsr);
@@ -322,7 +340,7 @@ u32 get_lp_apm(void)
 /*
  * get cspi clock rate.
  */
-u32 imx_get_cspiclk(void)
+static u32 imx_get_cspiclk(void)
 {
        u32 ret_val = 0, pdf, pre_pdf, clk_sel;
        u32 cscmr1 = __raw_readl(&mxc_ccm->cscmr1);
@@ -359,8 +377,77 @@ u32 imx_get_cspiclk(void)
        return ret_val;
 }
 
+static u32 get_axi_a_clk(void)
+{
+       u32 cbcdr =  __raw_readl(&mxc_ccm->cbcdr);
+       u32 pdf = (cbcdr & MXC_CCM_CBCDR_AXI_A_PODF_MASK) \
+                       >> MXC_CCM_CBCDR_AXI_A_PODF_OFFSET;
+
+       return  get_periph_clk() / (pdf + 1);
+}
+
+static u32 get_axi_b_clk(void)
+{
+       u32 cbcdr =  __raw_readl(&mxc_ccm->cbcdr);
+       u32 pdf = (cbcdr & MXC_CCM_CBCDR_AXI_B_PODF_MASK) \
+                       >> MXC_CCM_CBCDR_AXI_B_PODF_OFFSET;
+
+       return  get_periph_clk() / (pdf + 1);
+}
+
+static u32 get_emi_slow_clk(void)
+{
+       u32 cbcdr = __raw_readl(&mxc_ccm->cbcdr);
+       u32 emi_clk_sel = cbcdr & MXC_CCM_CBCDR_EMI_CLK_SEL;
+       u32 pdf = (cbcdr & MXC_CCM_CBCDR_EMI_PODF_MASK) \
+                       >> MXC_CCM_CBCDR_EMI_PODF_OFFSET;
+
+       if (emi_clk_sel)
+               return  get_ahb_clk() / (pdf + 1);
+
+       return  get_periph_clk() / (pdf + 1);
+}
+
+static u32 get_ddr_clk(void)
+{
+       u32 ret_val = 0;
+       u32 cbcmr = __raw_readl(&mxc_ccm->cbcmr);
+       u32 ddr_clk_sel = (cbcmr & MXC_CCM_CBCMR_DDR_CLK_SEL_MASK) \
+                               >> MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET;
+#ifdef CONFIG_MX51
+       u32 cbcdr = __raw_readl(&mxc_ccm->cbcdr);
+       if (cbcdr & MXC_CCM_CBCDR_DDR_HIFREQ_SEL) {
+               u32 ddr_clk_podf = (cbcdr & MXC_CCM_CBCDR_DDR_PODF_MASK) >> \
+                                       MXC_CCM_CBCDR_DDR_PODF_OFFSET;
+
+               ret_val = decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_SYS_MX5_HCLK);
+               ret_val /= ddr_clk_podf + 1;
+
+               return ret_val;
+       }
+#endif
+       switch (ddr_clk_sel) {
+       case 0:
+               ret_val = get_axi_a_clk();
+               break;
+       case 1:
+               ret_val = get_axi_b_clk();
+               break;
+       case 2:
+               ret_val = get_emi_slow_clk();
+               break;
+       case 3:
+               ret_val = get_ahb_clk();
+               break;
+       default:
+               break;
+       }
+
+       return ret_val;
+}
+
 /*
- * The API of get mxc clockes.
+ * The API of get mxc clocks.
  */
 unsigned int mxc_get_clock(enum mxc_clock clk)
 {
@@ -380,10 +467,14 @@ unsigned int mxc_get_clock(enum mxc_clock clk)
        case MXC_FEC_CLK:
                return decode_pll(mxc_plls[PLL1_CLOCK],
                                    CONFIG_SYS_MX5_HCLK);
+       case MXC_SATA_CLK:
+               return get_ahb_clk();
+       case MXC_DDR_CLK:
+               return get_ddr_clk();
        default:
                break;
        }
-       return -1;
+       return -EINVAL;
 }
 
 u32 imx_get_uartclk(void)
@@ -397,6 +488,375 @@ u32 imx_get_fecclk(void)
        return mxc_get_clock(MXC_IPG_CLK);
 }
 
+static 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;
+}
+
+/*
+ * This is to calculate various parameters based on reference clock and
+ * targeted clock based on the equation:
+ *      t_clk = 2*ref_freq*(mfi + mfn/(mfd+1))/(pd+1)
+ * This calculation is based on a fixed MFD value for simplicity.
+ */
+static int calc_pll_params(u32 ref, u32 target, struct pll_param *pll)
+{
+       u64 pd, mfi = 1, mfn, mfd, t1;
+       u32 n_target = target;
+       u32 n_ref = ref, i;
+
+       /*
+        * Make sure targeted freq is in the valid range.
+        * Otherwise the following calculation might be wrong!!!
+        */
+       if (n_target < PLL_FREQ_MIN(ref) ||
+               n_target > PLL_FREQ_MAX(ref)) {
+               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;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(fixed_mfd); i++) {
+               if (fixed_mfd[i].ref_clk_hz == ref) {
+                       mfd = fixed_mfd[i].mfd;
+                       break;
+               }
+       }
+
+       if (i == ARRAY_SIZE(fixed_mfd))
+               return -EINVAL;
+
+       /* Use n_target and n_ref to avoid overflow */
+       for (pd = 1; pd <= PLL_PD_MAX; pd++) {
+               t1 = n_target * pd;
+               do_div(t1, (4 * n_ref));
+               mfi = t1;
+               if (mfi > PLL_MFI_MAX)
+                       return -EINVAL;
+               else if (mfi < 5)
+                       continue;
+               break;
+       }
+       /*
+        * Now got pd and mfi already
+        *
+        * mfn = (((n_target * pd) / 4 - n_ref * mfi) * mfd) / n_ref;
+        */
+       t1 = n_target * pd;
+       do_div(t1, 4);
+       t1 -= n_ref * mfi;
+       t1 *= mfd;
+       do_div(t1, n_ref);
+       mfn = t1;
+       debug("ref=%d, target=%d, pd=%d," "mfi=%d,mfn=%d, mfd=%d\n",
+               ref, n_target, (u32)pd, (u32)mfi, (u32)mfn, (u32)mfd);
+       i = 1;
+       if (mfn != 0)
+               i = gcd(mfd, mfn);
+       pll->pd = (u32)pd;
+       pll->mfi = (u32)mfi;
+       do_div(mfn, i);
+       pll->mfn = (u32)mfn;
+       do_div(mfd, i);
+       pll->mfd = (u32)mfd;
+
+       return 0;
+}
+
+#define calc_div(tgt_clk, src_clk, limit) ({           \
+               u32 v = 0;                              \
+               if (((src_clk) % (tgt_clk)) <= 100)     \
+                       v = (src_clk) / (tgt_clk);      \
+               else                                    \
+                       v = ((src_clk) / (tgt_clk)) + 1;\
+               if (v > limit)                          \
+                       v = limit;                      \
+               (v - 1);                                \
+       })
+
+#define CHANGE_PLL_SETTINGS(pll, pd, fi, fn, fd) \
+       {       \
+               __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 = __raw_readl(&mxc_ccm->ccsr);
+       struct mxc_pll_reg *pll = mxc_plls[index];
+
+       switch (index) {
+       case PLL1_CLOCK:
+               /* Switch ARM to PLL2 clock */
+               __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 */
+               __raw_writel(ccsr & ~0x4, &mxc_ccm->ccsr);
+               break;
+       case PLL2_CLOCK:
+               /* Switch to pll2 bypass clock */
+               __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 */
+               __raw_writel(ccsr & ~0x2, &mxc_ccm->ccsr);
+               break;
+       case PLL3_CLOCK:
+               /* Switch to pll3 bypass clock */
+               __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 */
+               __raw_writel(ccsr & ~0x1, &mxc_ccm->ccsr);
+               break;
+       case PLL4_CLOCK:
+               /* Switch to pll4 bypass clock */
+               __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 */
+               __raw_writel(ccsr & ~0x20, &mxc_ccm->ccsr);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+/* Config CPU clock */
+static int config_core_clk(u32 ref, u32 freq)
+{
+       int ret = 0;
+       struct pll_param pll_param;
+
+       memset(&pll_param, 0, sizeof(struct pll_param));
+
+       /* 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 for %u.%03uMHz ref %u.%03uMHz\n",
+                       freq / 1000000, freq / 1000 % 1000,
+                       ref / 1000000, ref / 1000 % 1000);
+               return ret;
+       }
+
+       return config_pll_clk(PLL1_CLOCK, &pll_param);
+}
+
+static int config_nfc_clk(u32 nfc_clk)
+{
+       u32 reg;
+       u32 parent_rate = get_emi_slow_clk();
+       u32 div = parent_rate / nfc_clk;
+
+       if (nfc_clk <= 0)
+               return -EINVAL;
+       if (div == 0)
+               div++;
+       if (parent_rate / div > NFC_CLK_MAX)
+               div++;
+       reg = __raw_readl(&mxc_ccm->cbcdr);
+       reg &= ~MXC_CCM_CBCDR_NFC_PODF_MASK;
+       reg |= (div - 1) << MXC_CCM_CBCDR_NFC_PODF_OFFSET;
+       __raw_writel(reg, &mxc_ccm->cbcdr);
+       while (__raw_readl(&mxc_ccm->cdhipr) != 0)
+               ;
+       return 0;
+}
+
+/* Config main_bus_clock for periphs */
+static int config_periph_clk(u32 ref, u32 freq)
+{
+       int ret = 0;
+       struct pll_param pll_param;
+
+       memset(&pll_param, 0, sizeof(struct pll_param));
+
+       if (__raw_readl(&mxc_ccm->cbcdr) & MXC_CCM_CBCDR_PERIPH_CLK_SEL) {
+               ret = calc_pll_params(ref, freq, &pll_param);
+               if (ret != 0) {
+                       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;
+               }
+               switch ((__raw_readl(&mxc_ccm->cbcmr) & \
+                       MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK) >> \
+                       MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET) {
+               case 0:
+                       return config_pll_clk(PLL1_CLOCK, &pll_param);
+
+               case 1:
+                       return config_pll_clk(PLL3_CLOCK, &pll_param);
+
+               default:
+                       return -EINVAL;
+               }
+       }
+
+       return 0;
+}
+
+static int config_ddr_clk(u32 emi_clk)
+{
+       u32 clk_src;
+       s32 shift = 0, clk_sel, div = 1;
+       u32 cbcmr = __raw_readl(&mxc_ccm->cbcmr);
+       u32 cbcdr = __raw_readl(&mxc_ccm->cbcdr);
+
+       if (emi_clk > MAX_DDR_CLK) {
+               printf("Warning: DDR clock should not exceed %d MHz\n",
+                       MAX_DDR_CLK / SZ_DEC_1M);
+               emi_clk = MAX_DDR_CLK;
+       }
+
+       clk_src = get_periph_clk();
+       /* Find DDR clock input */
+       clk_sel = (cbcmr >> 10) & 0x3;
+#ifdef CONFIG_MX51
+       if (cbcdr & MXC_CCM_CBCDR_DDR_HIFREQ_SEL) {
+               clk_src = decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_SYS_MX5_HCLK);
+               clk_sel = 4;
+       }
+#endif
+       switch (clk_sel) {
+       case 0:
+               shift = 16;
+               break;
+       case 1:
+               shift = 19;
+               break;
+       case 2:
+               shift = 22;
+               break;
+       case 3:
+               shift = 10;
+               break;
+       case 4:
+               shift = 27;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       if ((clk_src % emi_clk) < 10000000)
+               div = clk_src / emi_clk;
+       else
+               div = (clk_src / emi_clk) + 1;
+       if (--div > 7)
+               div = 7;
+
+       cbcdr &= ~(0x7 << shift);
+       cbcdr |= div << shift;
+       __raw_writel(cbcdr, &mxc_ccm->cbcdr);
+       while (__raw_readl(&mxc_ccm->cdhipr) != 0)
+               ;
+       __raw_writel(0x0, &mxc_ccm->ccdr);
+
+       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)
+{
+       freq *= SZ_DEC_1M;
+
+       switch (clk) {
+       case MXC_ARM_CLK:
+               if (config_core_clk(ref, freq))
+                       return -EINVAL;
+               break;
+       case MXC_PERIPH_CLK:
+               if (config_periph_clk(ref, freq))
+                       return -EINVAL;
+               break;
+       case MXC_DDR_CLK:
+               if (config_ddr_clk(freq))
+                       return -EINVAL;
+               break;
+       case MXC_NFC_CLK:
+               if (config_nfc_clk(freq))
+                       return -EINVAL;
+               break;
+       default:
+               printf("Warning: Unsupported or invalid clock type: %d\n",
+                       clk);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+#ifdef CONFIG_MX53
+/*
+ * The clock for the external interface can be set to use internal clock
+ * if fuse bank 4, row 3, bit 2 is set.
+ * This is an undocumented feature and it was confirmed by Freescale's support:
+ * Fuses (but not pins) may be used to configure SATA clocks.
+ * Particularly the i.MX53 Fuse_Map contains the next information
+ * about configuring SATA clocks :  SATA_ALT_REF_CLK[1:0] (offset 0x180C)
+ * '00' - 100MHz (External)
+ * '01' - 50MHz (External)
+ * '10' - 120MHz, internal (USB PHY)
+ * '11' - Reserved
+*/
+void mxc_set_sata_internal_clock(void)
+{
+       u32 *tmp_base = (u32 *)(IIM_BASE_ADDR + 0x180c);
+
+       set_usb_phy1_clk();
+
+       writel((readl(tmp_base) & ~0x7) | 0x4, tmp_base);
+}
+#endif
+
 /*
  * Dump some core clockes.
  */
@@ -419,6 +879,7 @@ int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
        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);
 
        return 0;
 }
diff --git a/arch/arm/cpu/armv7/mx5/iomux-v3.c b/arch/arm/cpu/armv7/mx5/iomux-v3.c
new file mode 100644 (file)
index 0000000..d61fa99
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ *                       <armlinux@phytec.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/iomux-v3.h>
+#include <asm/arch/sys_proto.h>
+
+static void __iomem *base = (void __iomem *)IOMUXC_BASE_ADDR;
+
+/*
+ * configures a single pad in the iomuxer
+ */
+int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad)
+{
+       u32 mux_ctrl_ofs = (pad & MUX_CTRL_OFS_MASK) >> MUX_CTRL_OFS_SHIFT;
+       u32 mux_mode = (pad & MUX_MODE_MASK) >> MUX_MODE_SHIFT;
+       u32 sel_input_ofs = (pad & MUX_SEL_INPUT_OFS_MASK) >> MUX_SEL_INPUT_OFS_SHIFT;
+       u32 sel_input = (pad & MUX_SEL_INPUT_MASK) >> MUX_SEL_INPUT_SHIFT;
+       u32 pad_ctrl_ofs = (pad & MUX_PAD_CTRL_OFS_MASK) >> MUX_PAD_CTRL_OFS_SHIFT;
+       u32 pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT;
+
+       if (mux_ctrl_ofs)
+               __raw_writel(mux_mode, base + mux_ctrl_ofs);
+
+       if (sel_input_ofs)
+               __raw_writel(sel_input, base + sel_input_ofs);
+
+       if (!(pad_ctrl & NO_PAD_CTRL) && pad_ctrl_ofs)
+               __raw_writel(pad_ctrl, base + pad_ctrl_ofs);
+
+       return 0;
+}
+
+int mxc_iomux_v3_setup_multiple_pads(const iomux_v3_cfg_t *pad_list, unsigned count)
+{
+       const iomux_v3_cfg_t *p = pad_list;
+       int i;
+       int ret;
+
+       for (i = 0; i < count; i++) {
+               ret = mxc_iomux_v3_setup_pad(*p);
+               if (ret)
+                       return ret;
+               p++;
+       }
+       return 0;
+}
index 74ab753..f3a15f6 100644 (file)
@@ -22,6 +22,7 @@
 #include <config.h>
 #include <asm/arch/imx-regs.h>
 #include <generated/asm-offsets.h>
+#include <linux/linkage.h>
 
 /*
  * L2CC Cache setup/invalidation/disable
 .endm /* init_m4if */
 
 .macro setup_pll pll, freq
-       ldr r0, =\pll
+       ldr r2, =\pll
        ldr r1, =0x00001232
-       str r1, [r0, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */
+       str r1, [r2, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */
        mov r1, #0x2
-       str r1, [r0, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */
+       str r1, [r2, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */
 
        ldr r1, W_DP_OP_\freq
-       str r1, [r0, #PLL_DP_OP]
-       str r1, [r0, #PLL_DP_HFS_OP]
+       str r1, [r2, #PLL_DP_OP]
+       str r1, [r2, #PLL_DP_HFS_OP]
 
        ldr r1, W_DP_MFD_\freq
-       str r1, [r0, #PLL_DP_MFD]
-       str r1, [r0, #PLL_DP_HFS_MFD]
+       str r1, [r2, #PLL_DP_MFD]
+       str r1, [r2, #PLL_DP_HFS_MFD]
 
        ldr r1,  W_DP_MFN_\freq
-       str r1, [r0, #PLL_DP_MFN]
-       str r1, [r0, #PLL_DP_HFS_MFN]
+       str r1, [r2, #PLL_DP_MFN]
+       str r1, [r2, #PLL_DP_HFS_MFN]
 
        ldr r1, =0x00001232
-       str r1, [r0, #PLL_DP_CTL]
-1:     ldr r1, [r0, #PLL_DP_CTL]
+       str r1, [r2, #PLL_DP_CTL]
+101:
+       ldr r1, [r2, #PLL_DP_CTL]
        ands r1, r1, #0x1
-       beq 1b
+       beq 101b
 .endm
 
 .macro setup_pll_errata pll, freq
 1:     ldr r1, [r0, #CLKCTL_CDHIPR]
        cmp r1, #0x0
        bne 1b
+#elif defined(CONFIG_TX53)
+       @ CCGR registers have been setup via DCD
 #else
        ldr r1, =0x3FFFFFFF
        str r1, [r0, #CLKCTL_CCGR0]
        setup_pll PLL1_BASE_ADDR, 864
        setup_pll_errata PLL1_BASE_ADDR, W_DP_MFN_800_DIT
 #else
+#if !defined(CONFIG_SYS_CPU_CLK) || CONFIG_SYS_CPU_CLK == 800
        setup_pll PLL1_BASE_ADDR, 800
+#elif CONFIG_SYS_CPU_CLK == 600
+       setup_pll PLL1_BASE_ADDR, 600
+#else
+#error Unsupported CONFIG_SYS_CPU_CLK value
+#endif
 #endif
 
 #if defined(CONFIG_MX51)
        setup_pll PLL3_BASE_ADDR, 665
 
        /* Switch peripheral to PLL 3 */
-       ldr r0, =CCM_BASE_ADDR
        ldr r1, =0x000010C0
-       orr r1,r1,#CONFIG_SYS_DDR_CLKSEL
+       orr r1, r1, #CONFIG_SYS_DDR_CLKSEL
        str r1, [r0, #CLKCTL_CBCMR]
        ldr r1, =0x13239145
        str r1, [r0, #CLKCTL_CBCDR]
        setup_pll PLL2_BASE_ADDR, 665
 
        /* Switch peripheral to PLL2 */
-       ldr r0, =CCM_BASE_ADDR
        ldr r1, =0x19239145
        str r1, [r0, #CLKCTL_CBCDR]
        ldr r1, =0x000020C0
        orr r1,r1,#CONFIG_SYS_DDR_CLKSEL
        str r1, [r0, #CLKCTL_CBCMR]
+#elif defined(CONFIG_TX53)
+       setup_pll PLL3_BASE_ADDR, 400
+
+       /* Switch peripheral to PLL 3 */
+       ldr r1, [r0, #CLKCTL_CBCMR]
+       bic r1, #(0x3 << 12)
+       orr r1, r1, #(1 << 12)
+       str r1, [r0, #CLKCTL_CBCMR]
+
+       ldr r1, [r0, #CLKCTL_CBCDR]
+       orr r1, r1, #(1 << 25)
+       str r1, [r0, #CLKCTL_CBCDR]
+1:
+       /* make sure change is effective */
+       ldr     r1, [r0, #CLKCTL_CDHIPR]
+       tst     r1, #0x7f
+       bne     1b
+#if CONFIG_SYS_SDRAM_CLK == 400
+       setup_pll PLL2_BASE_ADDR, 400
+#elif CONFIG_SYS_SDRAM_CLK == 333
+       setup_pll PLL2_BASE_ADDR, 333
+#else
+#error Unsupported CONFIG_SYS_SDRAM_CLK
+#endif
+       /* Switch peripheral to PLL2 */
+       ldr r0, =CCM_BASE_ADDR
+       ldr r1, [r0, #CLKCTL_CBCDR]
+       bic r1, #(1 << 25)
+       str r1, [r0, #CLKCTL_CBCDR]
+
+       ldr r1, [r0, #CLKCTL_CBCMR]
+       bic r1, #(3 << 12)
+       orr r1, #(2 << 12)
+       str r1, [r0, #CLKCTL_CBCMR]
+
+       /* make sure change is effective */
+1:
+       ldr     r1, [r0, #CLKCTL_CDHIPR]
+       cmp     r1, #0x0
+       bne     1b
 #endif
        setup_pll PLL3_BASE_ADDR, 216
 
        movhi r1, #0
 #else
        mov r1, #0
-
 #endif
        str r1, [r0, #CLKCTL_CACRR]
        /* Switch ARM back to PLL 1 */
        ldr r1, =CONFIG_SYS_CLKTL_CBCDR
        str r1, [r0, #CLKCTL_CBCDR]
 #endif
-
+#ifndef CONFIG_TX53
        /* Restore the default values in the Gate registers */
        ldr r1, =0xFFFFFFFF
        str r1, [r0, #CLKCTL_CCGR0]
 #if defined(CONFIG_MX53)
        str r1, [r0, #CLKCTL_CCGR7]
 #endif
+#endif
 
+#if !defined(CONFIG_TX53)
 #if defined(CONFIG_MX51)
        /* Use PLL 2 for UART's, get 66.5MHz from it */
        ldr r1, =0xA5A2A020
        str r1, [r0, #CLKCTL_CSCDR1]
 #elif defined(CONFIG_MX53)
        /* Switch peripheral to PLL2 */
-       ldr r0, =CCM_BASE_ADDR
        ldr r1, =0x00808145
        orr r1, r1, #(2 << 10)
        orr r1, r1, #(0 << 16)
        str r1, [r0, #CLKCTL_CBCMR]
        /* Change uart clk parent to pll2*/
        ldr r1, [r0, #CLKCTL_CSCMR1]
-       and r1, r1, #0xfcffffff
-       orr r1, r1, #0x01000000
+       bic r1, #(0x3 << 24)
+       orr r1, r1, #(0x1 << 24)
        str r1, [r0, #CLKCTL_CSCMR1]
        ldr r1, [r0, #CLKCTL_CSCDR1]
-       and r1, r1, #0xffffffc0
+       bic r1, #(0x3f << 0)
        orr r1, r1, #0x0a
        str r1, [r0, #CLKCTL_CSCDR1]
 #endif
 1:     ldr r1, [r0, #CLKCTL_CDHIPR]
        cmp r1, #0x0
        bne 1b
-
+#endif
        mov r1, #0x0
        str r1, [r0, #CLKCTL_CCDR]
 
 
 .section ".text.init", "x"
 
-.globl lowlevel_init
-lowlevel_init:
+ENTRY(lowlevel_init)
 #if defined(CONFIG_MX51)
        ldr r0, =GPIO1_BASE_ADDR
        ldr r1, [r0, #0x0]
@@ -348,6 +395,7 @@ lowlevel_init:
 
        /* r12 saved upper lr*/
        mov pc,lr
+ENDPROC(lowlevel_init)
 
 /* Board level setting value */
 W_DP_OP_864:              .word DP_OP_864
@@ -360,6 +408,15 @@ W_DP_MFN_800:             .word DP_MFN_800
 W_DP_OP_665:              .word DP_OP_665
 W_DP_MFD_665:             .word DP_MFD_665
 W_DP_MFN_665:             .word DP_MFN_665
+W_DP_OP_600:              .word DP_OP_600
+W_DP_MFD_600:             .word DP_MFD_600
+W_DP_MFN_600:             .word DP_MFN_600
+W_DP_OP_400:              .word DP_OP_400
+W_DP_MFD_400:             .word DP_MFD_400
+W_DP_MFN_400:             .word DP_MFN_400
+W_DP_OP_333:              .word DP_OP_333
+W_DP_MFD_333:             .word DP_MFD_333
+W_DP_MFN_333:             .word DP_MFN_333
 W_DP_OP_216:              .word DP_OP_216
 W_DP_MFD_216:             .word DP_MFD_216
 W_DP_MFN_216:             .word DP_MFN_216
index 3f5a4f7..d104a66 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