[Armadeus-commitlog] armadeus branch, master, updated. armadeus-4.0-2598-g4aa3988
Brought to you by:
sszy
|
From: jorasse <jo...@us...> - 2011-12-02 00:44:09
|
This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "armadeus".
The branch, master has been updated
via 4aa3988714511f0fd381845e75a55039f358109e (commit)
via c3deb6824d5fb9fb5bcfce414726171d015e535c (commit)
from 682e0466ccd6120597956f70e2ea4aed255455cc (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
- Log -----------------------------------------------------------------
commit 4aa3988714511f0fd381845e75a55039f358109e
Merge: c3deb68 682e046
Author: Eric Jarrige <eri...@ar...>
Date: Fri Dec 2 01:43:02 2011 +0100
Merge branch 'master' of ssh://armadeus.git.sourceforge.net/gitroot/armadeus/armadeus
commit c3deb6824d5fb9fb5bcfce414726171d015e535c
Author: Eric Jarrige <eri...@ar...>
Date: Fri Dec 2 01:42:29 2011 +0100
[UBOOT][APF28] Add preliminary U-Boot patch & config to support the apf28 board
-----------------------------------------------------------------------
Summary of changes:
.../target/device/armadeus/apf28/apf28-u-boot-.h | 281 +++
patches/u-boot/2011.11/01-uboot-apf28.patch | 2220 ++++++++++++++++++++
2 files changed, 2501 insertions(+), 0 deletions(-)
create mode 100644 buildroot/target/device/armadeus/apf28/apf28-u-boot-.h
create mode 100644 patches/u-boot/2011.11/01-uboot-apf28.patch
diff --git a/buildroot/target/device/armadeus/apf28/apf28-u-boot-.h b/buildroot/target/device/armadeus/apf28/apf28-u-boot-.h
new file mode 100644
index 0000000..d11554c
--- /dev/null
+++ b/buildroot/target/device/armadeus/apf28/apf28-u-boot-.h
@@ -0,0 +1,281 @@
+/*
+ * Configuration settings for the Armadeus Project apf28 board.
+ *
+ * Copyright (C) 2011 Eric Jarrige, Armadeus Project
+ * Copyright (C) 2011 Marek Vasut <mar...@gm...>
+ * on behalf of DENX Software Engineering GmbH
+ *
+ * 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
+ */
+#ifndef __APF28_H__
+#define __APF28_H__
+
+#include <asm/arch/regs-base.h>
+
+#define CONFIG_ENV_VERSION "0.1"
+#define CONFIG_IDENT_STRING " apf28 patch 0.1"
+
+/*
+ * SoC configurations
+ */
+#define CONFIG_MX28 /* i.MX28 SoC */
+#define CONFIG_MXS_GPIO /* GPIO control */
+#define CONFIG_SYS_HZ 1000 /* Ticks per second */
+
+/*
+ * Define APF28 machine type by hand until it lands in mach-types
+ */
+#define MACH_TYPE_APF28 3845
+
+#define CONFIG_MACH_TYPE MACH_TYPE_APF28
+
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_SYS_ICACHE_OFF
+#define CONFIG_SYS_DCACHE_OFF
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_ARCH_CPU_INIT
+#define CONFIG_ARCH_MISC_INIT
+
+/*
+ * SPL
+ */
+#define CONFIG_SPL
+#define CONFIG_SPL_NO_CPU_SUPPORT_CODE
+#define CONFIG_SPL_START_S_PATH "board/armadeus/apf28"
+#define CONFIG_SPL_LDSCRIPT "board/armadeus/apf28/u-boot-spl.lds"
+
+/*
+ * U-Boot Commands
+ */
+#include <config_cmd_default.h>
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DOS_PARTITION
+
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_DATE
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_GPIO
+#define CONFIG_CMD_I2C
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_NAND
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_NFS
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_SETEXPR
+#define CONFIG_CMD_SPI
+#define CONFIG_CMD_USB
+
+/*
+ * Memory configurations
+ */
+#define CONFIG_NR_DRAM_BANKS 1 /* 1 bank of DRAM */
+#define PHYS_SDRAM_1 0x40000000 /* Base address */
+#define PHYS_SDRAM_1_SIZE 0x40000000 /* Max 1 GB RAM */
+#define CONFIG_STACKSIZE 0x00010000 /* 128 KB stack */
+#define CONFIG_SYS_MALLOC_LEN 0x00400000 /* 4 MB for malloc */
+#define CONFIG_SYS_GBL_DATA_SIZE 128 /* Initial data */
+#define CONFIG_SYS_MEMTEST_START 0x40000000 /* Memtest start adr */
+#define CONFIG_SYS_MEMTEST_END 0x40400000 /* 4 MB RAM test */
+#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
+/* Point initial SP in SRAM so SPL can use it too. */
+#define CONFIG_SYS_INIT_SP_ADDR 0x00002000
+/*
+ * We need to sacrifice first 4 bytes of RAM here to avoid triggering some
+ * strange BUG in ROM corrupting first 4 bytes of RAM when loading U-Boot
+ * binary. In case there was more of this mess, 0x100 bytes are skipped.
+ */
+#define CONFIG_SYS_TEXT_BASE 0x40000100
+
+/*
+ * U-Boot general configurations
+ */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_PROMPT "BIOS> "
+#define CONFIG_SYS_CBSIZE 1024 /* Console I/O buffer size */
+#define CONFIG_SYS_PBSIZE \
+ (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+ /* Print buffer size */
+#define CONFIG_SYS_MAXARGS 32 /* Max number of command args */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+ /* Boot argument buffer size */
+#define CONFIG_VERSION_VARIABLE /* U-BOOT version */
+#define CONFIG_AUTO_COMPLETE /* Command auto complete */
+#define CONFIG_CMDLINE_EDITING /* Command history etc */
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+
+/*
+ * Serial Driver
+ */
+#define CONFIG_PL011_SERIAL
+#define CONFIG_PL011_CLOCK 24000000
+#define CONFIG_PL01x_PORTS { (void *)MXS_UARTDBG_BASE }
+#define CONFIG_CONS_INDEX 0
+#define CONFIG_BAUDRATE 115200 /* Default baud rate */
+#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+/*
+ * MMC Driver
+ */
+#ifdef CONFIG_CMD_MMC
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_MXS_MMC
+#endif
+
+/*
+ * NAND
+ */
+#ifdef CONFIG_CMD_NAND
+#define CONFIG_NAND_MXS
+#define CONFIG_APBH_DMA
+#define CONFIG_SYS_MAX_NAND_DEVICE 1
+#define CONFIG_SYS_NAND_BASE 0x60000000
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#define NAND_MAX_CHIPS 1
+
+/* Environment is in NAND */
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_SIZE (16 * 1024)
+#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
+#define CONFIG_ENV_SECT_SIZE (128 * 1024)
+#define CONFIG_ENV_RANGE (512 * 1024)
+#define CONFIG_ENV_OFFSET 0x200000
+#define CONFIG_ENV_OFFSET_REDUND \
+ (CONFIG_ENV_OFFSET + CONFIG_ENV_RANGE)
+
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_RBTREE
+#define CONFIG_LZO
+#define CONFIG_MTD_DEVICE
+#define CONFIG_MTD_PARTITIONS
+#define MTDIDS_DEFAULT "nand0=gpmi-nand.0"
+#define MTDPARTS_DEFAULT \
+ "mtdparts=gpmi-nand.0:" \
+ "2M(bootloader)ro," \
+ "512k(environment)," \
+ "512k(redundant-environment)," \
+ "8M(kernel)," \
+ "-(rootfs)"
+#endif
+
+/*
+ * Ethernet on SOC (FEC)
+ */
+#ifdef CONFIG_CMD_NET
+#define CONFIG_NET_MULTI
+#define CONFIG_ETHPRIME "FEC0"
+#define CONFIG_FEC_MXC
+#define CONFIG_FEC_MXC_MULTI
+#define CONFIG_MII
+#define CONFIG_DISCOVER_PHY
+#define CONFIG_FEC_XCV_TYPE RMII
+#endif
+
+/*
+ * I2C
+ */
+#ifdef CONFIG_CMD_I2C
+#define CONFIG_I2C_MXS
+#define CONFIG_HARD_I2C
+#define CONFIG_SYS_I2C_SPEED 400000
+#endif
+
+/*
+ * RTC
+ */
+#ifdef CONFIG_CMD_DATE
+/* Use the internal RTC in the MXS chip */
+#define CONFIG_RTC_INTERNAL
+#define CONFIG_RTC_MXS
+#endif
+
+/*
+ * USB
+ */
+#ifdef CONFIG_CMD_USB
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_MXS
+#define CONFIG_EHCI_MXS_PORT 1
+#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_STORAGE
+#endif
+
+/*
+ * SPI
+ */
+#ifdef CONFIG_CMD_SPI
+#define CONFIG_HARD_SPI
+#define CONFIG_MXS_SPI
+#define CONFIG_SPI_HALF_DUPLEX
+#define CONFIG_DEFAULT_SPI_BUS 2
+#define CONFIG_DEFAULT_SPI_MODE SPI_MODE_0
+#endif
+
+/*
+ * Boot Linux
+ */
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_BOOTDELAY 3
+#define CONFIG_BOOTFILE "uImage"
+#define CONFIG_BOOTARGS "console=ttyAM0,115200n8 "
+#define CONFIG_BOOTCOMMAND "run bootcmd_net"
+#define CONFIG_LOADADDR 0x42000000
+#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
+
+/*
+ * Extra Environments
+ */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "env_version=" CONFIG_ENV_VERSION "\0" \
+ "update_nand_full_filename=u-boot.nand\0" \
+ "update_nand_firmware_filename=u-boot.sb\0" \
+ "update_nand_firmware_maxsz=0x80000\0" \
+ "update_nand_stride=0x40\0" /* MX28 datasheet ch. 12.12 */ \
+ "update_nand_count=0x4\0" /* MX28 datasheet ch. 12.12 */ \
+ "update_nand_get_fcb_size=" /* Get size of FCB blocks */ \
+ "nand device 0 ; " \
+ "nand info ; " \
+ "setexpr fcb_sz ${update_nand_stride} * ${update_nand_count};" \
+ "setexpr update_nand_fcb ${fcb_sz} * ${nand_writesize}\0" \
+ "update_nand_full=" /* Update FCB, DBBT and FW */ \
+ "if tftp ${update_nand_full_filename} ; then " \
+ "run update_nand_get_fcb_size ; " \
+ "nand scrub -y 0x0 ${filesize} ; " \
+ "nand write.raw ${loadaddr} 0x0 ${update_nand_fcb} ; " \
+ "setexpr update_off ${loadaddr} + ${update_nand_fcb} ; " \
+ "setexpr update_sz ${filesize} - ${update_nand_fcb} ; " \
+ "nand write ${update_off} ${update_nand_fcb} ${update_sz} ; " \
+ "fi\0" \
+ "update_nand_firmware=" /* Update only firmware */ \
+ "if tftp ${update_nand_firmware_filename} ; then " \
+ "run update_nand_get_fcb_size ; " \
+ "setexpr fcb_sz ${update_nand_fcb} * 2 ; " /* FCB + DBBT */ \
+ "setexpr fw_sz ${update_nand_firmware_maxsz} * 2 ; " \
+ "setexpr fw_off ${fcb_sz} + ${update_nand_firmware_maxsz};" \
+ "nand erase ${fcb_sz} ${fw_sz} ; " \
+ "nand write ${loadaddr} ${fcb_sz} ${filesize} ; " \
+ "nand write ${loadaddr} ${fw_off} ${filesize} ; " \
+ "fi\0"
+
+#endif /* __APF28_H__ */
+
diff --git a/patches/u-boot/2011.11/01-uboot-apf28.patch b/patches/u-boot/2011.11/01-uboot-apf28.patch
new file mode 100644
index 0000000..eb30c8d
--- /dev/null
+++ b/patches/u-boot/2011.11/01-uboot-apf28.patch
@@ -0,0 +1,2220 @@
+--- u-boot-orig/board/armadeus/apf28/apf28.c 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-custom/board/armadeus/apf28/apf28.c 2011-12-01 19:05:09.737024396 +0100
+@@ -0,0 +1,212 @@
++/*
++ * APF28 motherboard based on DENX M28 module
++ *
++ * Copyright (C) 2011 Marek Vasut <mar...@gm...>
++ * 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 <asm/gpio.h>
++#include <asm/io.h>
++#include <asm/arch/imx-regs.h>
++#include <asm/arch/iomux-mx28.h>
++#include <asm/arch/clock.h>
++#include <asm/arch/sys_proto.h>
++#include <linux/mii.h>
++#include <miiphy.h>
++#include <netdev.h>
++#include <errno.h>
++
++DECLARE_GLOBAL_DATA_PTR;
++
++/*
++ * Functions
++ */
++int board_early_init_f(void)
++{
++ /* IO0 clock at 480MHz */
++ mx28_set_ioclk(MXC_IOCLK0, 480000);
++ /* IO1 clock at 480MHz */
++ mx28_set_ioclk(MXC_IOCLK1, 480000);
++
++ /* SSP0 clock at 96MHz */
++ mx28_set_sspclk(MXC_SSPCLK0, 96000, 0);
++ /* SSP2 clock at 96MHz */
++ mx28_set_sspclk(MXC_SSPCLK2, 96000, 0);
++
++#ifdef CONFIG_CMD_USB
++ mxs_iomux_setup_pad(MX28_PAD_LCD_D23__GPIO_1_23 |
++ MXS_PAD_12MA | MXS_PAD_3V3 | MXS_PAD_PULLUP);
++ gpio_direction_output(MX28_PAD_LCD_D23__GPIO_1_23, 0);
++#endif
++
++ return 0;
++}
++
++int board_init(void)
++{
++ /* Adress of boot parameters */
++ gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
++
++ return 0;
++}
++
++#define HW_DIGCTRL_SCRATCH0 0x8001c280
++#define HW_DIGCTRL_SCRATCH1 0x8001c290
++int dram_init(void)
++{
++ uint32_t sz[2];
++
++ sz[0] = readl(HW_DIGCTRL_SCRATCH0);
++ sz[1] = readl(HW_DIGCTRL_SCRATCH1);
++
++ if (sz[0] != sz[1]) {
++ 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");
++ hang();
++ }
++
++ gd->ram_size = sz[0];
++ return 0;
++}
++
++#ifdef CONFIG_CMD_MMC
++static int m28_mmc_wp(int id)
++{
++ if (id != 0) {
++ printf("MXS MMC: Invalid card selected (card id = %d)\n", id);
++ return 1;
++ }
++
++ return 0;
++}
++
++int board_mmc_init(bd_t *bis)
++{
++ return mxsmmc_initialize(bis, 0, m28_mmc_wp);
++}
++#endif
++
++#ifdef CONFIG_CMD_NET
++
++#define MII_OPMODE_STRAP_OVERRIDE 0x16
++#define MII_PHY_CTRL1 0x1e
++#define MII_PHY_CTRL2 0x1f
++
++int fecmxc_mii_postcall(int phy)
++{
++ miiphy_write("FEC1", phy, MII_BMCR, 0x9000);
++ miiphy_write("FEC1", phy, MII_OPMODE_STRAP_OVERRIDE, 0x0202);
++ if (phy == 3)
++ miiphy_write("FEC1", 3, MII_PHY_CTRL2, 0x8180);
++ return 0;
++}
++
++int board_eth_init(bd_t *bis)
++{
++ struct mx28_clkctrl_regs *clkctrl_regs =
++ (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
++ struct eth_device *dev;
++ int ret;
++
++ ret = cpu_eth_init(bis);
++
++ clrsetbits_le32(&clkctrl_regs->hw_clkctrl_enet,
++ CLKCTRL_ENET_TIME_SEL_MASK | CLKCTRL_ENET_CLK_OUT_EN,
++ CLKCTRL_ENET_TIME_SEL_RMII_CLK);
++
++ ret = fecmxc_initialize_multi(bis, 0, 0, MXS_ENET0_BASE);
++ if (ret) {
++ printf("FEC MXS: Unable to init FEC0\n");
++ return ret;
++ }
++
++ ret = fecmxc_initialize_multi(bis, 1, 3, MXS_ENET1_BASE);
++ if (ret) {
++ printf("FEC MXS: Unable to init FEC1\n");
++ return ret;
++ }
++
++ dev = eth_get_dev_by_name("FEC0");
++ if (!dev) {
++ printf("FEC MXS: Unable to get FEC0 device entry\n");
++ return -EINVAL;
++ }
++
++ ret = fecmxc_register_mii_postcall(dev, fecmxc_mii_postcall);
++ if (ret) {
++ printf("FEC MXS: Unable to register FEC0 mii postcall\n");
++ return ret;
++ }
++
++ dev = eth_get_dev_by_name("FEC1");
++ if (!dev) {
++ printf("FEC MXS: Unable to get FEC1 device entry\n");
++ return -EINVAL;
++ }
++
++ ret = fecmxc_register_mii_postcall(dev, fecmxc_mii_postcall);
++ if (ret) {
++ printf("FEC MXS: Unable to register FEC1 mii postcall\n");
++ return ret;
++ }
++
++ return ret;
++}
++
++#ifdef CONFIG_M28_FEC_MAC_IN_OCOTP
++
++#define MXS_OCOTP_MAX_TIMEOUT 1000000
++void imx_get_mac_from_fuse(char *mac)
++{
++ struct mx28_ocotp_regs *ocotp_regs =
++ (struct mx28_ocotp_regs *)MXS_OCOTP_BASE;
++ uint32_t data;
++
++ memset(mac, 0, 6);
++
++ writel(OCOTP_CTRL_RD_BANK_OPEN, &ocotp_regs->hw_ocotp_ctrl_set);
++
++ if (mx28_wait_mask_clr(&ocotp_regs->hw_ocotp_ctrl_reg, OCOTP_CTRL_BUSY,
++ MXS_OCOTP_MAX_TIMEOUT)) {
++ printf("MXS FEC: Can't get MAC from OCOTP\n");
++ return;
++ }
++
++ data = readl(&ocotp_regs->hw_ocotp_cust0);
++
++ mac[0] = 0x00;
++ mac[1] = 0x1E;
++ mac[2] = (data >> 24) & 0xff;
++ mac[3] = (data >> 16) & 0xff;
++ mac[4] = (data >> 8) & 0xff;
++ mac[5] = data & 0xff;
++}
++#else
++void imx_get_mac_from_fuse(char *mac)
++{
++ memset(mac, 0, 6);
++}
++#endif
++
++#endif
+--- u-boot-orig/board/armadeus/apf28/m28_init.h 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-custom/board/armadeus/apf28/m28_init.h 2011-11-27 11:31:22.299138403 +0100
+@@ -0,0 +1,41 @@
++/*
++ * Freescale i.MX28 SPL functions
++ *
++ * Copyright (C) 2011 Marek Vasut <mar...@gm...>
++ * 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
++ */
++
++#ifndef __M28_INIT_H__
++#define __M28_INIT_H__
++
++void early_delay(int delay);
++
++void mx28_power_init(void);
++
++#ifdef CONFIG_SPL_MX28_PSWITCH_WAIT
++void mx28_power_wait_pswitch(void);
++#else
++static inline void mx28_power_wait_pswitch(void) { }
++#endif
++
++void mx28_mem_init(void);
++
++#endif /* __M28_INIT_H__ */
+--- u-boot-orig/board/armadeus/apf28/Makefile 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-custom/board/armadeus/apf28/Makefile 2011-11-27 11:31:22.299138403 +0100
+@@ -0,0 +1,56 @@
++#
++# (C) Copyright 2000-2006
++# Wolfgang Denk, DENX Software Engineering, wd...@de....
++#
++# 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 $(TOPDIR)/config.mk
++
++LIB = $(obj)lib$(BOARD).o
++
++ifndef CONFIG_SPL_BUILD
++COBJS := apf28.o
++endif
++
++ifdef CONFIG_SPL_BUILD
++COBJS := mem_init.o mmc_boot.o power_init.o memsize.o
++endif
++
++SRCS := $(COBJS:.o=.c)
++OBJS := $(addprefix $(obj),$(COBJS))
++
++$(LIB): $(obj).depend $(OBJS)
++ $(call cmd_link_o_target, $(OBJS))
++
++all: $(ALL)
++
++ifdef CONFIG_SPL_BUILD
++memsize.c:
++ ln -sf $(TOPDIR)/common/memsize.c $@
++endif
++
++#########################################################################
++
++# defines $(obj).depend target
++include $(SRCTREE)/rules.mk
++
++sinclude $(obj).depend
++
++#########################################################################
+--- u-boot-orig/board/armadeus/apf28/mem_init.c 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-custom/board/armadeus/apf28/mem_init.c 2011-11-27 11:31:22.299138403 +0100
+@@ -0,0 +1,240 @@
++/*
++ * Freescale i.MX28 RAM init
++ *
++ * Copyright (C) 2011 Marek Vasut <mar...@gm...>
++ * 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/iomux-mx28.h>
++#include <asm/arch/imx-regs.h>
++
++#include "m28_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, 0x0f02020a,
++ 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;
++
++ for (i = 0; i < ARRAY_SIZE(dram_vals); i++)
++ writel(dram_vals[i], MXS_DRAM_BASE + (4 * i));
++}
++
++void mx28_mem_init_clock(void)
++{
++ struct mx28_clkctrl_regs *clkctrl_regs =
++ (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
++
++ /* Gate EMI clock */
++ writel(CLKCTRL_FRAC0_CLKGATEEMI,
++ &clkctrl_regs->hw_clkctrl_frac0_set);
++
++ /* EMI = 205MHz */
++ writel(CLKCTRL_FRAC0_EMIFRAC_MASK,
++ &clkctrl_regs->hw_clkctrl_frac0_set);
++ writel((0x2a << CLKCTRL_FRAC0_EMIFRAC_OFFSET) &
++ CLKCTRL_FRAC0_EMIFRAC_MASK,
++ &clkctrl_regs->hw_clkctrl_frac0_clr);
++
++ /* Ungate EMI clock */
++ writel(CLKCTRL_FRAC0_CLKGATEEMI,
++ &clkctrl_regs->hw_clkctrl_frac0_clr);
++
++ early_delay(11000);
++
++ writel((2 << CLKCTRL_EMI_DIV_EMI_OFFSET) |
++ (1 << CLKCTRL_EMI_DIV_XTAL_OFFSET),
++ &clkctrl_regs->hw_clkctrl_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)
++{
++ struct mx28_clkctrl_regs *clkctrl_regs =
++ (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
++
++ /* CPU = 454MHz and ungate CPU clock */
++ clrsetbits_le32(&clkctrl_regs->hw_clkctrl_frac0,
++ CLKCTRL_FRAC0_CPUFRAC_MASK | CLKCTRL_FRAC0_CLKGATECPU,
++ 19 << CLKCTRL_FRAC0_CPUFRAC_OFFSET);
++
++ /* Set CPU bypass */
++ writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
++ &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);
++
++ /* CPU clock divider = 1 */
++ clrsetbits_le32(&clkctrl_regs->hw_clkctrl_cpu,
++ CLKCTRL_CPU_DIV_CPU_MASK, 1);
++
++ /* 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);
++}
++
++void mx28_mem_setup_vddd(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);
++}
++
++#define HW_DIGCTRL_SCRATCH0 0x8001c280
++#define HW_DIGCTRL_SCRATCH1 0x8001c290
++void data_abort_memdetect_handler(void) __attribute__((naked));
++void data_abort_memdetect_handler(void)
++{
++ asm volatile("subs pc, r14, #4");
++}
++
++void mx28_mem_get_size(void)
++{
++ uint32_t sz, da;
++ uint32_t *vt = (uint32_t *)0x20;
++
++ /* Replace the DABT handler. */
++ da = vt[4];
++ vt[4] = (uint32_t)&data_abort_memdetect_handler;
++
++ sz = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
++ writel(sz, HW_DIGCTRL_SCRATCH0);
++ writel(sz, HW_DIGCTRL_SCRATCH1);
++
++ /* Restore the old DABT handler. */
++ vt[4] = da;
++}
++
++void mx28_mem_init(void)
++{
++ struct mx28_clkctrl_regs *clkctrl_regs =
++ (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
++ struct mx28_pinctrl_regs *pinctrl_regs =
++ (struct mx28_pinctrl_regs *)MXS_PINCTRL_BASE;
++
++ /* Set DDR2 mode */
++ writel(PINCTRL_EMI_DS_CTRL_DDR_MODE_DDR2,
++ &pinctrl_regs->hw_pinctrl_emi_ds_ctrl_set);
++
++ /* Power up PLL0 */
++ writel(CLKCTRL_PLL0CTRL0_POWER,
++ &clkctrl_regs->hw_clkctrl_pll0ctrl0_set);
++
++ early_delay(11000);
++
++ mx28_mem_init_clock();
++
++ mx28_mem_setup_vdda();
++
++ /*
++ * Configure the DRAM registers
++ */
++
++ /* Clear START bit from DRAM_CTL16 */
++ clrbits_le32(MXS_DRAM_BASE + 0x40, 1);
++
++ init_m28_200mhz_ddr2();
++
++ /* Clear SREFRESH bit from DRAM_CTL17 */
++ clrbits_le32(MXS_DRAM_BASE + 0x44, 1);
++
++ /* Set START bit in DRAM_CTL16 */
++ setbits_le32(MXS_DRAM_BASE + 0x40, 1);
++
++ /* Wait for bit 20 (DRAM init complete) in DRAM_CTL58 */
++ 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();
++}
+--- u-boot-orig/board/armadeus/apf28/memsize.c 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-custom/board/armadeus/apf28/memsize.c 2011-11-23 21:23:45.000000000 +0100
+@@ -0,0 +1,94 @@
++/*
++ * (C) Copyright 2004
++ * Wolfgang Denk, DENX Software Engineering, wd...@de....
++ *
++ * 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 <config.h>
++#ifdef __PPC__
++/*
++ * At least on G2 PowerPC cores, sequential accesses to non-existent
++ * memory must be synchronized.
++ */
++# include <asm/io.h> /* for sync() */
++#else
++# define sync() /* nothing */
++#endif
++
++/*
++ * Check memory range for valid RAM. A simple memory test determines
++ * the actually available RAM size between addresses `base' and
++ * `base + maxsize'.
++ */
++long get_ram_size(long *base, long maxsize)
++{
++ volatile long *addr;
++ long save[32];
++ long cnt;
++ long val;
++ long size;
++ int i = 0;
++
++ for (cnt = (maxsize / sizeof (long)) >> 1; cnt > 0; cnt >>= 1) {
++ addr = base + cnt; /* pointer arith! */
++ sync ();
++ save[i++] = *addr;
++ sync ();
++ *addr = ~cnt;
++ }
++
++ addr = base;
++ sync ();
++ save[i] = *addr;
++ sync ();
++ *addr = 0;
++
++ sync ();
++ if ((val = *addr) != 0) {
++ /* Restore the original data before leaving the function.
++ */
++ sync ();
++ *addr = save[i];
++ for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) {
++ addr = base + cnt;
++ sync ();
++ *addr = save[--i];
++ }
++ return (0);
++ }
++
++ for (cnt = 1; cnt < maxsize / sizeof (long); cnt <<= 1) {
++ addr = base + cnt; /* pointer arith! */
++ val = *addr;
++ *addr = save[--i];
++ if (val != ~cnt) {
++ size = cnt * sizeof (long);
++ /* Restore the original data before leaving the function.
++ */
++ for (cnt <<= 1; cnt < maxsize / sizeof (long); cnt <<= 1) {
++ addr = base + cnt;
++ *addr = save[--i];
++ }
++ return (size);
++ }
++ }
++
++ return (maxsize);
++}
+--- u-boot-orig/board/armadeus/apf28/mmc_boot.c 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-custom/board/armadeus/apf28/mmc_boot.c 2011-12-01 19:32:00.022103665 +0100
+@@ -0,0 +1,273 @@
++/*
++ * Freescale i.MX28 Boot setup
++ *
++ * Copyright (C) 2011 Marek Vasut <mar...@gm...>
++ * 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/iomux-mx28.h>
++
++#include "m28_init.h"
++
++/*
++ * This delay function is intended to be used only in early stage of boot, where
++ * clock are not set up yet. The timer used here is reset on every boot and
++ * 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.
++ */
++#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))
++ ;
++}
++
++#define MUX_CONFIG_LED (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
++#define MUX_CONFIG_LCD (MXS_PAD_3V3 | MXS_PAD_4MA)
++#define MUX_CONFIG_TSC (MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_PULLUP)
++#define MUX_CONFIG_SSP0 (MXS_PAD_3V3 | MXS_PAD_12MA | MXS_PAD_PULLUP)
++#define MUX_CONFIG_SSP2 (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_PULLUP)
++#define MUX_CONFIG_GPMI (MXS_PAD_1V8 | MXS_PAD_4MA | MXS_PAD_NOPULL)
++#define MUX_CONFIG_ENET (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_PULLUP)
++#define MUX_CONFIG_EMI (MXS_PAD_3V3 | MXS_PAD_12MA | MXS_PAD_NOPULL)
++
++const iomux_cfg_t iomux_setup[] = {
++ /* LED */
++ /*MX28_PAD_ENET0_RXD3__GPIO_4_10 | MUX_CONFIG_LED,*/
++
++ /* framebuffer */
++ MX28_PAD_LCD_D00__LCD_D0 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D01__LCD_D1 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D02__LCD_D2 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D03__LCD_D3 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D04__LCD_D4 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D05__LCD_D5 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D06__LCD_D6 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D07__LCD_D7 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D08__LCD_D8 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D09__LCD_D9 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D10__LCD_D10 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D11__LCD_D11 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D12__LCD_D12 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D13__LCD_D13 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D14__LCD_D14 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D15__LCD_D15 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D16__LCD_D16 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D17__LCD_D17 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D18__LCD_D18 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D19__LCD_D19 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D20__LCD_D20 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D21__LCD_D21 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_D22__LCD_D22 | MUX_CONFIG_LCD,
++/* MX28_PAD_LCD_D23__LCD_D23 | MUX_CONFIG_LCD,*/
++ MX28_PAD_LCD_RD_E__LCD_VSYNC | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_WR_RWN__LCD_HSYNC | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_RS__LCD_DOTCLK | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_CS__LCD_CS | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_VSYNC__LCD_VSYNC | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_HSYNC__LCD_HSYNC | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_DOTCLK__LCD_DOTCLK | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_ENABLE__GPIO_1_31 | MUX_CONFIG_LCD,
++ MX28_PAD_LCD_RESET__GPIO_3_30 | MUX_CONFIG_LCD,
++
++ /* UART1 */
++ MX28_PAD_PWM0__DUART_RX,
++ MX28_PAD_PWM1__DUART_TX,
++ MX28_PAD_AUART0_TX__DUART_RTS,
++ MX28_PAD_AUART0_RX__DUART_CTS,
++
++ /* UART2 */
++ MX28_PAD_AUART1_RX__AUART1_RX,
++ MX28_PAD_AUART1_TX__AUART1_TX,
++ MX28_PAD_AUART1_RTS__AUART1_RTS,
++ MX28_PAD_AUART1_CTS__AUART1_CTS,
++
++ /* CAN */
++ MX28_PAD_GPMI_RDY2__CAN0_TX,
++ MX28_PAD_GPMI_RDY3__CAN0_RX,
++
++ /* I2C */
++ MX28_PAD_I2C0_SCL__I2C0_SCL,
++ MX28_PAD_I2C0_SDA__I2C0_SDA,
++
++ /* TSC2007 */
++ /*MX28_PAD_SAIF0_MCLK__GPIO_3_20 | MUX_CONFIG_TSC,*/
++
++ /* MMC0 */
++ MX28_PAD_SSP0_DATA0__SSP0_D0 | MUX_CONFIG_SSP0,
++ MX28_PAD_SSP0_DATA1__SSP0_D1 | MUX_CONFIG_SSP0,
++ MX28_PAD_SSP0_DATA2__SSP0_D2 | MUX_CONFIG_SSP0,
++ MX28_PAD_SSP0_DATA3__SSP0_D3 | MUX_CONFIG_SSP0,
++ MX28_PAD_SSP0_DATA4__SSP0_D4 | MUX_CONFIG_SSP0,
++ MX28_PAD_SSP0_DATA5__SSP0_D5 | MUX_CONFIG_SSP0,
++ MX28_PAD_SSP0_DATA6__SSP0_D6 | MUX_CONFIG_SSP0,
++ MX28_PAD_SSP0_DATA7__SSP0_D7 | MUX_CONFIG_SSP0,
++ MX28_PAD_SSP0_CMD__SSP0_CMD | MUX_CONFIG_SSP0,
++ MX28_PAD_SSP0_DETECT__SSP0_CARD_DETECT |
++ (MXS_PAD_3V3 | MXS_PAD_12MA | MXS_PAD_NOPULL),
++ MX28_PAD_SSP0_SCK__SSP0_SCK |
++ (MXS_PAD_3V3 | MXS_PAD_12MA | MXS_PAD_NOPULL),
++ /*MX28_PAD_PWM3__GPIO_3_28 | MUX_CONFIG_SSP0,*/ /* Power .. FIXME */
++ /*MX28_PAD_AUART2_CTS__GPIO_3_10,*/ /* WP ... FIXME */
++
++ /* GPMI NAND */
++ MX28_PAD_GPMI_D00__GPMI_D0 | MUX_CONFIG_GPMI,
++ MX28_PAD_GPMI_D01__GPMI_D1 | MUX_CONFIG_GPMI,
++ MX28_PAD_GPMI_D02__GPMI_D2 | MUX_CONFIG_GPMI,
++ MX28_PAD_GPMI_D03__GPMI_D3 | MUX_CONFIG_GPMI,
++ MX28_PAD_GPMI_D04__GPMI_D4 | MUX_CONFIG_GPMI,
++ MX28_PAD_GPMI_D05__GPMI_D5 | MUX_CONFIG_GPMI,
++ MX28_PAD_GPMI_D06__GPMI_D6 | MUX_CONFIG_GPMI,
++ MX28_PAD_GPMI_D07__GPMI_D7 | MUX_CONFIG_GPMI,
++ MX28_PAD_GPMI_CE0N__GPMI_CE0N | MUX_CONFIG_GPMI,
++ MX28_PAD_GPMI_RDY0__GPMI_READY0 | MUX_CONFIG_GPMI,
++ MX28_PAD_GPMI_RDN__GPMI_RDN |
++ (MXS_PAD_1V8 | MXS_PAD_8MA | MXS_PAD_PULLUP),
++ MX28_PAD_GPMI_WRN__GPMI_WRN | MUX_CONFIG_GPMI,
++ MX28_PAD_GPMI_ALE__GPMI_ALE | MUX_CONFIG_GPMI,
++ MX28_PAD_GPMI_CLE__GPMI_CLE | MUX_CONFIG_GPMI,
++ MX28_PAD_GPMI_RESETN__GPMI_RESETN | MUX_CONFIG_GPMI,
++
++ /* FEC Ethernet */
++ MX28_PAD_ENET0_MDC__ENET0_MDC | MUX_CONFIG_ENET,
++ MX28_PAD_ENET0_MDIO__ENET0_MDIO | MUX_CONFIG_ENET,
++ MX28_PAD_ENET0_RX_EN__ENET0_RX_EN | MUX_CONFIG_ENET,
++ MX28_PAD_ENET0_TX_EN__ENET0_TX_EN | MUX_CONFIG_ENET,
++ MX28_PAD_ENET0_RXD0__ENET0_RXD0 | MUX_CONFIG_ENET,
++ MX28_PAD_ENET0_RXD1__ENET0_RXD1 | MUX_CONFIG_ENET,
++ MX28_PAD_ENET0_TXD0__ENET0_TXD0 | MUX_CONFIG_ENET,
++ MX28_PAD_ENET0_TXD1__ENET0_TXD1 | MUX_CONFIG_ENET,
++ MX28_PAD_ENET_CLK__CLKCTRL_ENET | MUX_CONFIG_ENET,
++
++ MX28_PAD_ENET0_COL__ENET1_TX_EN | MUX_CONFIG_ENET,
++ MX28_PAD_ENET0_CRS__ENET1_RX_EN | MUX_CONFIG_ENET,
++ MX28_PAD_ENET0_RXD2__ENET1_RXD0 | MUX_CONFIG_ENET,
++ MX28_PAD_ENET0_RXD3__ENET1_RXD1 | MUX_CONFIG_ENET,
++ MX28_PAD_ENET0_TXD2__ENET1_TXD0 | MUX_CONFIG_ENET,
++ MX28_PAD_ENET0_TXD3__ENET1_TXD1 | MUX_CONFIG_ENET,
++
++ /* I2C */
++ MX28_PAD_I2C0_SCL__I2C0_SCL,
++ MX28_PAD_I2C0_SDA__I2C0_SDA,
++
++ /* EMI */
++ MX28_PAD_EMI_D00__EMI_DATA0 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_D01__EMI_DATA1 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_D02__EMI_DATA2 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_D03__EMI_DATA3 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_D04__EMI_DATA4 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_D05__EMI_DATA5 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_D06__EMI_DATA6 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_D07__EMI_DATA7 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_D08__EMI_DATA8 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_D09__EMI_DATA9 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_D10__EMI_DATA10 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_D11__EMI_DATA11 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_D12__EMI_DATA12 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_D13__EMI_DATA13 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_D14__EMI_DATA14 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_D15__EMI_DATA15 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_ODT0__EMI_ODT0 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_DQM0__EMI_DQM0 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_ODT1__EMI_ODT1 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_DQM1__EMI_DQM1 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_DDR_OPEN_FB__EMI_DDR_OPEN_FEEDBACK | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_CLK__EMI_CLK | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_DQS0__EMI_DQS0 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_DQS1__EMI_DQS1 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_DDR_OPEN__EMI_DDR_OPEN | MUX_CONFIG_EMI,
++
++ MX28_PAD_EMI_A00__EMI_ADDR0 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_A01__EMI_ADDR1 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_A02__EMI_ADDR2 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_A03__EMI_ADDR3 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_A04__EMI_ADDR4 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_A05__EMI_ADDR5 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_A06__EMI_ADDR6 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_A07__EMI_ADDR7 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_A08__EMI_ADDR8 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_A09__EMI_ADDR9 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_A10__EMI_ADDR10 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_A11__EMI_ADDR11 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_A12__EMI_ADDR12 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_A13__EMI_ADDR13 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_A14__EMI_ADDR14 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_BA0__EMI_BA0 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_BA1__EMI_BA1 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_BA2__EMI_BA2 | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_CASN__EMI_CASN | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_RASN__EMI_RASN | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_WEN__EMI_WEN | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_CE0N__EMI_CE0N | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_CE1N__EMI_CE1N | MUX_CONFIG_EMI,
++ MX28_PAD_EMI_CKE__EMI_CKE | MUX_CONFIG_EMI,
++
++ /* SPI2 (for flash) */
++ MX28_PAD_SSP2_SCK__SSP2_SCK | MUX_CONFIG_SSP2,
++ MX28_PAD_SSP2_MOSI__SSP2_CMD | MUX_CONFIG_SSP2,
++ MX28_PAD_SSP2_MISO__SSP2_D0 | MUX_CONFIG_SSP2,
++ MX28_PAD_SSP2_SS0__SSP2_D3 |
++ (MXS_PAD_3V3 | MXS_PAD_8MA | MXS_PAD_PULLUP),
++};
++
++void board_init_ll(void)
++{
++ mxs_iomux_setup_multiple_pads(iomux_setup, ARRAY_SIZE(iomux_setup));
++ mx28_power_init();
++ mx28_mem_init();
++ mx28_power_wait_pswitch();
++}
++
++/* Support aparatus */
++inline void board_init_f(unsigned long bootflag)
++{
++ for (;;)
++ ;
++}
++
++inline void board_init_r(gd_t *id, ulong dest_addr)
++{
++ for (;;)
++ ;
++}
++
++inline int printf(const char *fmt, ...)
++{
++ return 0;
++}
++
++inline void __coloured_LED_init(void) {}
++inline void __red_LED_on(void) {}
++void coloured_LED_init(void)
++ __attribute__((weak, alias("__coloured_LED_init")));
++void red_LED_on(void)
++ __attribute__((weak, alias("__red_LED_on")));
++void hang(void) __attribute__ ((noreturn));
++void hang(void)
++{
++ for (;;)
++ ;
++}
+--- u-boot-orig/board/armadeus/apf28/power_init.c 1970-01-01 01:00:00.000000000 +0100
++++ u-boot-custom/board/armadeus/apf28/power_init.c 2011-11-27 11:31:22.299138403 +0100
+@@ -0,0 +1,913 @@
++/*
++ * Freescale i.MX28 Boot PMIC init
++ *
++ * Copyright (C) 2011 Marek Vasut <mar...@gm...>
++ * 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 "m28_init.h"
++
++void mx28_power_clock2xtal(void)
++{
++ struct mx28_clkctrl_regs *clkctrl_regs =
++ (struct mx28_clkctrl_regs *)MXS_CLKCTRL_BASE;
++
++ /* Set XTAL as CPU reference clock */
++ writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
++ &clkctrl_regs->hw_clkctrl_clkseq_set);
++}
++
++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);
++ early_delay(100);
++ writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
++ &clkctrl_regs->hw_clkctrl_clkseq_clr);
++}
++
++void mx28_power_clear_auto_restart(void)
++{
++ struct mx28_rtc_regs *rtc_regs =
++ (struct mx28_rtc_regs *)MXS_RTC_BASE;
++
++ writel(RTC_CTRL_SFTRST, &rtc_regs->hw_rtc_ctrl_clr);
++ while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_SFTRST)
++ ;
++
++ writel(RTC_CTRL_CLKGATE, &rtc_regs->hw_rtc_ctrl_clr);
++ while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE)
++ ;
++
++ /*
++ * Due to the hardware design bug of mx28 EVK-A
++ * we need to set the AUTO_RESTART bit.
++ */
++ if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART)
++ return;
++
++ while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
++ ;
++
++ setbits_le32(&rtc_regs->hw_rtc_persistent0,
++ RTC_PERSISTENT0_AUTO_RESTART);
++ writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_set);
++ writel(RTC_CTRL_FORCE_UPDATE, &rtc_regs->hw_rtc_ctrl_clr);
++ while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_NEW_REGS_MASK)
++ ;
++ while (readl(&rtc_regs->hw_rtc_stat) & RTC_STAT_STALE_REGS_MASK)
++ ;
++}
++
++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,
++ POWER_VDDDCTRL_LINREG_OFFSET_1STEPS_BELOW);
++
++ clrsetbits_le32(&power_regs->hw_power_vddactrl,
++ POWER_VDDACTRL_LINREG_OFFSET_MASK,
++ POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW);
++
++ clrsetbits_le32(&power_regs->hw_power_vddioctrl,
++ POWER_VDDIOCTRL_LINREG_OFFSET_MASK,
++ POWER_VDDIOCTRL_LINREG_OFFSET_1STEPS_BELOW);
++}
++
++void mx28_power_setup_5v_detect(void)
++{
++ struct mx28_power_regs *power_regs =
++ (struct mx28_power_regs *)MXS_POWER_BASE;
++
++ /* Start 5V detection */
++ clrsetbits_le32(&power_regs->hw_power_5vctrl,
++ POWER_5VCTRL_VBUSVALID_TRSH_MASK,
++ POWER_5VCTRL_VBUSVALID_TRSH_4V4 |
++ POWER_5VCTRL_PWRUP_VBUS_CMPS);
++}
++
++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);
++
++ clrsetbits_le32(&power_regs->hw_power_dclimits,
++ POWER_DCLIMITS_POSLIMIT_BUCK_MASK,
++ 0x30 << POWER_DCLIMITS_POSLIMIT_BUCK_OFFSET);
++
++ setbits_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,
++ POWER_LOOPCTRL_EN_RCSCALE_MASK,
++ POWER_LOOPCTRL_RCSCALE_THRESH |
++ POWER_LOOPCTRL_EN_RCSCALE_8X);
++
++ 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);
++}
++
++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,
++ POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET));
++
++ clrsetbits_le32(&power_regs->hw_power_5vctrl,
++ POWER_5VCTRL_HEADROOM_ADJ_MASK,
++ 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET);
++
++ clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
++ POWER_DCDC4P2_DROPOUT_CTRL_MASK,
++ POWER_DCDC4P2_DROPOUT_CTRL_100MV |
++ POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL);
++
++ clrsetbits_le32(&power_regs->hw_power_5vctrl,
++ POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
++ 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
++}
++
++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;
++
++ prev_5v_brnout = readl(&power_regs->hw_power_5vctrl) &
++ POWER_5VCTRL_PWDN_5VBRNOUT;
++ prev_5v_droop = readl(&power_regs->hw_power_ctrl) &
++ POWER_CTRL_ENIRQ_VDD5V_DROOP;
++
++ clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_PWDN_5VBRNOUT);
++ writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
++ &power_regs->hw_power_reset);
++
++ clrbits_le32(&power_regs->hw_power_ctrl, POWER_CTRL_ENIRQ_VDD5V_DROOP);
++
++ if (xfer && (readl(&power_regs->hw_power_5vctrl) &
++ POWER_5VCTRL_ENABLE_DCDC)) {
++ return;
++ }
++
++ /*
++ * Recording orignal values that will be modified temporarlily
++ * to handle a chip bug. See chip errata for CQ ENGR00115837
++ */
++ tmp = readl(&power_regs->hw_power_5vctrl);
++ vbus_thresh = tmp & POWER_5VCTRL_VBUSVALID_TRSH_MASK;
++ vbus_5vdetect = tmp & POWER_5VCTRL_VBUSVALID_5VDETECT;
++
++ pwd_bo = readl(&power_regs->hw_power_minpwr) & POWER_MINPWR_PWD_BO;
++
++ /*
++ * Disable mechanisms that get erroneously tripped by when setting
++ * the DCDC4P2 EN_DCDC
++ */
++ clrbits_le32(&power_regs->hw_power_5vctrl,
++ POWER_5VCTRL_VBUSVALID_5VDETECT |
++ POWER_5VCTRL_VBUSVALID_TRSH_MASK);
++
++ writel(POWER_MINPWR_PWD_BO, &power_regs->hw_power_minpwr_set);
++
++ if (xfer) {
++ setbits_le32(&power_regs->hw_power_5vctrl,
++ POWER_5VCTRL_DCDC_XFER);
++ early_delay(20);
++ clrbits_le32(&power_regs->hw_power_5vctrl,
++ POWER_5VCTRL_DCDC_XFER);
++
++ setbits_le32(&power_regs->hw_power_5vctrl,
++ POWER_5VCTRL_ENABLE_DCDC);
++ } else {
++ setbits_le32(&power_regs->hw_power_dcdc4p2,
++ POWER_DCDC4P2_ENABLE_DCDC);
++ }
++
++ early_delay(25);
++
++ clrsetbits_le32(&power_regs->hw_power_5vctrl,
++ POWER_5VCTRL_VBUSVALID_TRSH_MASK, vbus_thresh);
++
++ if (vbus_5vdetect)
++ writel(vbus_5vdetect, &power_regs->hw_power_5vctrl_set);
++
++ if (!pwd_bo)
++ clrbits_le32(&power_regs->hw_power_minpwr, POWER_MINPWR_PWD_BO);
++
++ while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ)
++ clrbits_le32(&power_regs->hw_power_ctrl,
++ POWER_CTRL_VBUS_VALID_IRQ);
++
++ if (prev_5v_brnout) {
++ writel(POWER_5VCTRL_PWDN_5VBRNOUT,
++ &power_regs->hw_power_5vctrl_set);
++ writel(POWER_RESET_UNLOCK_KEY,
++ &power_regs->hw_power_reset);
++ } else {
++ writel(POWER_5VCTRL_PWDN_5VBRNOUT,
++ &power_regs->hw_power_5vctrl_clr);
++ writel(POWER_RESET_UNLOCK_KEY | POWER_RESET_PWD_OFF,
++ &power_regs->hw_power_reset);
++ }
++
++ while (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VDD5V_DROOP_IRQ)
++ clrbits_le32(&power_regs->hw_power_ctrl,
++ POWER_CTRL_VDD5V_DROOP_IRQ);
++
++ if (prev_5v_droop)
++ clrbits_le32(&power_regs->hw_power_ctrl,
++ POWER_CTRL_ENIRQ_VDD5V_DROOP);
++ else
++ setbits_le32(&power_regs->hw_power_ctrl,
++ POWER_CTRL_ENIRQ_VDD5V_DROOP);
++}
++
++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);
++
++ writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set);
++
++ writel(POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK,
++ &power_regs->hw_power_5vctrl_clr);
++ clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_TRG_MASK);
++
++ /* Power up the 4p2 rail and logic/control */
++ writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
++ &power_regs->hw_power_5vctrl_clr);
++
++ /*
++ * Start charging up the 4p2 capacitor. We ramp of this charge
++ * gradually to avoid large inrush current from the 5V cable which can
++ * cause transients/problems
++ */
++ mx28_enable_4p2_dcdc_input(0);
++
++ if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
++ /*
++ * If we arrived here, we were unable to recover from mx23 chip
++ * errata 5837. 4P2 is disabled and sufficient battery power is
++ * not present. Exiting to not enable DCDC power during 5V
++ * connected state.
++ */
++ clrbits_le32(&power_regs->hw_power_dcdc4p2,
++ POWER_DCDC4P2_ENABLE_DCDC);
++ writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
++ &power_regs->hw_power_5vctrl_set);
++ hang();
++ }
++
++ /*
++ * Here we set the 4p2 brownout level to something very close to 4.2V.
++ * We then check the brownout status. If the brownout status is false,
++ * the voltage is already close to the target voltage of 4.2V so we
++ * can go ahead and set the 4P2 current limit to our max target limit.
++ * If the brownout status is true, we need to ramp us the current limit
++ * so that we don't cause large inrush current issues. We step up the
++ * current limit until the brownout status is false or until we've
++ * reached our maximum defined 4p2 current limit.
++ */
++ clrsetbits_le32(&power_regs->hw_power_dcdc4p2,
++ POWER_DCDC4P2_BO_MASK,
++ 22 << POWER_DCDC4P2_BO_OFFSET); /* 4.15V */
++
++ if (!(readl(&power_regs->hw_power_sts) & POWER_STS_DCDC_4P2_BO)) {
++ setbits_le32(&power_regs->hw_power_5vctrl,
++ 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET);
++ } else {
++ tmp = (readl(&power_regs->hw_power_5vctrl) &
++ POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK) >>
++ POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
++ while (tmp < 0x3f) {
++ if (!(readl(&power_regs->hw_power_sts) &
++ POWER_STS_DCDC_4P2_BO)) {
++ tmp = readl(&power_regs->hw_power_5vctrl);
++ tmp |= POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
++ early_delay(100);
++ writel(tmp, &power_regs->hw_power_5vctrl);
++ break;
++ } else {
++ tmp++;
++ tmp2 = readl(&power_regs->hw_power_5vctrl);
++ tmp2 &= ~POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK;
++ tmp2 |= tmp <<
++ POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET;
++ writel(tmp2, &power_regs->hw_power_5vctrl);
++ early_delay(100);
++ }
++ }
++ }
++
++ clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK);
++ writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr);
++}
++
++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();
++ }
++
++ mx28_enable_4p2_dcdc_input(1);
++
++ if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) {
++ clrbits_le32(&power_regs->hw_power_dcdc4p2,
++ POWER_DCDC4P2_ENABLE_DCDC);
++ writel(POWER_5VCTRL_ENABLE_DCDC,
++ &power_regs->hw_power_5vctrl_clr);
++ writel(POWER_5VCTRL_PWD_CHARGE_4P2_MASK,
++ &power_regs->hw_power_5vctrl_set);
++ }
++}
++
++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;
++
++ vdddctrl = readl(&power_regs->hw_power_vdddctrl);
++ vddactrl = readl(&power_regs->hw_power_vddactrl);
++ vddioctrl = readl(&power_regs->hw_power_vddioctrl);
++
++ setbits_le32(&power_regs->hw_power_vdddctrl,
++ POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
++ POWER_VDDDCTRL_PWDN_BRNOUT);
++
++ setbits_le32(&power_regs->hw_power_vddactrl,
++ POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG |
++ POWER_VDDACTRL_PWDN_BRNOUT);
++
++ setbits_le32(&power_regs->hw_power_vddioctrl,
++ POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT);
++
++ mx28_power_init_4p2_params();
++ 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);
++
++ mx28_power_init_dcdc_4p2_source();
++
++ writel(vdddctrl, &power_regs->hw_power_vdddctrl);
++ early_delay(20);
++ writel(vddactrl, &power_regs->hw_power_vddactrl);
++ early_delay(20);
++ writel(vddioctrl, &power_regs->hw_power_vddioctrl);
++
++ /*
++ * Check if FET is enabled on either powerout and if so,
++ * disable load.
++ */
++ tmp = 0;
++ tmp |= !(readl(&power_regs->hw_power_vdddctrl) &
++ POWER_VDDDCTRL_DISABLE_FET);
++ tmp |= !(readl(&power_regs->hw_power_vddactrl) &
++ POWER_VDDACTRL_DISABLE_FET);
++ tmp |= !(readl(&power_regs->hw_power_vddioctrl) &
++ POWER_VDDIOCTRL_DISABLE_FET);
++ if (tmp)
++ writel(POWER_CHARGE_ENABLE_LOAD,
++ &power_regs->hw_power_charge_clr);
++}
++
++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
++ */
++ writel(POWER_5VCTRL_VBUSVALID_5VDETECT,
++ &power_regs->hw_power_5vctrl_set);
++
++ /* Configure polarity to check for 5V disconnection. */
++ writel(POWER_CTRL_POLARITY_VBUSVALID |
++ POWER_CTRL_POLARITY_VDD5V_GT_VDDIO,
++ &power_regs->hw_power_ctrl_clr);
++
++ writel(POWER_CTRL_VBUS_VALID_IRQ | POWER_CTRL_VDD5V_GT_VDDIO_IRQ,
++ &power_regs->hw_power_ctrl_clr);
++
++ mx28_power_enable_4p2();
++}
++
++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)
++{
++ struct mx28_power_regs *power_regs =
++ (struct mx28_power_regs *)MXS_POWER_BASE;
++ uint32_t tmp;
++
++ setbits_le32(&power_regs->hw_power_vddioctrl,
++ POWER_VDDIOCTRL_BO_OFFSET_MASK);
++
++ for (;;) {
++ tmp = readl(&power_regs->hw_power_sts);
++
++ if (tmp & POWER_STS_VDDIO_BO) {
++ mx28_powerdown();
++ break;
++ }
++
++ if (tmp & POWER_STS_VDD5V_GT_VDDIO) {
++ mx28_boot_valid_5v();
++ break;
++ } else {
++ 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);
++}
++
++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.
++ */
++ if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
++ mx28_boot_valid_5v();
++ return;
++ }
++
++ early_delay(1000);
++ if (readl(&power_regs->hw_power_sts) & POWER_STS_VDD5V_GT_VDDIO) {
++ mx28_boot_valid_5v();
++ return;
++ }
++
++ mx28_handle_5v_conflict();
++}
++
++void mx28_init_batt_bo(void)
++{
++ struct mx28_power_regs *power_regs =
++ (struct mx28_power_regs *)MXS_POWER_BASE;
++
++ /* Brownout at 3V */
++ clrsetbits_le32(&power_regs->hw_power_battmonitor,
++ POWER_BATTMONITOR_BRWNOUT_LVL_MASK,
++ 15 << 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)
++{
++ 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);
++
++ clrbits_le32(&power_regs->hw_power_vdddctrl,
++ POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG |
++ 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)
++{
++ mx28_src_power_init();
++
++ mx28_5v_boot();
++ mx28_power_clock2pll();
++
++ mx28_init_batt_bo();
++ mx28_switch_vddd_to_dcdc_source();
++}
++
++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);
++
++ setbits_le32(&power_regs->hw_power_vdddctrl,
++ POWER_VDDDCTRL_PWDN_BRNOUT);
++
++ setbits_le32(&power_regs->hw_power_vddactrl,
++ POWER_VDDACTRL_PWDN_BRNOUT);
++
++ setbits_le32(&power_regs->hw_power_vddioctrl,
++ POWER_VDDIOCTRL_PWDN_BRNOUT);
++}
++
++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) {
++ tmp = readl(&power_regs->hw_power_vddioctrl);
++ if (tmp & POWER_VDDIOCTRL_DISABLE_FET) {
++ if ((tmp & POWER_VDDIOCTRL_LINREG_OFFSET_MASK) ==
++ POWER_VDDDCTRL_LINREG_OFFSET_0STEPS) {
++ return 1;
++ }
++...
[truncated message content] |