summaryrefslogtreecommitdiff
path: root/board
diff options
context:
space:
mode:
authorMarcel Ziswiler <marcel.ziswiler@toradex.com>2013-10-24 18:20:35 +0200
committerMarcel Ziswiler <marcel.ziswiler@toradex.com>2013-10-24 22:06:17 +0200
commitea8bc0b643ba31d5b74ea3c018956b832b98dc5a (patch)
treee174b5404cb4fd19a93b1cd82cb5470aca8e7657 /board
parentac13ca97df9f8c17d1c89d425041690484ee0fdf (diff)
colibri_vf61: initial integration
Add initial Colibri VF61 support based off Timesys' implementation for Freescale's Vybrid Tower System TWR-VF65GS10: - New machine ID. - Default UART_A on SCI0. - ESDHC2 only. - 8-bit NAND. - No quad SPI. - FEC1 only. - Enabled command line editing. - PLL5 based RMII clocking (e.g. no external crystal). - UART_A, UART_B and UART_C I/O muxing. - Increase the available space for the U-Boot binary to half a megabyte by booting from gfxRAM rather than sysRAM0. - Integrate factory configuration block handling for hardware version, MAC address and serial number to be passed to Linux. - The U-Boot environment is stored in NAND flash. - Fix long standing boot hang issue introduced by Freescale's Vybrid 1.1 silicon. - Proper 256 MB Nanya DDR3 RAM timings. Tested on early Colibri VF61 prototypes V1.0b and V1.0c using SD card (mandatory for initial loading) as well as NAND boot.
Diffstat (limited to 'board')
-rw-r--r--board/toradex/colibri_vf61/Makefile41
-rw-r--r--board/toradex/colibri_vf61/colibri_vf61.c637
-rw-r--r--board/toradex/colibri_vf61/nandimage.cfg61
-rw-r--r--board/toradex/colibri_vf61/sdbootimage.cfg44
4 files changed, 783 insertions, 0 deletions
diff --git a/board/toradex/colibri_vf61/Makefile b/board/toradex/colibri_vf61/Makefile
new file mode 100644
index 0000000000..da6375c570
--- /dev/null
+++ b/board/toradex/colibri_vf61/Makefile
@@ -0,0 +1,41 @@
+#
+#
+# Copyright 2013 Toradex, Inc.
+#
+# 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
+
+COBJS := $(BOARD).o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/toradex/colibri_vf61/colibri_vf61.c b/board/toradex/colibri_vf61/colibri_vf61.c
new file mode 100644
index 0000000000..e9256759a2
--- /dev/null
+++ b/board/toradex/colibri_vf61/colibri_vf61.c
@@ -0,0 +1,637 @@
+/*
+ * Copyright 2013 Toradex, Inc.
+ *
+ * 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> /* do not change order of include file */
+
+#include <asm/arch/crm_regs.h>
+#include <asm/arch/iomux.h>
+#include <asm/arch/scsc_regs.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/vybrid-pins.h>
+#include <asm/arch/vybrid-regs.h>
+#include <asm/errno.h>
+#include <asm/fec.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <fsl_esdhc.h>
+#include <i2c.h>
+#include <malloc.h>
+#include <mmc.h>
+#include <nand.h>
+#include <usb/ehci-fsl.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if defined(CONFIG_BOARD_LATE_INIT) && (defined(CONFIG_TRDX_CFG_BLOCK) || \
+ defined(CONFIG_REVISION_TAG) || defined(CONFIG_SERIAL_TAG))
+static unsigned char *config_block = NULL;
+#endif
+
+#ifdef CONFIG_FSL_ESDHC
+struct fsl_esdhc_cfg esdhc_cfg[] = {
+ {CONFIG_SYS_ESDHC1_BASE, 1},
+};
+#endif /* CONFIG_FSL_ESDHC */
+
+void ddr_phy_init(void);
+void setup_iomux_ddr(void);
+void setup_iomux_nfc(void);
+void setup_iomux_uart(void);
+
+int board_early_init_f(void)
+{
+ setup_iomux_uart();
+
+#ifdef CONFIG_NAND_FSL_NFC
+ setup_iomux_nfc();
+#endif
+
+ return 0;
+}
+
+int board_init(void)
+{
+ u32 temp;
+ struct vybrid_scsc_reg *scsc = (struct vybrid_scsc_reg *)SCSCM_BASE_ADDR;
+
+ /* address of boot parameters */
+ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+
+ /*
+ * Enable external 32K Oscillator
+ *
+ * The internal clock experiences significant drift
+ * so we must use the external oscillator in order
+ * to maintain correct time in the hwclock
+ */
+ temp = __raw_readl(&scsc->sosc_ctr);
+ temp |= VYBRID_SCSC_SICR_CTR_SOSC_EN;
+ __raw_writel(temp, &scsc->sosc_ctr);
+
+ return 0;
+}
+
+#ifdef CONFIG_BOARD_LATE_INIT
+int board_late_init(void)
+{
+ char env_str[256];
+
+ int i;
+
+ char *addr_str, *end;
+ unsigned char bi_enetaddr[6] = {0, 0, 0, 0, 0, 0}; /* Ethernet address */
+ unsigned char *mac_addr;
+ unsigned char mac_addr00[6] = {0, 0, 0, 0, 0, 0};
+
+ size_t size = 4096;
+ unsigned char toradex_oui[3] = { 0x00, 0x14, 0x2d };
+ int valid = 0;
+
+ int ret;
+
+ /* Allocate RAM area for config block */
+ config_block = malloc(size);
+ if (!config_block) {
+ printf("Not enough malloc space available!\n");
+ return -1;
+ }
+
+ /* Clear it */
+ memset((void *)config_block, 0, size);
+
+ /* Read production parameter config block from NAND */
+ ret = nand_read_skip_bad(&nand_info[0], CONFIG_TRDX_CFG_BLOCK_OFFSET, &size,
+ (unsigned char *)config_block);
+
+ /* Check validity */
+ if ((ret == 0) && (size > 0)) {
+ mac_addr = config_block + 8;
+ if (!(memcmp(mac_addr, toradex_oui, 3))) {
+ valid = 1;
+ }
+ }
+
+ if (!valid) {
+ printf("Missing Colibri config block\n");
+ memset((void *)config_block, 0, size);
+ } else {
+ /* Get MAC address from environment */
+ if ((addr_str = getenv("ethaddr")) != NULL) {
+ for (i = 0; i < 6; i++) {
+ bi_enetaddr[i] = addr_str ? simple_strtoul(addr_str, &end, 16) : 0;
+ if (addr_str) {
+ addr_str = (*end) ? end + 1 : end;
+ }
+ }
+ }
+
+ /* Set Ethernet MAC address from config block if not already set */
+ if (memcmp(mac_addr00, bi_enetaddr, 6) == 0) {
+ sprintf(env_str, "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac_addr[0], mac_addr[1], mac_addr[2],
+ mac_addr[3], mac_addr[4], mac_addr[5]);
+ setenv("ethaddr", env_str);
+#ifndef CONFIG_ENV_IS_NOWHERE
+ saveenv();
+#endif
+ }
+ }
+
+#ifdef CONFIG_MXC_SPI
+ setup_iomux_spi();
+#endif
+
+ return 0;
+}
+#endif /* CONFIG_BOARD_LATE_INIT */
+
+#ifdef CONFIG_FSL_ESDHC
+int board_mmc_getcd(struct mmc *mmc)
+{
+ /*struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;*/
+ int ret;
+
+ __raw_writel(0x005031ef, IOMUXC_PAD_014); /* clk */
+ __raw_writel(0x005031ef, IOMUXC_PAD_015); /* cmd */
+ __raw_writel(0x005031ef, IOMUXC_PAD_016); /* dat0 */
+ __raw_writel(0x005031ef, IOMUXC_PAD_017); /* dat1 */
+ __raw_writel(0x005031ef, IOMUXC_PAD_018); /* dat2 */
+ __raw_writel(0x005031ef, IOMUXC_PAD_019); /* dat3 */
+
+ ret = 1;
+ return ret;
+}
+
+int board_mmc_init(bd_t *bis)
+{
+ u32 index = 0;
+ s32 status = 0;
+
+ status |= fsl_esdhc_initialize(bis, &esdhc_cfg[index]);
+ return status;
+}
+#endif /* CONFIG_FSL_ESDHC */
+
+int checkboard(void)
+{
+ puts("Board: Colibri VF61\n");
+
+ return 0;
+}
+
+unsigned long ddr_ctrl_init(void)
+{
+ int dram_size, rows, cols, banks, port;
+
+ __raw_writel(0x00000600, DDR_CR000); /* DDR3 */
+ __raw_writel(0x00000020, DDR_CR002); /* TINIT */
+ __raw_writel(0x0000007c, DDR_CR010); /* reset during power on */
+ /* warm boot - 200ns */
+ __raw_writel(0x00013880, DDR_CR011); /* 500us - 10ns */
+ __raw_writel(0x0000050c, DDR_CR012); /* CASLAT_LIN, WRLAT */
+ __raw_writel(0x15040404, DDR_CR013); /* trc, trrd, tccd
+ tbst_int_interval */
+ __raw_writel(0x1406040F, DDR_CR014); /* tfaw, tfp, twtr, tras_min */
+ __raw_writel(0x04040000, DDR_CR016); /* tmrd, trtp */
+ __raw_writel(0x006DB00C, DDR_CR017); /* tras_max, tmod */
+ __raw_writel(0x00000403, DDR_CR018); /* tckesr, tcke */
+
+ __raw_writel(0x01000403, DDR_CR020); /* ap, writrp */
+ __raw_writel(0x00060101, DDR_CR021); /* trcd_int, tras_lockout
+ ccAP */
+ __raw_writel(0x000B0000, DDR_CR022); /* tdal */
+ __raw_writel(0x03000200, DDR_CR023); /* bstlen, tmrr, tdll */
+ __raw_writel(0x00000006, DDR_CR024); /* addr_mirror, reg_dimm
+ trp_ab */
+ __raw_writel(0x00010000, DDR_CR025); /* tref_enable, auto_refresh
+ arefresh */
+ __raw_writel(0x0C280040, DDR_CR026); /* tref, trfc */
+ __raw_writel(0x00000005, DDR_CR028); /* tref_interval fixed at 5 */
+ __raw_writel(0x00000003, DDR_CR029); /* tpdex */
+
+ __raw_writel(0x0000000A, DDR_CR030); /* txpdll */
+ __raw_writel(0x00440200, DDR_CR031); /* txsnr, txsr */
+ __raw_writel(0x00010000, DDR_CR033); /* cke_dly, en_quick_srefresh
+ * srefresh_exit_no_refresh,
+ * pwr, srefresh_exit
+ */
+ __raw_writel(0x00050500, DDR_CR034); /* cksrx, */
+ /* cksre, lowpwr_ref_en */
+
+ /* Frequency change */
+ __raw_writel(0x00000100, DDR_CR038); /* freq change... */
+ __raw_writel(0x04001002, DDR_CR039);
+
+ __raw_writel(0x00000001, DDR_CR041); /* dfi_init_start */
+ __raw_writel(0x00000000, DDR_CR045); /* wrmd */
+ __raw_writel(0x00000000, DDR_CR046); /* rdmd */
+ __raw_writel(0x00000000, DDR_CR047); /* REF_PER_AUTO_TEMPCHK:
+ * LPDDR2 set to 2, else 0
+ */
+
+ /* DRAM device Mode registers */
+ __raw_writel(0x00460420, DDR_CR048); /* mr0, ddr3 burst of 8 only
+ * mr1, if freq < 125
+ * dll_dis = 1, rtt = 0
+ * if freq > 125, dll_dis = 0
+ * rtt = 3
+ */
+ __raw_writel(0x00000000, DDR_CR049); /* mr2 */
+ __raw_writel(0x00000000, DDR_CR051); /* mr3 & mrsingle_data_0 */
+ __raw_writel(0x00000000, DDR_CR052);
+
+ __raw_writel(0x00000000, DDR_CR057); /* ctrl_raw */
+
+ /* ECC */
+ __raw_writel(0x00000000, DDR_CR058);
+
+ /* ZQ stuff */
+ __raw_writel(0x01000200, DDR_CR066); /* zqcl, zqinit */
+ __raw_writel(0x02000040, DDR_CR067); /* zqcs */
+ __raw_writel(0x00000200, DDR_CR069); /* zq_on_sref_exit, zq_req */
+
+ __raw_writel(0x00000040, DDR_CR070); /* ref_per_zq */
+ __raw_writel(0x00000000, DDR_CR071); /* zqreset, ddr3 set to 0 */
+ __raw_writel(0x01000000, DDR_CR072); /* zqcs_rotate, no_zq_init */
+
+ /* DRAM controller misc */
+ __raw_writel(0x0a010200, DDR_CR073); /* arebit, col_diff, row_diff
+ bank_diff */
+ __raw_writel(0x0101ffff, DDR_CR074); /* bank_split, addr_cmp_en
+ cmd/age cnt */
+ __raw_writel(0x01010101, DDR_CR075); /* rw same pg, rw same en
+ pri en, plen */
+ __raw_writel(0x03030101, DDR_CR076); /* #q_entries_act_dis
+ * (#cmdqueues
+ * dis_rw_grp_w_bnk_conflict
+ * w2r_split_en, cs_same_en */
+ __raw_writel(0x01000101, DDR_CR077); /* cs_map, inhibit_dram_cmd
+ * dis_interleave, swen */
+ __raw_writel(0x0000000C, DDR_CR078); /* qfull, lpddr2_s4, reduc
+ burst_on_fly */
+ __raw_writel(0x01000000, DDR_CR079); /* ctrlupd_req_per aref en
+ * ctrlupd_req
+ * ctrller busy
+ * in_ord_accept */
+ /* disable interrupts */
+ __raw_writel(0x1FFFFFFF, DDR_CR082);
+
+ /* ODT */
+ __raw_writel(0x01010000, DDR_CR087); /* odt: wr_map_cs0
+ * rd_map_cs0
+ * port_data_err_id */
+ __raw_writel(0x00040000, DDR_CR088); /* todtl_2cmd */
+ __raw_writel(0x00000002, DDR_CR089); /* add_odt stuff */
+
+ __raw_writel(0x00020000, DDR_CR091);
+ __raw_writel(0x00000000, DDR_CR092); /* tdqsck _min, max */
+
+ __raw_writel(0x00002819, DDR_CR096); /* wlmrd, wldqsen */
+
+ /* AXI ports */
+ __raw_writel(0x00202000, DDR_CR105);
+ __raw_writel(0x20200000, DDR_CR106);
+ __raw_writel(0x00002020, DDR_CR110);
+ __raw_writel(0x00202000, DDR_CR114);
+ __raw_writel(0x20200000, DDR_CR115);
+
+ __raw_writel(0x00000101, DDR_CR117); /* FIFO type (0-async, 1-2:1
+ * 2-1:2, 3- sync, w_pri
+ * r_pri
+ */
+ __raw_writel(0x01010000, DDR_CR118); /* w_pri, rpri, en */
+ __raw_writel(0x00000000, DDR_CR119); /* fifo_type */
+
+ __raw_writel(0x02020000, DDR_CR120);
+ __raw_writel(0x00000202, DDR_CR121);
+ __raw_writel(0x01010064, DDR_CR122);
+ __raw_writel(0x00010101, DDR_CR123);
+ __raw_writel(0x00000064, DDR_CR124);
+
+ /* TDFI */
+ __raw_writel(0x00000000, DDR_CR125);
+ __raw_writel(0x00000B00, DDR_CR126); /* PHY rdlat */
+ __raw_writel(0x00000000, DDR_CR127); /* dram ck dis */
+
+ __raw_writel(0x00000000, DDR_CR131);
+ __raw_writel(0x00000506, DDR_CR132); /* wrlat, rdlat */
+ __raw_writel(0x00020000, DDR_CR137);
+ __raw_writel(0x04070303, DDR_CR139);
+
+ __raw_writel(0x00000000, DDR_CR136); /* ??? why later */
+
+ __raw_writel(0x682C0000, DDR_CR154); /* Bit 19–18 DDR_SEL_PAD_Contr
+ DDR_SEL = 11 (DDR3 mode) */
+ __raw_writel(0x00000102, DDR_CR155); /* pad_ibe, _sel */
+ __raw_writel(0x00000006, DDR_CR158); /* twr */
+ __raw_writel(0x00000006, DDR_CR159); /* todth */
+
+ ddr_phy_init();
+ __raw_writel(0x1FFFFFFF, DDR_CR082); /* ??? */
+ __raw_writel(0x00000601, DDR_CR000); /* LPDDR2 or DDR3, start */
+
+ udelay(200);
+
+ rows = (__raw_readl(DDR_CR001) & 0x1F) -
+ ((__raw_readl(DDR_CR073) >> 8) & 3);
+ cols = ((__raw_readl(DDR_CR001) >> 8) & 0xF) -
+ ((__raw_readl(DDR_CR073) >> 16) & 7);
+ banks = 1 << (3 - (__raw_readl(DDR_CR073) & 3));
+ port = ((__raw_readl(DDR_CR078) >> 8) & 1) ? 1 : 2;
+
+ dram_size = (1 << (rows + cols)) * banks * port;
+
+ return dram_size;
+}
+
+void ddr_phy_init(void)
+{
+#define PHY_DQ_TIMING 0x00002213
+#define PHY_DQS_TIMING 0x00002615
+#define PHY_CTRL 0x00200000
+#define PHY_MASTER_CTRL 0x00000020
+#define PHY_SLAVE_CTRL 0x00002000
+
+ /* phy_dq_timing_reg freq set 0 */
+ __raw_writel(PHY_DQ_TIMING, DDR_PHY000);
+ __raw_writel(PHY_DQ_TIMING, DDR_PHY016);
+ __raw_writel(PHY_DQ_TIMING, DDR_PHY032);
+
+ /* phy_dqs_timing_reg freq set 0 */
+ __raw_writel(PHY_DQS_TIMING, DDR_PHY001);
+ __raw_writel(PHY_DQS_TIMING, DDR_PHY017);
+ __raw_writel(PHY_DQS_TIMING, DDR_PHY033);
+
+ /* phy_gate_lpbk_ctrl_reg freq set 0 */
+ __raw_writel(PHY_CTRL, DDR_PHY002); /* read delay bit21:19 */
+ __raw_writel(PHY_CTRL, DDR_PHY018); /* phase_detect_sel bit18:16 */
+ __raw_writel(PHY_CTRL, DDR_PHY034); /* bit lpbk_ctrl bit12 */
+
+ /* phy_dll_master_ctrl_reg freq set 0 */
+ __raw_writel(PHY_MASTER_CTRL, DDR_PHY003);
+ __raw_writel(PHY_MASTER_CTRL, DDR_PHY019);
+ __raw_writel(PHY_MASTER_CTRL, DDR_PHY035);
+
+ /* phy_dll_slave_ctrl_reg freq set 0 */
+ __raw_writel(PHY_SLAVE_CTRL, DDR_PHY004);
+ __raw_writel(PHY_SLAVE_CTRL, DDR_PHY020);
+ __raw_writel(PHY_SLAVE_CTRL, DDR_PHY036);
+
+ __raw_writel(0x00001105, DDR_PHY050);
+}
+
+static int do_mc_reg_dump(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ u32 addr;
+ for (addr = DDR_CR000; addr <= DDR_CR161; addr+=4) {
+ printf("DDR_CR[%d] = 0x%08x\n", (addr-DDR_CR000)/4, __raw_readl(addr));
+ }
+ for (addr = DDR_PHY000; addr <= DDR_PHY052; addr+=4) {
+ printf("DDR_PHY[%d] = 0x%08x\n", (addr-DDR_PHY000)/4, __raw_readl(addr));
+ }
+
+ return 0;
+}
+U_BOOT_CMD(
+ mcdump, 1, 1, do_mc_reg_dump,
+ "Dump MC registers",
+ ""
+);
+
+int dram_init(void)
+{
+ setup_iomux_ddr();
+ gd->ram_size = ddr_ctrl_init();
+
+ return 0;
+}
+
+#if defined(CONFIG_CMD_NET)
+int fecpin_setclear(struct eth_device *dev, int setclear)
+{
+ struct fec_info_s *info = (struct fec_info_s *)dev->priv;
+
+ /* 5.2.1 Software MUX Pad Control Register 0 (IOMUXC_PTA6) */
+ __raw_writel(0x00103191, IOMUXC_PAD_000); /* RMII_CLKOUT */
+
+ if (setclear) {
+ if (info->iobase == CONFIG_SYS_FEC1_IOBASE) {
+ __raw_writel(0x00103192, IOMUXC_PAD_054); /* MDC */
+ __raw_writel(0x00103193, IOMUXC_PAD_055); /* MDIO */
+ __raw_writel(0x00103191, IOMUXC_PAD_056); /* RxDV */
+ __raw_writel(0x00103191, IOMUXC_PAD_057); /* RxD1 */
+ __raw_writel(0x00103191, IOMUXC_PAD_058); /* RxD0 */
+ __raw_writel(0x00103191, IOMUXC_PAD_059); /* RxER */
+ __raw_writel(0x00103192, IOMUXC_PAD_060); /* TxD1 */
+ __raw_writel(0x00103192, IOMUXC_PAD_061); /* TxD0 */
+ __raw_writel(0x00103192, IOMUXC_PAD_062); /* TxEn */
+ }
+ } else {
+ if (info->iobase == CONFIG_SYS_FEC1_IOBASE) {
+ __raw_writel(0x00003192, IOMUXC_PAD_054); /* MDC */
+ __raw_writel(0x00003193, IOMUXC_PAD_055); /* MDIO */
+ __raw_writel(0x00003191, IOMUXC_PAD_056); /* RxDV */
+ __raw_writel(0x00003191, IOMUXC_PAD_057); /* RxD1 */
+ __raw_writel(0x00003191, IOMUXC_PAD_058); /* RxD0 */
+ __raw_writel(0x00003191, IOMUXC_PAD_059); /* RxER */
+ __raw_writel(0x00003192, IOMUXC_PAD_060); /* TxD1 */
+ __raw_writel(0x00003192, IOMUXC_PAD_061); /* TxD0 */
+ __raw_writel(0x00003192, IOMUXC_PAD_062); /* TxEn */
+ }
+ }
+
+ return 0;
+}
+#endif /* CONFIG_CMD_NET */
+
+#ifdef CONFIG_REVISION_TAG
+u32 get_board_rev(void)
+{
+#ifdef CONFIG_BOARD_LATE_INIT
+ int i;
+ unsigned short major = 0, minor = 0, release = 0;
+ size_t size = 4096;
+
+ if(config_block == NULL) {
+ return 0;
+ }
+
+ /* Parse revision information in config block */
+ for (i = 0; i < (size - 8); i++) {
+ if (config_block[i] == 0x02 && config_block[i+1] == 0x40 &&
+ config_block[i+2] == 0x08) {
+ break;
+ }
+ }
+
+ major = (config_block[i+3] << 8) | config_block[i+4];
+ minor = (config_block[i+5] << 8) | config_block[i+6];
+ release = (config_block[i+7] << 8) | config_block[i+8];
+
+ /* Check validity */
+ if (major)
+ return ((major & 0xff) << 8) | ((minor & 0xf) << 4) | ((release & 0xf) + 0xa);
+ else
+ return 0;
+#else
+ return 0;
+#endif /* CONFIG_BOARD_LATE_INIT */
+}
+#endif /* CONFIG_REVISION_TAG */
+
+#ifdef CONFIG_SERIAL_TAG
+void get_board_serial(struct tag_serialnr *serialnr)
+{
+#ifdef CONFIG_BOARD_LATE_INIT
+ int array[8];
+ int i;
+ unsigned int serial = 0;
+ unsigned int serial_offset = 11;
+
+ if(config_block == NULL) {
+ serialnr->low = 0;
+ serialnr->high = 0;
+ return;
+ }
+
+ /* Get MAC address from config block */
+ memcpy(&serial, config_block + serial_offset, 3);
+ serial = ntohl(serial);
+ serial >>= 8;
+
+ /* Check validity */
+ if (serial) {
+ /* Convert to Linux serial number format (hexadecimal coded decimal) */
+ i = 7;
+ while (serial) {
+ array[i--] = serial % 10;
+ serial /= 10;
+ }
+ while (i >= 0) {
+ array[i--] = 0;
+ }
+ serial = array[0];
+ for (i = 1; i < 8; i++) {
+ serial *= 16;
+ serial += array[i];
+ }
+ }
+
+ serialnr->low = serial;
+#else
+ serialnr->low = 0;
+#endif /* CONFIG_BOARD_LATE_INIT */
+ serialnr->high = 0;
+}
+#endif /* CONFIG_SERIAL_TAG */
+
+void setup_iomux_ddr(void)
+{
+#define DDR_IOMUX 0x00000140
+#define DDR_IOMUX1 0x00010140 /* Differential input mode */
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_RESET);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_A15);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_A14);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_A13);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_A12);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_A11);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_A10);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_A9);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_A8);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_A7);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_A6);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_A5);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_A4);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_A3);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_A2);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_A1);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_A0);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_BA2);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_BA1);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_BA0);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_CAS);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_CKE);
+ __raw_writel(DDR_IOMUX1, IOMUXC_DDR_CLK);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_CS);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_D15);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_D14);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_D13);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_D12);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_D11);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_D10);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_D9);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_D8);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_D7);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_D6);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_D5);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_D4);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_D3);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_D2);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_D1);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_D0);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_DQM1); /* UDM */
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_DQM0); /* LDM */
+ __raw_writel(DDR_IOMUX1, IOMUXC_DDR_DQS1); /* UDQS */
+ __raw_writel(DDR_IOMUX1, IOMUXC_DDR_DQS0); /* LDQS */
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_RAS);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_WE);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_ODT0);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_ODT1);
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_DDRBYTE1); /* ? */
+ __raw_writel(DDR_IOMUX, IOMUXC_DDR_DDRBYTE0); /* ? */
+}
+
+#ifdef CONFIG_NAND_FSL_NFC
+void setup_iomux_nfc(void)
+{
+ __raw_writel(0x002038df, IOMUXC_PAD_071);
+ __raw_writel(0x002038df, IOMUXC_PAD_072);
+ __raw_writel(0x002038df, IOMUXC_PAD_073);
+ __raw_writel(0x002038df, IOMUXC_PAD_074);
+ __raw_writel(0x002038df, IOMUXC_PAD_075);
+ __raw_writel(0x002038df, IOMUXC_PAD_076);
+ __raw_writel(0x002038df, IOMUXC_PAD_077);
+ __raw_writel(0x002038df, IOMUXC_PAD_078);
+ __raw_writel(0x005038d2, IOMUXC_PAD_094);
+ __raw_writel(0x005038d2, IOMUXC_PAD_095);
+ __raw_writel(0x006038d2, IOMUXC_PAD_097);
+ __raw_writel(0x005038dd, IOMUXC_PAD_099);
+ __raw_writel(0x006038d2, IOMUXC_PAD_100);
+ __raw_writel(0x006038d2, IOMUXC_PAD_101);
+}
+#endif /* CONFIG_NAND_FSL_NFC */
+
+#ifdef CONFIG_MXC_SPI
+void setup_iomux_spi(void)
+{
+}
+#endif /* CONFIG_MXC_SPI */
+
+void setup_iomux_uart(void)
+{
+ __raw_writel(0x002011a2, IOMUXC_PAD_026); /* UART_C_TXD: SCI1_TX */
+ __raw_writel(0x002011a1, IOMUXC_PAD_027); /* UART_C_RXD: SCI1_RX */
+ __raw_writel(0x001011a2, IOMUXC_PAD_032); /* UART_A_TXD: SCI0_TX */
+ __raw_writel(0x001011a1, IOMUXC_PAD_033); /* UART_A_RXD: SCI0_RX */
+ __raw_writel(0x001011a2, IOMUXC_PAD_079); /* UART_B_TXD: SCI2_TX */
+ __raw_writel(0x001011a1, IOMUXC_PAD_080); /* UART_B_RXD: SCI2_RX */
+}
diff --git a/board/toradex/colibri_vf61/nandimage.cfg b/board/toradex/colibri_vf61/nandimage.cfg
new file mode 100644
index 0000000000..dd093f90ac
--- /dev/null
+++ b/board/toradex/colibri_vf61/nandimage.cfg
@@ -0,0 +1,61 @@
+#
+# Copyright 2013 Toradex, Inc.
+#
+# 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. 51 Franklin Street Fifth Floor Boston,
+# MA 02110-1301 USA
+#
+# Refer docs/README.imxmage for more details about how-to configure
+# and create imximage boot image
+#
+# The syntax is taken as close as possible with the kwbimage
+
+IMAGE_VERSION 2
+
+# Boot Device : one of
+# spi, sd (the board has no nand neither onenand)
+
+BOOT_FROM nand
+
+# Device Configuration Data (DCD)
+#
+# Each entry must have the format:
+# Addr-type Address Value
+#
+# where:
+# Addr-type register length (1,2 or 4 bytes)
+# Address absolute address of the register
+# value value to be stored in the register
+
+# Hack for ROM to read past the first 4k of the NAND image.
+
+# If the FW is located at a different location in flash the
+# row address will need to be changed to the first page of
+# the new location.
+# This forces a NAND page read
+DATA 4 0x400E3F0C 0x11000100 # Row address - page 256
+DATA 4 0x400E3F20 0x3F040000
+DATA 4 0x400E3F34 0x3F040800
+DATA 4 0x400E3F38 0x60160000
+DATA 4 0x400E3F04 0x007EE001
+
+# This forces a NAND page read
+DATA 4 0x400E3F0C 0x11000100 # Row address - page 256
+DATA 4 0x400E3F20 0x3F040000
+DATA 4 0x400E3F34 0x3F040800
+DATA 4 0x400E3F38 0x60160000
+DATA 4 0x400E3F04 0x007EE001
diff --git a/board/toradex/colibri_vf61/sdbootimage.cfg b/board/toradex/colibri_vf61/sdbootimage.cfg
new file mode 100644
index 0000000000..85e5869806
--- /dev/null
+++ b/board/toradex/colibri_vf61/sdbootimage.cfg
@@ -0,0 +1,44 @@
+#
+# Copyright 2013 Toradex, Inc.
+#
+# 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. 51 Franklin Street Fifth Floor Boston,
+# MA 02110-1301 USA
+#
+# Refer docs/README.imxmage for more details about how-to configure
+# and create imximage boot image
+#
+# The syntax is taken as close as possible with the kwbimage
+
+IMAGE_VERSION 2
+
+# Boot Device : one of
+# spi, sd (the board has no nand neither onenand)
+
+BOOT_FROM sd
+
+# Device Configuration Data (DCD)
+#
+# Each entry must have the format:
+# Addr-type Address Value
+#
+# where:
+# Addr-type register length (1,2 or 4 bytes)
+# Address absolute address of the register
+# value value to be stored in the register
+
+# Setting IOMUXC