]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'master' of git://www.denx.de/git/u-boot-ppc4xx
authorTom Rini <trini@ti.com>
Mon, 9 Sep 2013 13:59:30 +0000 (09:59 -0400)
committerTom Rini <trini@ti.com>
Mon, 9 Sep 2013 13:59:30 +0000 (09:59 -0400)
127 files changed:
MAINTAINERS
arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg [new file with mode: 0644]
arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg [new file with mode: 0644]
arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
arch/arm/cpu/armv7/at91/sama5d3_devices.c
arch/arm/cpu/armv7/mx6/Makefile
arch/arm/cpu/armv7/mx6/hab.c [new file with mode: 0644]
arch/arm/cpu/armv7/mx6/soc.c
arch/arm/cpu/armv7/omap3/clock.c
arch/arm/cpu/armv7/omap3/lowlevel_init.S
arch/arm/cpu/armv7/omap4/hw_data.c
arch/arm/cpu/armv7/omap4/hwinit.c
arch/arm/cpu/armv7/omap4/sdram_elpida.c
arch/arm/cpu/armv7/socfpga/Makefile
arch/arm/cpu/armv7/socfpga/misc.c
arch/arm/cpu/armv7/socfpga/reset_manager.c [new file with mode: 0644]
arch/arm/cpu/armv7/zynq/Makefile
arch/arm/cpu/armv7/zynq/ddrc.c [new file with mode: 0644]
arch/arm/cpu/armv7/zynq/slcr.c
arch/arm/cpu/u-boot.lds
arch/arm/include/asm/arch-am33xx/cpu.h
arch/arm/include/asm/arch-am33xx/hardware_am33xx.h
arch/arm/include/asm/arch-am33xx/omap.h
arch/arm/include/asm/arch-at91/at91_common.h
arch/arm/include/asm/arch-at91/at91sam9x5.h
arch/arm/include/asm/arch-at91/sama5d3.h
arch/arm/include/asm/arch-at91/sama5d3_smc.h
arch/arm/include/asm/arch-mx6/hab.h [new file with mode: 0644]
arch/arm/include/asm/arch-mx6/imx-regs.h
arch/arm/include/asm/arch-mx6/sys_proto.h
arch/arm/include/asm/arch-mxs/regs-uartapp.h [new file with mode: 0644]
arch/arm/include/asm/arch-omap3/clock.h
arch/arm/include/asm/arch-omap4/clock.h
arch/arm/include/asm/arch-omap4/omap.h
arch/arm/include/asm/arch-omap5/omap.h
arch/arm/include/asm/arch-socfpga/reset_manager.h
arch/arm/include/asm/arch-zynq/hardware.h
arch/arm/include/asm/arch-zynq/sys_proto.h
arch/arm/include/asm/omap_common.h
arch/powerpc/cpu/mpc85xx/speed.c
arch/powerpc/cpu/mpc85xx/u-boot-spl.lds
board/atmel/at91sam9m10g45ek/config.mk [deleted file]
board/atmel/at91sam9x5ek/config.mk [deleted file]
board/atmel/sama5d3xek/sama5d3xek.c
board/boundary/nitrogen6x/nitrogen6x.c
board/congatec/cgtqmx6eval/README
board/freescale/p1022ds/spl.c
board/isee/igep0033/board.c
board/phytec/pcm051/board.c
board/siemens/common/board.c [new file with mode: 0644]
board/siemens/common/factoryset.c [new file with mode: 0644]
board/siemens/common/factoryset.h [new file with mode: 0644]
board/siemens/dxr2/Makefile [new file with mode: 0644]
board/siemens/dxr2/board.c [new file with mode: 0644]
board/siemens/dxr2/board.h [new file with mode: 0644]
board/siemens/dxr2/mux.c [new file with mode: 0644]
board/siemens/pxm2/Makefile [new file with mode: 0644]
board/siemens/pxm2/board.c [new file with mode: 0644]
board/siemens/pxm2/board.h [new file with mode: 0644]
board/siemens/pxm2/mux.c [new file with mode: 0644]
board/siemens/pxm2/pmic.h [new file with mode: 0644]
board/siemens/rut/Makefile [new file with mode: 0644]
board/siemens/rut/board.c [new file with mode: 0644]
board/siemens/rut/board.h [new file with mode: 0644]
board/siemens/rut/mux.c [new file with mode: 0644]
board/ti/am335x/README
board/ti/am335x/board.c
board/ti/sdp4430/sdp.c
board/xilinx/zynq/board.c
boards.cfg
common/image.c
config.mk
doc/README.SPL
doc/README.atmel_pmecc
doc/README.imximage
doc/README.mxc_hab [new file with mode: 0644]
doc/README.mxsimage [new file with mode: 0644]
drivers/gpio/at91_gpio.c
drivers/mmc/mxsmmc.c
drivers/mtd/nand/atmel_nand.c
drivers/net/fec_mxc.c
drivers/net/macb.c
drivers/serial/Makefile
drivers/serial/mxs_auart.c [new file with mode: 0644]
drivers/serial/serial.c
drivers/usb/musb-new/linux-compat.h
drivers/video/Makefile
drivers/video/formike.c [new file with mode: 0644]
drivers/watchdog/Makefile
drivers/watchdog/omap_wdt.c [new file with mode: 0644]
include/configs/am335x_evm.h
include/configs/at91sam9m10g45ek.h
include/configs/at91sam9n12ek.h
include/configs/at91sam9x5ek.h
include/configs/dalmore.h
include/configs/dra7xx_evm.h
include/configs/dxr2.h [new file with mode: 0644]
include/configs/eb_cpux9k2.h
include/configs/igep00x0.h
include/configs/mxs.h
include/configs/omap4_sdp4430.h
include/configs/omap5_common.h
include/configs/omap5_uevm.h
include/configs/pxm2.h [new file with mode: 0644]
include/configs/rut.h [new file with mode: 0644]
include/configs/sama5d3xek.h
include/configs/siemens-am33x-common.h [new file with mode: 0644]
include/configs/socfpga_cyclone5.h
include/configs/tegra-common.h
include/configs/tegra114-common.h
include/configs/tegra20-common.h
include/configs/tegra30-common.h
include/configs/ti_am335x_common.h
include/configs/ti_armv7_common.h
include/image.h
include/linux/compat.h
include/video.h
spl/Makefile
tools/Makefile
tools/imximage.c
tools/imximage.h
tools/logos/siemens.bmp [new file with mode: 0644]
tools/mkimage.c
tools/mkimage.h
tools/mxsboot.c
tools/mxsimage.c [new file with mode: 0644]
tools/mxsimage.h [new file with mode: 0644]

index bd0f3a07637a4beed563d2ef5909f0a6e00eff1e..0807727703cf23f7928a2bed236297e25c2da5cf 100644 (file)
@@ -1094,6 +1094,11 @@ Sergey Yanovich <ynvich@gmail.com>
 
        lp8x4x          xscale/pxa
 
+Roger Meier <r.meier@siemens.com>
+       dxr2                    ARM ARMV7 (AM335x SoC)
+       pxm2                    ARM ARMV7 (AM335x SoC)
+       rut                     ARM ARMV7 (AM335x SoC)
+
 -------------------------------------------------------------------------
 
 Unknown / orphaned boards:
diff --git a/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg b/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg
new file mode 100644 (file)
index 0000000..8118767
--- /dev/null
@@ -0,0 +1,6 @@
+SECTION 0x0 BOOTABLE
+ TAG LAST
+ LOAD     0x0        spl/u-boot-spl.bin
+ CALL     0x14       0x0
+ LOAD     0x40000100 u-boot.bin
+ CALL     0x40000100 0x0
diff --git a/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg b/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg
new file mode 100644 (file)
index 0000000..ea772f0
--- /dev/null
@@ -0,0 +1,8 @@
+SECTION 0x0 BOOTABLE
+ TAG LAST
+ LOAD     0x0        spl/u-boot-spl.bin
+ LOAD IVT 0x8000     0x14
+ CALL HAB 0x8000     0x0
+ LOAD     0x40000100 u-boot.bin
+ LOAD IVT 0x8000     0x40000100
+ CALL HAB 0x8000     0x0
index e3b6cd95f9e20bcad6c9ef693608daff63375082..f3579590598332406be2cd9f7455d7a6dd8184ab 100644 (file)
@@ -36,7 +36,7 @@ static void mxs_power_clock2pll(void)
                        CLKCTRL_CLKSEQ_BYPASS_CPU);
 }
 
-static void mxs_power_clear_auto_restart(void)
+static void mxs_power_set_auto_restart(void)
 {
        struct mxs_rtc_regs *rtc_regs =
                (struct mxs_rtc_regs *)MXS_RTC_BASE;
@@ -49,10 +49,7 @@ static void mxs_power_clear_auto_restart(void)
        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.
-        */
+       /* Do nothing if flag already set */
        if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART)
                return;
 
@@ -911,7 +908,7 @@ void mxs_power_init(void)
        mxs_ungate_power();
 
        mxs_power_clock2xtal();
-       mxs_power_clear_auto_restart();
+       mxs_power_set_auto_restart();
        mxs_power_set_linreg();
        mxs_power_setup_5v_detect();
 
index 4a3fca56a1a94409abd7bf4d2e2461af271fbf82..e55e1c660255a0e5c9034a5d7a9d4ea283a4cc4b 100644 (file)
@@ -144,6 +144,30 @@ void at91_macb_hw_init(void)
        /* Enable clock */
        at91_periph_clk_enable(ATMEL_ID_EMAC);
 }
+
+void at91_gmac_hw_init(void)
+{
+       at91_set_a_periph(AT91_PIO_PORTB, 0, 0);        /* GTX0 */
+       at91_set_a_periph(AT91_PIO_PORTB, 1, 0);        /* GTX1 */
+       at91_set_a_periph(AT91_PIO_PORTB, 2, 0);        /* GTX2 */
+       at91_set_a_periph(AT91_PIO_PORTB, 3, 0);        /* GTX3 */
+       at91_set_a_periph(AT91_PIO_PORTB, 4, 0);        /* GRX0 */
+       at91_set_a_periph(AT91_PIO_PORTB, 5, 0);        /* GRX1 */
+       at91_set_a_periph(AT91_PIO_PORTB, 6, 0);        /* GRX2 */
+       at91_set_a_periph(AT91_PIO_PORTB, 7, 0);        /* GRX3 */
+       at91_set_a_periph(AT91_PIO_PORTB, 8, 0);        /* GTXCK */
+       at91_set_a_periph(AT91_PIO_PORTB, 9, 0);        /* GTXEN */
+
+       at91_set_a_periph(AT91_PIO_PORTB, 11, 0);       /* GRXCK */
+       at91_set_a_periph(AT91_PIO_PORTB, 13, 0);       /* GRXER */
+
+       at91_set_a_periph(AT91_PIO_PORTB, 16, 0);       /* GMDC */
+       at91_set_a_periph(AT91_PIO_PORTB, 17, 0);       /* GMDIO */
+       at91_set_a_periph(AT91_PIO_PORTB, 18, 0);       /* G125CK */
+
+       /* Enable clock */
+       at91_periph_clk_enable(ATMEL_ID_GMAC);
+}
 #endif
 
 #ifdef CONFIG_LCD
index c5e98582d06fa9dd1a144d9b7ebc44a01a873445..6d736174dbb09e38b50c4b9432c91dc94b6795e6 100644 (file)
@@ -11,10 +11,11 @@ include $(TOPDIR)/config.mk
 
 LIB    = $(obj)lib$(SOC).o
 
-COBJS  = soc.o clock.o
+COBJS-y        = soc.o clock.o
+COBJS-$(CONFIG_SECURE_BOOT)    += hab.o
 
-SRCS   := $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS))
+SRCS   := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
+OBJS   := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
 
 all:   $(obj).depend $(LIB)
 
diff --git a/arch/arm/cpu/armv7/mx6/hab.c b/arch/arm/cpu/armv7/mx6/hab.c
new file mode 100644 (file)
index 0000000..5187775
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hab.h>
+
+/* -------- start of HAB API updates ------------*/
+#define hab_rvt_report_event ((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT)
+#define hab_rvt_report_status ((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS)
+#define hab_rvt_authenticate_image \
+       ((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE)
+#define hab_rvt_entry ((hab_rvt_entry_t *)HAB_RVT_ENTRY)
+#define hab_rvt_exit ((hab_rvt_exit_t *)HAB_RVT_EXIT)
+#define hab_rvt_clock_init HAB_RVT_CLOCK_INIT
+
+bool is_hab_enabled(void)
+{
+       struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+       struct fuse_bank *bank = &ocotp->bank[0];
+       struct fuse_bank0_regs *fuse =
+               (struct fuse_bank0_regs *)bank->fuse_regs;
+       uint32_t reg = readl(&fuse->cfg5);
+
+       return (reg & 0x2) == 0x2;
+}
+
+void display_event(uint8_t *event_data, size_t bytes)
+{
+       uint32_t i;
+
+       if (!(event_data && bytes > 0))
+               return;
+
+       for (i = 0; i < bytes; i++) {
+               if (i == 0)
+                       printf("\t0x%02x", event_data[i]);
+               else if ((i % 8) == 0)
+                       printf("\n\t0x%02x", event_data[i]);
+               else
+                       printf(" 0x%02x", event_data[i]);
+       }
+}
+
+int get_hab_status(void)
+{
+       uint32_t index = 0; /* Loop index */
+       uint8_t event_data[128]; /* Event data buffer */
+       size_t bytes = sizeof(event_data); /* Event size in bytes */
+       enum hab_config config = 0;
+       enum hab_state state = 0;
+
+       if (is_hab_enabled())
+               puts("\nSecure boot enabled\n");
+       else
+               puts("\nSecure boot disabled\n");
+
+       /* Check HAB status */
+       if (hab_rvt_report_status(&config, &state) != HAB_SUCCESS) {
+               printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
+                      config, state);
+
+               /* Display HAB Error events */
+               while (hab_rvt_report_event(HAB_FAILURE, index, event_data,
+                                       &bytes) == HAB_SUCCESS) {
+                       puts("\n");
+                       printf("--------- HAB Event %d -----------------\n",
+                              index + 1);
+                       puts("event data:\n");
+                       display_event(event_data, bytes);
+                       puts("\n");
+                       bytes = sizeof(event_data);
+                       index++;
+               }
+       }
+       /* Display message if no HAB events are found */
+       else {
+               printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
+                      config, state);
+               puts("No HAB Events Found!\n\n");
+       }
+       return 0;
+}
+
+int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       if ((argc != 1)) {
+               cmd_usage(cmdtp);
+               return 1;
+       }
+
+       get_hab_status();
+
+       return 0;
+}
+
+U_BOOT_CMD(
+               hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
+               "display HAB status",
+               ""
+         );
index 8150bffb8ce60b5c1947f65e5554598b24316f6d..a3902962b5249c4ebf9ef66df991d42b69e007f8 100644 (file)
@@ -213,6 +213,34 @@ const struct boot_mode soc_boot_modes[] = {
 
 void s_init(void)
 {
+       struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
+       int is_6q = is_cpu_type(MXC_CPU_MX6Q);
+       u32 mask480;
+       u32 mask528;
+
+       /* Due to hardware limitation, on MX6Q we need to gate/ungate all PFDs
+        * to make sure PFD is working right, otherwise, PFDs may
+        * not output clock after reset, MX6DL and MX6SL have added 396M pfd
+        * workaround in ROM code, as bus clock need it
+        */
+
+       mask480 = ANATOP_PFD_CLKGATE_MASK(0) |
+               ANATOP_PFD_CLKGATE_MASK(1) |
+               ANATOP_PFD_CLKGATE_MASK(2) |
+               ANATOP_PFD_CLKGATE_MASK(3);
+       mask528 = ANATOP_PFD_CLKGATE_MASK(0) |
+               ANATOP_PFD_CLKGATE_MASK(1) |
+               ANATOP_PFD_CLKGATE_MASK(3);
+
+       /*
+        * Don't reset PFD2 on DL/S
+        */
+       if (is_6q)
+               mask528 |= ANATOP_PFD_CLKGATE_MASK(2);
+       writel(mask480, &anatop->pfd_480_set);
+       writel(mask528, &anatop->pfd_528_set);
+       writel(mask480, &anatop->pfd_480_clr);
+       writel(mask528, &anatop->pfd_528_clr);
 }
 
 #ifdef CONFIG_IMX_HDMI
index e903ed9ac492f6967475b8a9a2b39602eae33e90..9f989ff860e7f6e63acf9236fce81a7174c7bfcc 100644 (file)
@@ -183,8 +183,7 @@ static void dpll3_init_34xx(u32 sil_index, u32 clk_index)
                 * if running from flash, jump to small relocated code
                 * area in SRAM.
                 */
-               f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start +
-                               SRAM_VECT_CODE);
+               f_lock_pll = (void *) (SRAM_CLK_CODE);
 
                p0 = readl(&prcm_base->clken_pll);
                sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
@@ -401,8 +400,7 @@ static void dpll3_init_36xx(u32 sil_index, u32 clk_index)
                 * if running from flash, jump to small relocated code
                 * area in SRAM.
                 */
-               f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start +
-                               SRAM_VECT_CODE);
+               f_lock_pll = (void *) (SRAM_CLK_CODE);
 
                p0 = readl(&prcm_base->clken_pll);
                sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
index 98c3c03a0eb16e6f8fac2d23aa2246d4c5e13288..6f7261b7b8ead7c91d760d039ba0f33584e31544 100644 (file)
@@ -69,15 +69,13 @@ ENDPROC(do_omap3_emu_romcode_call)
  *************************************************************************/
 ENTRY(cpy_clk_code)
        /* Copy DPLL code into SRAM */
-       adr     r0, go_to_speed         /* get addr of clock setting code */
-       mov     r2, #384                /* r2 size to copy (div by 32 bytes) */
-       mov     r1, r1                  /* r1 <- dest address (passed in) */
-       add     r2, r2, r0              /* r2 <- source end address */
+       adr     r0, go_to_speed         /* copy from start of go_to_speed... */
+       adr     r2, lowlevel_init       /* ... up to start of low_level_init */
 next2:
        ldmia   r0!, {r3 - r10}         /* copy from source address [r0] */
        stmia   r1!, {r3 - r10}         /* copy to   target address [r1] */
        cmp     r0, r2                  /* until source end address [r2] */
-       bne     next2
+       blo     next2
        mov     pc, lr                  /* back to caller */
 ENDPROC(cpy_clk_code)
 
index 310df5a6e226cf12575b89ba5f9501cd8569d5a2..6a225c8cb268eb59f3651165af28bc6e26f5abfd 100644 (file)
@@ -50,6 +50,7 @@ static const struct dpll_params mpu_dpll_params_1400mhz[NUM_SYS_CLKS] = {
 /*
  * dpll locked at 1600 MHz - MPU clk at 800 MHz(OPP Turbo 4430)
  * OMAP4430 OPP_TURBO frequency
+ * OMAP4470 OPP_NOM frequency
  */
 static const struct dpll_params mpu_dpll_params_1600mhz[NUM_SYS_CLKS] = {
        {200, 2, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1},        /* 12 MHz   */
@@ -76,6 +77,7 @@ static const struct dpll_params mpu_dpll_params_1200mhz[NUM_SYS_CLKS] = {
 };
 
 /* OMAP4460 OPP_NOM frequency */
+/* OMAP4470 OPP_NOM (Low Power) frequency */
 static const struct dpll_params core_dpll_params_1600mhz[NUM_SYS_CLKS] = {
        {200, 2, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1},     /* 12 MHz   */
        {800, 12, 1, 5, 8, 4, 6, 5, -1, -1, -1, -1},    /* 13 MHz   */
@@ -198,6 +200,20 @@ struct dplls omap4460_dplls = {
        .ddr = NULL
 };
 
+struct dplls omap4470_dplls = {
+       .mpu = mpu_dpll_params_1600mhz,
+       .core = core_dpll_params_1600mhz,
+       .per = per_dpll_params_1536mhz,
+       .iva = iva_dpll_params_1862mhz,
+#ifdef CONFIG_SYS_OMAP_ABE_SYSCK
+       .abe = abe_dpll_params_sysclk_196608khz,
+#else
+       .abe = &abe_dpll_params_32k_196608khz,
+#endif
+       .usb = usb_dpll_params_1920mhz,
+       .ddr = NULL
+};
+
 struct pmic_data twl6030_4430es1 = {
        .base_offset = PHOENIX_SMPS_BASE_VOLT_STD_MODE_UV,
        .step = 12660, /* 12.66 mV represented in uV */
@@ -208,6 +224,7 @@ struct pmic_data twl6030_4430es1 = {
        .pmic_write     = omap_vc_bypass_send_value,
 };
 
+/* twl6030 struct is used for TWL6030 and TWL6032 PMIC */
 struct pmic_data twl6030 = {
        .base_offset = PHOENIX_SMPS_BASE_VOLT_STD_MODE_WITH_OFFSET_UV,
        .step = 12660, /* 12.66 mV represented in uV */
@@ -271,6 +288,20 @@ struct vcores_data omap4460_volts = {
        .mm.pmic = &twl6030,
 };
 
+struct vcores_data omap4470_volts = {
+       .mpu.value = 1200,
+       .mpu.addr = SMPS_REG_ADDR_SMPS1,
+       .mpu.pmic = &twl6030,
+
+       .core.value = 1126,
+       .core.addr = SMPS_REG_ADDR_SMPS1,
+       .core.pmic = &twl6030,
+
+       .mm.value = 1137,
+       .mm.addr = SMPS_REG_ADDR_SMPS1,
+       .mm.pmic = &twl6030,
+};
+
 /*
  * Enable essential clock domains, modules and
  * do some additional special settings needed
@@ -476,6 +507,11 @@ void hw_data_init(void)
        *omap_vcores = &omap4460_volts;
        break;
 
+       case OMAP4470_ES1_0:
+       *dplls_data = &omap4470_dplls;
+       *omap_vcores = &omap4470_volts;
+       break;
+
        default:
                printf("\n INVALID OMAP REVISION ");
        }
index 4da0fc0ad56913190da90a4bf64ef8ed740bba24..b0598a0774d5a0ce6a085a244e782c16439418d3 100644 (file)
@@ -138,6 +138,9 @@ void init_omap_revision(void)
                break;
        case MIDR_CORTEX_A9_R2P10:
                switch (readl(CONTROL_ID_CODE)) {
+               case OMAP4470_CONTROL_ID_CODE_ES1_0:
+                       *omap_si_rev = OMAP4470_ES1_0;
+                       break;
                case OMAP4460_CONTROL_ID_CODE_ES1_1:
                        *omap_si_rev = OMAP4460_ES1_1;
                        break;
index d76dde719a1a00523d07f7879a10393ddc0071b3..67a79261f778c6afab3d0e3870eac1e18cff8411 100644 (file)
@@ -60,6 +60,20 @@ static const struct emif_regs emif_regs_elpida_380_mhz_1cs = {
        .emif_ddr_phy_ctlr_1            = 0x049ff418
 };
 
+const struct emif_regs emif_regs_elpida_400_mhz_1cs = {
+       .sdram_config_init              = 0x80800eb2,
+       .sdram_config                   = 0x80801ab2,
+       .ref_ctrl                       = 0x00000618,
+       .sdram_tim1                     = 0x10eb0662,
+       .sdram_tim2                     = 0x20370dd2,
+       .sdram_tim3                     = 0x00b1c33f,
+       .read_idle_ctrl                 = 0x000501ff,
+       .zq_config                      = 0x500b3215,
+       .temp_alert_config              = 0x58016893,
+       .emif_ddr_phy_ctlr_1_init       = 0x049ffff5,
+       .emif_ddr_phy_ctlr_1            = 0x049ff418
+};
+
 const struct emif_regs emif_regs_elpida_400_mhz_2cs = {
        .sdram_config_init              = 0x80000eb9,
        .sdram_config                   = 0x80001ab9,
@@ -107,8 +121,10 @@ static void emif_get_reg_dump_sdp(u32 emif_nr, const struct emif_regs **regs)
                *regs = &emif_regs_elpida_380_mhz_1cs;
        else if (omap4_rev == OMAP4430_ES2_0)
                *regs = &emif_regs_elpida_200_mhz_2cs;
-       else
+       else if (omap4_rev < OMAP4470_ES1_0)
                *regs = &emif_regs_elpida_400_mhz_2cs;
+       else
+               *regs = &emif_regs_elpida_400_mhz_1cs;
 }
 void emif_get_reg_dump(u32 emif_nr, const struct emif_regs **regs)
        __attribute__((weak, alias("emif_get_reg_dump_sdp")));
@@ -138,20 +154,31 @@ static const struct lpddr2_device_details elpida_2G_S4_details = {
        .manufacturer   = LPDDR2_MANUFACTURER_ELPIDA
 };
 
+static const struct lpddr2_device_details elpida_4G_S4_details = {
+       .type           = LPDDR2_TYPE_S4,
+       .density        = LPDDR2_DENSITY_4Gb,
+       .io_width       = LPDDR2_IO_WIDTH_32,
+       .manufacturer   = LPDDR2_MANUFACTURER_ELPIDA
+};
+
 struct lpddr2_device_details *emif_get_device_details_sdp(u32 emif_nr, u8 cs,
                        struct lpddr2_device_details *lpddr2_dev_details)
 {
        u32 omap_rev = omap_revision();
 
        /* EMIF1 & EMIF2 have identical configuration */
-       if ((omap_rev == OMAP4430_ES1_0) && (cs == CS1)) {
-               /* Nothing connected on CS1 for ES1.0 */
+       if (((omap_rev == OMAP4430_ES1_0) || (omap_rev == OMAP4470_ES1_0))
+               && (cs == CS1)) {
+               /* Nothing connected on CS1 for 4430/4470 ES1.0 */
                return NULL;
-       } else {
-               /* In all other cases Elpida 2G device */
+       } else if (omap_rev < OMAP4470_ES1_0) {
+               /* In all other 4430/4460 cases Elpida 2G device */
                *lpddr2_dev_details = elpida_2G_S4_details;
-               return lpddr2_dev_details;
+       } else {
+               /* 4470: 4G device */
+               *lpddr2_dev_details = elpida_4G_S4_details;
        }
+       return lpddr2_dev_details;
 }
 
 struct lpddr2_device_details *emif_get_device_details(u32 emif_nr, u8 cs,
@@ -265,7 +292,7 @@ void emif_get_device_timings_sdp(u32 emif_nr,
        /* Identical devices on EMIF1 & EMIF2 */
        *cs0_device_timings = &elpida_2G_S4_timings;
 
-       if (omap_rev == OMAP4430_ES1_0)
+       if ((omap_rev == OMAP4430_ES1_0) || (omap_rev == OMAP4470_ES1_0))
                *cs1_device_timings = NULL;
        else
                *cs1_device_timings = &elpida_2G_S4_timings;
index 3b48ac9b2b275f9a6059a5f4e4c06bfedeb843ba..5024fc55e275d6f11e12830b3cdc5eea4b5704ef 100644 (file)
@@ -13,7 +13,7 @@ include $(TOPDIR)/config.mk
 LIB    =  $(obj)lib$(SOC).o
 
 SOBJS  := lowlevel_init.o
-COBJS-y        := misc.o timer.o
+COBJS-y        := misc.o timer.o reset_manager.o
 COBJS-$(CONFIG_SPL_BUILD) += spl.o
 
 COBJS  := $(COBJS-y)
index 66edb3c20fbba6d20c9efbae32a6446e8c21be6d..2f1c7160f1ff458bef09c2a3b7078a540d47b5e8 100644 (file)
@@ -6,36 +6,9 @@
 
 #include <common.h>
 #include <asm/io.h>
-#include <asm/arch/reset_manager.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-static const struct socfpga_reset_manager *reset_manager_base =
-               (void *)SOCFPGA_RSTMGR_ADDRESS;
-
-/*
- * Write the reset manager register to cause reset
- */
-void reset_cpu(ulong addr)
-{
-       /* request a warm reset */
-       writel(RSTMGR_CTRL_SWWARMRSTREQ_LSB, &reset_manager_base->ctrl);
-       /*
-        * infinite loop here as watchdog will trigger and reset
-        * the processor
-        */
-       while (1)
-               ;
-}
-
-/*
- * Release peripherals from reset based on handoff
- */
-void reset_deassert_peripherals_handoff(void)
-{
-       writel(0, &reset_manager_base->per_mod_reset);
-}
-
 int dram_init(void)
 {
        gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
diff --git a/arch/arm/cpu/armv7/socfpga/reset_manager.c b/arch/arm/cpu/armv7/socfpga/reset_manager.c
new file mode 100644 (file)
index 0000000..e320c01
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  Copyright (C) 2013 Altera Corporation <www.altera.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/reset_manager.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static const struct socfpga_reset_manager *reset_manager_base =
+               (void *)SOCFPGA_RSTMGR_ADDRESS;
+
+/*
+ * Write the reset manager register to cause reset
+ */
+void reset_cpu(ulong addr)
+{
+       /* request a warm reset */
+       writel((1 << RSTMGR_CTRL_SWWARMRSTREQ_LSB),
+               &reset_manager_base->ctrl);
+       /*
+        * infinite loop here as watchdog will trigger and reset
+        * the processor
+        */
+       while (1)
+               ;
+}
+
+/*
+ * Release peripherals from reset based on handoff
+ */
+void reset_deassert_peripherals_handoff(void)
+{
+       writel(0, &reset_manager_base->per_mod_reset);
+}
index e5494f748989fcf4a1820c210267ff448cab8bcd..de6b08157e9e1afe35411728d109b1840de1056c 100644 (file)
@@ -14,6 +14,7 @@ LIB   = $(obj)lib$(SOC).o
 
 COBJS-y        := timer.o
 COBJS-y        += cpu.o
+COBJS-y        += ddrc.o
 COBJS-y        += slcr.o
 
 COBJS  := $(COBJS-y)
diff --git a/arch/arm/cpu/armv7/zynq/ddrc.c b/arch/arm/cpu/armv7/zynq/ddrc.c
new file mode 100644 (file)
index 0000000..ba6a6ae
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2012 - 2013 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2012 - 2013 Xilinx, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hardware.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* Control regsiter bitfield definitions */
+#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_MASK                0xC
+#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_SHIFT       2
+#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_16BIT       1
+
+/* ECC scrub regsiter definitions */
+#define ZYNQ_DDRC_ECC_SCRUBREG_ECC_MODE_MASK   0x7
+#define ZYNQ_DDRC_ECC_SCRUBREG_ECCMODE_SECDED  0x4
+
+void zynq_ddrc_init(void)
+{
+       u32 width, ecctype;
+
+       width = readl(&ddrc_base->ddrc_ctrl);
+       width = (width & ZYNQ_DDRC_CTRLREG_BUSWIDTH_MASK) >>
+                                       ZYNQ_DDRC_CTRLREG_BUSWIDTH_SHIFT;
+       ecctype = (readl(&ddrc_base->ecc_scrub) &
+               ZYNQ_DDRC_ECC_SCRUBREG_ECC_MODE_MASK);
+
+       /* ECC is enabled when memory is in 16bit mode and it is enabled */
+       if ((ecctype == ZYNQ_DDRC_ECC_SCRUBREG_ECCMODE_SECDED) &&
+           (width == ZYNQ_DDRC_CTRLREG_BUSWIDTH_16BIT)) {
+               puts("Memory: ECC enabled\n");
+               /*
+                * Clear the first 1MB because it is not initialized from
+                * first stage bootloader. To get ECC to work all memory has
+                * been initialized by writing any value.
+                */
+               memset(0, 0, 1 * 1024 * 1024);
+       } else {
+               puts("Memory: ECC disabled\n");
+       }
+
+       if (width == ZYNQ_DDRC_CTRLREG_BUSWIDTH_16BIT)
+               gd->ram_size /= 2;
+}
index e5fe9929827cd6117ec683d1986a804f998c9f29..717ec65aeee0132a6a07f49c774192ec18f4e4f4 100644 (file)
@@ -70,7 +70,7 @@ void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk)
                /* Configure GEM_RCLK_CTRL */
                writel(rclk, &slcr_base->gem0_rclk_ctrl);
        }
-
+       udelay(100000);
 out:
        zynq_slcr_lock();
 }
index 490aed2e0d89204329d05bca14741ebc23735342..23bf0306550ac9e209f8ffec9ac538a972ce8f17 100644 (file)
@@ -97,4 +97,6 @@ SECTIONS
        /DISCARD/ : { *(.plt*) }
        /DISCARD/ : { *(.interp*) }
        /DISCARD/ : { *(.gnu*) }
+       /DISCARD/ : { *(.ARM.exidx*) }
+       /DISCARD/ : { *(.gnu.linkonce.armexidx.*) }
 }
index 10b56e0db41e0411e046c275800da1bd9e796952..73e6db89984584850f988decb9b7dc9038065d35 100644 (file)
 #define PRM_RSTCTRL_RESET              0x01
 #define PRM_RSTST_WARM_RESET_MASK      0x232
 
+/*
+ * Watchdog:
+ * Using the prescaler, the OMAP watchdog could go for many
+ * months before firing.  These limits work without scaling,
+ * with the 60 second default assumed by most tools and docs.
+ */
+#define TIMER_MARGIN_MAX       (24 * 60 * 60)  /* 1 day */
+#define TIMER_MARGIN_DEFAULT   60      /* 60 secs */
+#define TIMER_MARGIN_MIN       1
+
+#define PTV                    0       /* prescale */
+#define GET_WLDR_VAL(secs)     (0xffffffff - ((secs) * (32768/(1<<PTV))) + 1)
+#define WDT_WWPS_PEND_WCLR     BIT(0)
+#define WDT_WWPS_PEND_WLDR     BIT(2)
+#define WDT_WWPS_PEND_WTGR     BIT(3)
+#define WDT_WWPS_PEND_WSPR     BIT(4)
+
+#define WDT_WCLR_PRE           BIT(5)
+#define WDT_WCLR_PTV_OFF       2
+
 #ifndef __KERNEL_STRICT_NAMES
 #ifndef __ASSEMBLY__
 struct gpmc_cs {
@@ -193,7 +213,8 @@ struct cm_perpll {
        unsigned int dcan1clkctrl;      /* offset 0xC4 */
        unsigned int resv6[2];
        unsigned int emiffwclkctrl;     /* offset 0xD0 */
-       unsigned int resv7[2];
+       unsigned int epwmss0clkctrl;    /* offset 0xD4 */
+       unsigned int epwmss2clkctrl;    /* offset 0xD8 */
        unsigned int l3instrclkctrl;    /* offset 0xDC */
        unsigned int l3clkctrl;         /* Offset 0xE0 */
        unsigned int resv8[4];
@@ -204,6 +225,7 @@ struct cm_perpll {
        unsigned int l4hsclkctrl;       /* offset 0x120 */
        unsigned int resv10[8];
        unsigned int cpswclkstctrl;     /* offset 0x144 */
+       unsigned int lcdcclkstctrl;     /* offset 0x148 */
 };
 #else
 /* Encapsulating core pll registers */
@@ -366,6 +388,8 @@ struct cm_perpll {
 struct cm_dpll {
        unsigned int resv1[2];
        unsigned int clktimer2clk;      /* offset 0x08 */
+       unsigned int resv2[10];
+       unsigned int clklcdcpixelclk;   /* offset 0x34 */
 };
 
 /* Control Module RTC registers */
@@ -486,6 +510,54 @@ struct ctrl_dev {
        unsigned int resv4[4];
        unsigned int miisel;            /* offset 0x50 */
 };
+
+/* gmii_sel register defines */
+#define GMII1_SEL_MII          0x0
+#define GMII1_SEL_RMII         0x1
+#define GMII1_SEL_RGMII                0x2
+#define GMII2_SEL_MII          0x0
+#define GMII2_SEL_RMII         0x4
+#define GMII2_SEL_RGMII                0x8
+#define RGMII1_IDMODE          BIT(4)
+#define RGMII2_IDMODE          BIT(5)
+#define RMII1_IO_CLK_EN                BIT(6)
+#define RMII2_IO_CLK_EN                BIT(7)
+
+#define MII_MODE_ENABLE                (GMII1_SEL_MII | GMII2_SEL_MII)
+#define RMII_MODE_ENABLE        (GMII1_SEL_RMII | GMII2_SEL_RMII)
+#define RGMII_MODE_ENABLE      (GMII1_SEL_RGMII | GMII2_SEL_RGMII)
+#define RGMII_INT_DELAY                (RGMII1_IDMODE | RGMII2_IDMODE)
+#define RMII_CHIPCKL_ENABLE     (RMII1_IO_CLK_EN | RMII2_IO_CLK_EN)
+
+/* PWMSS */
+struct pwmss_regs {
+       unsigned int idver;
+       unsigned int sysconfig;
+       unsigned int clkconfig;
+       unsigned int clkstatus;
+};
+#define ECAP_CLK_EN            BIT(0)
+#define ECAP_CLK_STOP_REQ      BIT(1)
+
+struct pwmss_ecap_regs {
+       unsigned int tsctr;
+       unsigned int ctrphs;
+       unsigned int cap1;
+       unsigned int cap2;
+       unsigned int cap3;
+       unsigned int cap4;
+       unsigned int resv1[4];
+       unsigned short ecctl1;
+       unsigned short ecctl2;
+};
+
+/* Capture Control register 2 */
+#define ECTRL2_SYNCOSEL_MASK   (0x03 << 6)
+#define ECTRL2_MDSL_ECAP       BIT(9)
+#define ECTRL2_CTRSTP_FREERUN  BIT(4)
+#define ECTRL2_PLSL_LOW                BIT(10)
+#define ECTRL2_SYNC_EN         BIT(5)
+
 #endif /* __ASSEMBLY__ */
 #endif /* __KERNEL_STRICT_NAMES */
 
index 8973fd884f96ae0986f11d5ca16b39280a9f79ef..e4231c81ad907ade4c27c1ad8fea5b9377c90f60 100644 (file)
 #define USB0_OTG_BASE                  0x47401000
 #define USB1_OTG_BASE                  0x47401800
 
+/* LCD Controller */
+#define LCD_CNTL_BASE                  0x4830E000
+
+/* PWMSS */
+#define PWMSS0_BASE                    0x48300000
+#define AM33XX_ECAP0_BASE              0x48300100
+
 #endif /* __AM33XX_HARDWARE_AM33XX_H */
index 1f8431196f2d5972f8513f2191a9fdadd5305f7d..225072186dbe6ea9d735e83490b5b5aca98ef4b6 100644 (file)
@@ -18,7 +18,7 @@
 #ifdef CONFIG_AM33XX
 #define NON_SECURE_SRAM_START  0x402F0400
 #define NON_SECURE_SRAM_END    0x40310000
-#define SRAM_SCRATCH_SPACE_ADDR        0x4030C000
+#define SRAM_SCRATCH_SPACE_ADDR        0x4030B800
 #elif defined(CONFIG_TI81XX)
 #define NON_SECURE_SRAM_START  0x40300000
 #define NON_SECURE_SRAM_END    0x40320000
index d6597023c6e31b02b5e2bfcb099c8075f2965f39..9f54fddce51efe63473fbb403f51be20efffdc4e 100644 (file)
@@ -10,6 +10,7 @@
 #define AT91_COMMON_H
 
 void at91_can_hw_init(void);
+void at91_gmac_hw_init(void);
 void at91_macb_hw_init(void);
 void at91_mci_hw_init(void);
 void at91_serial0_hw_init(void);
index fcc6fdc21931f14039da99bb4f9f2689926a827d..a47103851e48594c1a19b64d4d1a1ef2303a1e89 100644 (file)
 #define ATMEL_PMC_UHP          AT91SAM926x_PMC_UHP
 #define ATMEL_ID_UHP           ATMEL_ID_UHPHS
 
+/*
+ * PMECC table in ROM
+ */
+#define ATMEL_PMECC_INDEX_OFFSET_512   0x8000
+#define ATMEL_PMECC_INDEX_OFFSET_1024  0x10000
+
 /*
  * at91sam9x5 specific prototypes
  */
index 49bd335102d3647c4158696bb1c24f1f505b0c1c..fefee5ed259e10fab04de25e5f53c66311b20fc9 100644 (file)
  */
 #define ATMEL_PMECC_INDEX_OFFSET_512   0x10000
 #define ATMEL_PMECC_INDEX_OFFSET_1024  0x18000
-#define ATMEL_PMECC_ALPHA_OFFSET_512   0x10000
-#define ATMEL_PMECC_ALPHA_OFFSET_1024  0x18000
 
 /*
  * SAMA5D3 specific prototypes
index c060894f14b371f3e5f9945e6a62b41696f7e5cc..6caa9b6ed8fdc0f3c2eab1a7f06b8e8d44ccf686 100644 (file)
@@ -17,7 +17,6 @@
 #define AT91_ASM_SMC_MODE0     (ATMEL_BASE_SMC + 0x60C)
 #else
 struct at91_cs {
-       u32     reserved[96];
        u32     setup;          /* 0x600 SMC Setup Register */
        u32     pulse;          /* 0x604 SMC Pulse Register */
        u32     cycle;          /* 0x608 SMC Cycle Register */
@@ -26,6 +25,7 @@ struct at91_cs {
 };
 
 struct at91_smc {
+       u32 reserved[384];
        struct at91_cs cs[4];
 };
 #endif /*  __ASSEMBLY__ */
diff --git a/arch/arm/include/asm/arch-mx6/hab.h b/arch/arm/include/asm/arch-mx6/hab.h
new file mode 100644 (file)
index 0000000..d724f20
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ *
+*/
+
+#ifndef __SECURE_MX6Q_H__
+#define __SECURE_MX6Q_H__
+
+#include <linux/types.h>
+
+/* -------- start of HAB API updates ------------*/
+/* The following are taken from HAB4 SIS */
+
+/* Status definitions */
+enum hab_status {
+       HAB_STS_ANY = 0x00,
+       HAB_FAILURE = 0x33,
+       HAB_WARNING = 0x69,
+       HAB_SUCCESS = 0xf0
+};
+
+/* Security Configuration definitions */
+enum hab_config {
+       HAB_CFG_RETURN = 0x33, /**< Field Return IC */
+       HAB_CFG_OPEN = 0xf0, /**< Non-secure IC */
+       HAB_CFG_CLOSED = 0xcc /**< Secure IC */
+};
+
+/* State definitions */
+enum hab_state {
+       HAB_STATE_INITIAL = 0x33, /**< Initialising state (transitory) */
+       HAB_STATE_CHECK = 0x55, /**< Check state (non-secure) */
+       HAB_STATE_NONSECURE = 0x66, /**< Non-secure state */
+       HAB_STATE_TRUSTED = 0x99, /**< Trusted state */
+       HAB_STATE_SECURE = 0xaa, /**< Secure state */
+       HAB_STATE_FAIL_SOFT = 0xcc, /**< Soft fail state */
+       HAB_STATE_FAIL_HARD = 0xff, /**< Hard fail state (terminal) */
+       HAB_STATE_NONE = 0xf0, /**< No security state machine */
+       HAB_STATE_MAX
+};
+
+/*Function prototype description*/
+typedef enum hab_status hab_rvt_report_event_t(enum hab_status, uint32_t,
+               uint8_t* , size_t*);
+typedef enum hab_status hab_rvt_report_status_t(enum hab_config *,
+               enum hab_state *);
+typedef enum hab_status hab_loader_callback_f_t(void**, size_t*, const void*);
+typedef enum hab_status hab_rvt_entry_t(void);
+typedef enum hab_status hab_rvt_exit_t(void);
+typedef void *hab_rvt_authenticate_image_t(uint8_t, ptrdiff_t,
+               void **, size_t *, hab_loader_callback_f_t);
+typedef void hapi_clock_init_t(void);
+
+#define HAB_RVT_REPORT_EVENT (*(uint32_t *)0x000000B4)
+#define HAB_RVT_REPORT_STATUS (*(uint32_t *)0x000000B8)
+#define HAB_RVT_AUTHENTICATE_IMAGE (*(uint32_t *)0x000000A4)
+#define HAB_RVT_ENTRY (*(uint32_t *)0x00000098)
+#define HAB_RVT_EXIT (*(uint32_t *)0x0000009C)
+#define HAB_RVT_CLOCK_INIT ((hapi_clock_init_t *)0x0000024D)
+
+#define HAB_CID_ROM 0 /**< ROM Caller ID */
+#define HAB_CID_UBOOT 1 /**< UBOOT Caller ID*/
+/* ----------- end of HAB API updates ------------*/
+
+#endif
index 5d6bccbc0c9b590cd2d0af38b0a1e8d63c6585c4..7ef7152678702a1318b6f7eee45143c8fe22f357 100644 (file)
@@ -456,7 +456,13 @@ struct fuse_bank0_regs {
        u32     uid_low;
        u32     rsvd1[3];
        u32     uid_high;
-       u32     rsvd2[0x17];
+       u32     rsvd2[3];
+       u32     rsvd3[4];
+       u32     rsvd4[4];
+       u32     rsvd5[4];
+       u32     cfg5;
+       u32     rsvd6[3];
+       u32     rsvd7[4];
 };
 
 struct fuse_bank4_regs {
@@ -629,29 +635,12 @@ struct anatop_regs {
        u32     digprog_sololite;       /* 0x280 */
 };
 
-#define ANATOP_PFD_480_PFD0_FRAC_SHIFT         0
-#define ANATOP_PFD_480_PFD0_FRAC_MASK          (0x3f<<ANATOP_PFD_480_PFD0_FRAC_SHIFT)
-#define ANATOP_PFD_480_PFD0_STABLE_SHIFT       6
-#define ANATOP_PFD_480_PFD0_STABLE_MASK                (1<<ANATOP_PFD_480_PFD0_STABLE_SHIFT)
-#define ANATOP_PFD_480_PFD0_CLKGATE_SHIFT      7
-#define ANATOP_PFD_480_PFD0_CLKGATE_MASK       (1<<ANATOP_PFD_480_PFD0_CLKGATE_SHIFT)
-#define ANATOP_PFD_480_PFD1_FRAC_SHIFT         8
-#define ANATOP_PFD_480_PFD1_FRAC_MASK          (0x3f<<ANATOP_PFD_480_PFD1_FRAC_SHIFT)
-#define ANATOP_PFD_480_PFD1_STABLE_SHIFT       14
-#define ANATOP_PFD_480_PFD1_STABLE_MASK                (1<<ANATOP_PFD_480_PFD1_STABLE_SHIFT)
-#define ANATOP_PFD_480_PFD1_CLKGATE_SHIFT      15
-#define ANATOP_PFD_480_PFD1_CLKGATE_MASK       (0x3f<<ANATOP_PFD_480_PFD1_CLKGATE_SHIFT)
-#define ANATOP_PFD_480_PFD2_FRAC_SHIFT         16
-#define ANATOP_PFD_480_PFD2_FRAC_MASK          (1<<ANATOP_PFD_480_PFD2_FRAC_SHIFT)
-#define ANATOP_PFD_480_PFD2_STABLE_SHIFT       22
-#define ANATOP_PFD_480_PFD2_STABLE_MASK        (1<<ANATOP_PFD_480_PFD2_STABLE_SHIFT)
-#define ANATOP_PFD_480_PFD2_CLKGATE_SHIFT      23
-#define ANATOP_PFD_480_PFD2_CLKGATE_MASK       (0x3f<<ANATOP_PFD_480_PFD2_CLKGATE_SHIFT)
-#define ANATOP_PFD_480_PFD3_FRAC_SHIFT         24
-#define ANATOP_PFD_480_PFD3_FRAC_MASK          (1<<ANATOP_PFD_480_PFD3_FRAC_SHIFT)
-#define ANATOP_PFD_480_PFD3_STABLE_SHIFT       30
-#define ANATOP_PFD_480_PFD3_STABLE_MASK                (1<<ANATOP_PFD_480_PFD3_STABLE_SHIFT)
-#define ANATOP_PFD_480_PFD3_CLKGATE_SHIFT      31
+#define ANATOP_PFD_FRAC_SHIFT(n)       ((n)*8)
+#define ANATOP_PFD_FRAC_MASK(n)        (0x3f<<ANATOP_PFD_FRAC_SHIFT(n))
+#define ANATOP_PFD_STABLE_SHIFT(n)     (6+((n)*8))
+#define ANATOP_PFD_STABLE_MASK(n)      (1<<ANATOP_PFD_STABLE_SHIFT(n))
+#define ANATOP_PFD_CLKGATE_SHIFT(n)    (7+((n)*8))
+#define ANATOP_PFD_CLKGATE_MASK(n)     (1<<ANATOP_PFD_CLKGATE_SHIFT(n))
 
 struct iomuxc_base_regs {
        u32     gpr[14];        /* 0x000 */
index bfdfd2911d05b10773ffcd53b93ae2de90899866..8c21364e71b7ca72cff54dd7344da533fe77cdc1 100644 (file)
 
 #define is_soc_rev(rev)        ((get_cpu_rev() & 0xFF) - rev)
 u32 get_cpu_rev(void);
+
+/* returns MXC_CPU_ value */
+#define cpu_type(rev) (((rev) >> 12)&0xff)
+
+/* use with MXC_CPU_ constants */
+#define is_cpu_type(cpu) (cpu_type(get_cpu_rev()) == cpu)
+
 const char *get_imx_type(u32 imxtype);
 unsigned imx_ddr_size(void);
 
diff --git a/arch/arm/include/asm/arch-mxs/regs-uartapp.h b/arch/arm/include/asm/arch-mxs/regs-uartapp.h
new file mode 100644 (file)
index 0000000..7ceb810
--- /dev/null
@@ -0,0 +1,220 @@
+/*
+ * Freescale MXS UARTAPP Register Definitions
+ *
+ * Copyright (C) 2013 Andreas Wass <andreas.wass@dalelven.com>
+ *
+ * Based on code from LTIB:
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __ARCH_ARM___MXS_UARTAPP_H
+#define __ARCH_ARM___MXS_UARTAPP_H
+
+#include <asm/imx-common/regs-common.h>
+
+#ifndef __ASSEMBLY__
+struct mxs_uartapp_regs {
+       mxs_reg_32(hw_uartapp_ctrl0)
+       mxs_reg_32(hw_uartapp_ctrl1)
+       mxs_reg_32(hw_uartapp_ctrl2)
+       mxs_reg_32(hw_uartapp_linectrl)
+       mxs_reg_32(hw_uartapp_linectrl2)
+       mxs_reg_32(hw_uartapp_intr)
+       mxs_reg_32(hw_uartapp_data)
+       mxs_reg_32(hw_uartapp_stat)
+       mxs_reg_32(hw_uartapp_debug)
+       mxs_reg_32(hw_uartapp_version)
+       mxs_reg_32(hw_uartapp_autobaud)
+};
+#endif
+
+#define UARTAPP_CTRL0_SFTRST_MASK                              (1 << 31)
+#define UARTAPP_CTRL0_CLKGATE_MASK                     (1 << 30)
+#define UARTAPP_CTRL0_RUN_MASK                         (1 << 29)
+#define UARTAPP_CTRL0_RX_SOURCE_MASK                   (1 << 28)
+#define UARTAPP_CTRL0_RXTO_ENABLE_MASK                 (1 << 27)
+#define UARTAPP_CTRL0_RXTIMEOUT_OFFSET                 16
+#define UARTAPP_CTRL0_RXTIMEOUT_MASK                   (0x7FF << 16)
+#define UARTAPP_CTRL0_XFER_COUNT_OFFSET                        0
+#define UARTAPP_CTRL0_XFER_COUNT_MASK                  0xFFFF
+
+#define UARTAPP_CTRL1_RUN_MASK                         (1 << 28)
+
+#define UARTAPP_CTRL1_XFER_COUNT_OFFSET                        0
+#define UARTAPP_CTRL1_XFER_COUNT_MASK                  0xFFFF
+
+#define UARTAPP_CTRL2_INVERT_RTS_MASK                  (1 << 31)
+#define UARTAPP_CTRL2_INVERT_CTS_MASK                  (1 << 30)
+#define UARTAPP_CTRL2_INVERT_TX_MASK                   (1 << 29)
+#define UARTAPP_CTRL2_INVERT_RX_MASK                   (1 << 28)
+#define UARTAPP_CTRL2_RTS_SEMAPHORE_MASK                       (1 << 27)
+#define UARTAPP_CTRL2_DMAONERR_MASK                    (1 << 26)
+#define UARTAPP_CTRL2_TXDMAE_MASK                              (1 << 25)
+#define UARTAPP_CTRL2_RXDMAE_MASK                              (1 << 24)
+#define UARTAPP_CTRL2_RXIFLSEL_OFFSET                  20
+#define UARTAPP_CTRL2_RXIFLSEL_MASK                    (0x7 << 20)
+
+#define UARTAPP_CTRL2_RXIFLSEL_NOT_EMPTY               (0x0 << 20)
+#define UARTAPP_CTRL2_RXIFLSEL_ONE_QUARTER             (0x1 << 20)
+#define UARTAPP_CTRL2_RXIFLSEL_ONE_HALF                (0x2 << 20)
+#define UARTAPP_CTRL2_RXIFLSEL_THREE_QUARTERS          (0x3 << 20)
+#define UARTAPP_CTRL2_RXIFLSEL_SEVEN_EIGHTHS           (0x4 << 20)
+#define UARTAPP_CTRL2_RXIFLSEL_INVALID5                (0x5 << 20)
+#define UARTAPP_CTRL2_RXIFLSEL_INVALID6                (0x6 << 20)
+#define UARTAPP_CTRL2_RXIFLSEL_INVALID7                (0x7 << 20)
+#define UARTAPP_CTRL2_TXIFLSEL_OFFSET                  16
+#define UARTAPP_CTRL2_TXIFLSEL_MASK                    (0x7 << 16)
+#define UARTAPP_CTRL2_TXIFLSEL_EMPTY                   (0x0 << 16)
+#define UARTAPP_CTRL2_TXIFLSEL_ONE_QUARTER             (0x1 << 16)
+#define UARTAPP_CTRL2_TXIFLSEL_ONE_HALF                (0x2 << 16)
+#define UARTAPP_CTRL2_TXIFLSEL_THREE_QUARTERS          (0x3 << 16)
+#define UARTAPP_CTRL2_TXIFLSEL_SEVEN_EIGHTHS           (0x4 << 16)
+#define UARTAPP_CTRL2_TXIFLSEL_INVALID5                (0x5 << 16)
+#define UARTAPP_CTRL2_TXIFLSEL_INVALID6                (0x6 << 16)
+#define UARTAPP_CTRL2_TXIFLSEL_INVALID7                (0x7 << 16)
+#define UARTAPP_CTRL2_CTSEN_MASK                               (1 << 15)
+#define UARTAPP_CTRL2_RTSEN_MASK                               (1 << 14)
+#define UARTAPP_CTRL2_OUT2_MASK                                (1 << 13)
+#define UARTAPP_CTRL2_OUT1_MASK                                (1 << 12)
+#define UARTAPP_CTRL2_RTS_MASK                         (1 << 11)
+#define UARTAPP_CTRL2_DTR_MASK                         (1 << 10)
+#define UARTAPP_CTRL2_RXE_MASK                         (1 << 9)
+#define UARTAPP_CTRL2_TXE_MASK                         (1 << 8)
+#define UARTAPP_CTRL2_LBE_MASK                         (1 << 7)
+#define UARTAPP_CTRL2_USE_LCR2_MASK                    (1 << 6)
+
+#define UARTAPP_CTRL2_SIRLP_MASK                               (1 << 2)
+#define UARTAPP_CTRL2_SIREN_MASK                               (1 << 1)
+#define UARTAPP_CTRL2_UARTEN_MASK                              0x01
+
+#define UARTAPP_LINECTRL_BAUD_DIVINT_OFFSET                    16
+#define UARTAPP_LINECTRL_BAUD_DIVINT_MASK                      (0xFFFF << 16)
+#define UARTAPP_LINECTRL_EXTRACT_BAUD_DIVINT_OFFSET            6
+
+#define UARTAPP_LINECTRL_BAUD_DIVFRAC_OFFSET           8
+#define UARTAPP_LINECTRL_BAUD_DIVFRAC_MASK             (0x3F << 8)
+#define UARTAPP_LINECTRL_EXTRACT_BAUD_DIVFRAC_MASK     0x3F
+
+#define UARTAPP_LINECTRL_SPS_MASK                              (1 << 7)
+#define UARTAPP_LINECTRL_WLEN_OFFSET                   5
+#define UARTAPP_LINECTRL_WLEN_MASK                     (0x03 << 5)
+#define UARTAPP_LINECTRL_WLEN_5BITS                    (0x00 << 5)
+#define UARTAPP_LINECTRL_WLEN_6BITS                    (0x01 << 5)
+#define UARTAPP_LINECTRL_WLEN_7BITS                    (0x02 << 5)
+#define UARTAPP_LINECTRL_WLEN_8BITS                    (0x03 << 5)
+
+#define UARTAPP_LINECTRL_FEN_MASK                              (1 << 4)
+#define UARTAPP_LINECTRL_STP2_MASK                     (1 << 3)
+#define UARTAPP_LINECTRL_EPS_MASK                              (1 << 2)
+#define UARTAPP_LINECTRL_PEN_MASK                              (1 << 1)
+#define UARTAPP_LINECTRL_BRK_MASK                              1
+
+#define UARTAPP_LINECTRL2_BAUD_DIVINT_OFFSET           16
+#define UARTAPP_LINECTRL2_BAUD_DIVINT_MASK             (0xFFFF << 16)
+#define UARTAPP_LINECTRL2_EXTRACT_BAUD_DIVINT_OFFSET   6
+
+#define UARTAPP_LINECTRL2_BAUD_DIVFRAC_OFFSET          8
+#define UARTAPP_LINECTRL2_BAUD_DIVFRAC_MASK            (0x3F << 8)
+#define UARTAPP_LINECTRL2_EXTRACT_BAUD_DIVFRAC_MASK    0x3F
+
+#define UARTAPP_LINECTRL2_SPS_MASK                     (1 << 7)
+#define UARTAPP_LINECTRL2_WLEN_OFFSET                  5
+#define UARTAPP_LINECTRL2_WLEN_MASK                    (0x03 << 5)
+#define UARTAPP_LINECTRL2_WLEN_5BITS                   (0x00 << 5)
+#define UARTAPP_LINECTRL2_WLEN_6BITS                   (0x01 << 5)
+#define UARTAPP_LINECTRL2_WLEN_7BITS                   (0x02 << 5)
+#define UARTAPP_LINECTRL2_WLEN_8BITS                   (0x03 << 5)
+
+#define UARTAPP_LINECTRL2_FEN_MASK                     (1 << 4)
+#define UARTAPP_LINECTRL2_STP2_MASK                    (1 << 3)
+#define UARTAPP_LINECTRL2_EPS_MASK                     (1 << 2)
+#define UARTAPP_LINECTRL2_PEN_MASK                     (1 << 1)
+
+#define UARTAPP_INTR_ABDIEN_MASK                               (1 << 27)
+#define UARTAPP_INTR_OEIEN_MASK                                (1 << 26)
+#define UARTAPP_INTR_BEIEN_MASK                                (1 << 25)
+#define UARTAPP_INTR_PEIEN_MASK                                (1 << 24)
+#define UARTAPP_INTR_FEIEN_MASK                                (1 << 23)
+#define UARTAPP_INTR_RTIEN_MASK                                (1 << 22)
+#define UARTAPP_INTR_TXIEN_MASK                                (1 << 21)
+#define UARTAPP_INTR_RXIEN_MASK                                (1 << 20)
+#define UARTAPP_INTR_DSRMIEN_MASK                              (1 << 19)
+#define UARTAPP_INTR_DCDMIEN_MASK                              (1 << 18)
+#define UARTAPP_INTR_CTSMIEN_MASK                              (1 << 17)
+#define UARTAPP_INTR_RIMIEN_MASK                               (1 << 16)
+
+#define UARTAPP_INTR_ABDIS_MASK                                (1 << 11)
+#define UARTAPP_INTR_OEIS_MASK                         (1 << 10)
+#define UARTAPP_INTR_BEIS_MASK                         (1 << 9)
+#define UARTAPP_INTR_PEIS_MASK                         (1 << 8)
+#define UARTAPP_INTR_FEIS_MASK                         (1 << 7)
+#define UARTAPP_INTR_RTIS_MASK                         (1 << 6)
+#define UARTAPP_INTR_TXIS_MASK                         (1 << 5)
+#define UARTAPP_INTR_RXIS_MASK                         (1 << 4)
+#define UARTAPP_INTR_DSRMIS_MASK                               (1 << 3)
+#define UARTAPP_INTR_DCDMIS_MASK                               (1 << 2)
+#define UARTAPP_INTR_CTSMIS_MASK                               (1 << 1)
+#define UARTAPP_INTR_RIMIS_MASK                                0x1
+
+#define UARTAPP_DATA_DATA_OFFSET                               0
+#define UARTAPP_DATA_DATA_MASK                         0xFFFFFFFF
+#define UARTAPP_STAT_PRESENT_MASK                              (1 << 31)
+#define UARTAPP_STAT_PRESENT_UNAVAILABLE               (0x0 << 31)
+#define UARTAPP_STAT_PRESENT_AVAILABLE                 (0x1 << 31)
+
+#define UARTAPP_STAT_HISPEED_MASK                              (1 << 30)
+#define UARTAPP_STAT_HISPEED_UNAVAILABLE               (0x0 << 30)
+#define UARTAPP_STAT_HISPEED_AVAILABLE                 (0x1 << 30)
+
+#define UARTAPP_STAT_BUSY_MASK                         (1 << 29)
+#define UARTAPP_STAT_CTS_MASK                          (1 << 28)
+#define UARTAPP_STAT_TXFE_MASK                         (1 << 27)
+#define UARTAPP_STAT_RXFF_MASK                         (1 << 26)
+#define UARTAPP_STAT_TXFF_MASK                         (1 << 25)
+#define UARTAPP_STAT_RXFE_MASK                         (1 << 24)
+#define UARTAPP_STAT_RXBYTE_INVALID_OFFSET                     20
+#define UARTAPP_STAT_RXBYTE_INVALID_MASK               (0xF << 20)
+
+#define UARTAPP_STAT_OERR_MASK                         (1 << 19)
+#define UARTAPP_STAT_BERR_MASK                         (1 << 18)
+#define UARTAPP_STAT_PERR_MASK                         (1 << 17)
+#define UARTAPP_STAT_FERR_MASK                         (1 << 16)
+#define UARTAPP_STAT_RXCOUNT_OFFSET                            0
+#define UARTAPP_STAT_RXCOUNT_MASK                              0xFFFF
+
+#define UARTAPP_DEBUG_RXIBAUD_DIV_OFFSET                       16
+#define UARTAPP_DEBUG_RXIBAUD_DIV_MASK                         (0xFFFF << 16)
+
+#define UARTAPP_DEBUG_RXFBAUD_DIV_OFFSET                       10
+#define UARTAPP_DEBUG_RXFBAUD_DIV_MASK                         (0x3F << 10)
+
+#define UARTAPP_DEBUG_TXDMARUN_MASK                    (1 << 5)
+#define UARTAPP_DEBUG_RXDMARUN_MASK                    (1 << 4)
+#define UARTAPP_DEBUG_TXCMDEND_MASK                    (1 << 3)
+#define UARTAPP_DEBUG_RXCMDEND_MASK                    (1 << 2)
+#define UARTAPP_DEBUG_TXDMARQ_MASK                     (1 << 1)
+#define UARTAPP_DEBUG_RXDMARQ_MASK                     0x01
+
+#define UARTAPP_VERSION_MAJOR_OFFSET                   24
+#define UARTAPP_VERSION_MAJOR_MASK                     (0xFF << 24)
+
+#define UARTAPP_VERSION_MINOR_OFFSET                   16
+#define UARTAPP_VERSION_MINOR_MASK                     (0xFF << 16)
+
+#define UARTAPP_VERSION_STEP_OFFSET                            0
+#define UARTAPP_VERSION_STEP_MASK                              0xFFFF
+
+#define UARTAPP_AUTOBAUD_REFCHAR1_OFFSET                       24
+#define UARTAPP_AUTOBAUD_REFCHAR1_MASK                         (0xFF << 24)
+
+#define UARTAPP_AUTOBAUD_REFCHAR0_OFFSET                       16
+#define UARTAPP_AUTOBAUD_REFCHAR0_MASK                         (0xFF << 16)
+
+#define UARTAPP_AUTOBAUD_UPDATE_TX_MASK                        (1 << 4)
+#define UARTAPP_AUTOBAUD_TWO_REF_CHARS_MASK            (1 << 3)
+#define UARTAPP_AUTOBAUD_START_WITH_RUNBIT_MASK                (1 << 2)
+#define UARTAPP_AUTOBAUD_START_BAUD_DETECT_MASK                (1 << 1)
+#define UARTAPP_AUTOBAUD_BAUD_DETECT_ENABLE_MASK               0x01
+#endif /* __ARCH_ARM___UARTAPP_H */
index 514839c778eabb0e24d4c989cae0a9a2231eb70a..be669c156f51b7c80085489e3dbd783243403fc7 100644 (file)
@@ -63,6 +63,4 @@ extern dpll_param *get_36x_core_dpll_param(void);
 extern dpll_param *get_36x_per_dpll_param(void);
 extern dpll_param *get_36x_per2_dpll_param(void);
 
-extern void *_end_vect, *_start;
-
 #endif
index b2e03d6e1e393e4de5d9fdf8f8bfdca0e6b0918e..f3a682a19715675b0c5ad9ef202df7145d7dcc3c 100644 (file)
 /* PRM_VC_VAL_BYPASS */
 #define PRM_VC_I2C_CHANNEL_FREQ_KHZ    400
 
-/* SMPS */
+/* PMIC */
 #define SMPS_I2C_SLAVE_ADDR    0x12
+/* TWL6030 SMPS */
 #define SMPS_REG_ADDR_VCORE1   0x55
 #define SMPS_REG_ADDR_VCORE2   0x5B
 #define SMPS_REG_ADDR_VCORE3   0x61
+/* TWL6032 SMPS */
+#define SMPS_REG_ADDR_SMPS1    0x55
+#define SMPS_REG_ADDR_SMPS2    0x5B
+#define SMPS_REG_ADDR_SMPS5    0x49
 
 #define PHOENIX_SMPS_BASE_VOLT_STD_MODE_UV             607700
 #define PHOENIX_SMPS_BASE_VOLT_STD_MODE_WITH_OFFSET_UV 709000
index 3823a37f2ff00770dacdd419e85d7fefe160ee8f..9129c0dd7cb005c4ed0494b367c3956c0503266a 100644 (file)
@@ -41,6 +41,7 @@
 #define OMAP4_CONTROL_ID_CODE_ES2_3    0x6B95C02F
 #define OMAP4460_CONTROL_ID_CODE_ES1_0 0x0B94E02F
 #define OMAP4460_CONTROL_ID_CODE_ES1_1 0x2B94E02F
+#define OMAP4470_CONTROL_ID_CODE_ES1_0 0x0B97502F
 
 /* UART */
 #define UART1_BASE             (OMAP44XX_L4_PER_BASE + 0x6a000)
index 597c692b97c1423fc4807ab600c457733c9e238d..e9a51d340381fbe94bd608e10776db3a2272c455 100644 (file)
@@ -153,6 +153,15 @@ struct s32ktimer {
 #define EFUSE_4 0x45145100
 #endif /* __ASSEMBLY__ */
 
+/*
+ * In all cases, the TRM defines the RAM Memory Map for the processor
+ * and indicates the area for the downloaded image.  We use all of that
+ * space for download and once up and running may use other parts of the
+ * map for our needs.  We set a scratch space that is at the end of the
+ * OMAP5 download area, but within the DRA7xx download area (as it is
+ * much larger) and do not, at this time, make use of the additional
+ * space.
+ */
 #ifdef CONFIG_DRA7XX
 #define NON_SECURE_SRAM_START  0x40300000
 #define NON_SECURE_SRAM_END    0x40380000      /* Not inclusive */
@@ -160,7 +169,7 @@ struct s32ktimer {
 #define NON_SECURE_SRAM_START  0x40300000
 #define NON_SECURE_SRAM_END    0x40320000      /* Not inclusive */
 #endif
-#define SRAM_SCRATCH_SPACE_ADDR        NON_SECURE_SRAM_START
+#define SRAM_SCRATCH_SPACE_ADDR        0x4031E000
 
 /* base address for indirect vectors (internal boot mode) */
 #define SRAM_ROM_VECT_BASE     0x4031F000
index 13d73577023d23c6f86e776026f1ac3067632950..3e9547682833c25cfd2e5c5c0c48f49c05a570ed 100644 (file)
@@ -11,16 +11,20 @@ void reset_cpu(ulong addr);
 void reset_deassert_peripherals_handoff(void);
 
 struct socfpga_reset_manager {
-       u32     padding1;
+       u32     status;
        u32     ctrl;
-       u32     padding2;
-       u32     padding3;
+       u32     counts;
+       u32     padding1;
        u32     mpu_mod_reset;
        u32     per_mod_reset;
        u32     per2_mod_reset;
        u32     brg_mod_reset;
 };
 
+#if defined(CONFIG_SOCFPGA_VIRTUAL_TARGET)
+#define RSTMGR_CTRL_SWWARMRSTREQ_LSB 2
+#else
 #define RSTMGR_CTRL_SWWARMRSTREQ_LSB 1
+#endif
 
 #endif /* _RESET_MANAGER_H_ */
index 081624e20160fc8ae088da5609aca7566f7a8faf..cd69677729cbf81ad237e1ac64b8477fde37e1f3 100644 (file)
@@ -19,6 +19,7 @@
 #define ZYNQ_I2C_BASEADDR1             0xE0005000
 #define ZYNQ_SPI_BASEADDR0             0xE0006000
 #define ZYNQ_SPI_BASEADDR1             0xE0007000
+#define ZYNQ_DDRC_BASEADDR             0xF8006000
 
 /* Reflect slcr offsets */
 struct slcr_regs {
@@ -86,4 +87,11 @@ struct scu_regs {
 
 #define scu_base ((struct scu_regs *)ZYNQ_SCU_BASEADDR)
 
+struct ddrc_regs {
+       u32 ddrc_ctrl; /* 0x0 */
+       u32 reserved[60];
+       u32 ecc_scrub; /* 0xF4 */
+};
+#define ddrc_base ((struct ddrc_regs *)ZYNQ_DDRC_BASEADDR)
+
 #endif /* _ASM_ARCH_HARDWARE_H */
index 19a4eec6a973f23595c4112e8e013afacb9f0f54..110de9092213995dbee9a50c4cdca4810643c606 100644 (file)
@@ -14,6 +14,7 @@ extern void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk);
 extern void zynq_slcr_devcfg_disable(void);
 extern void zynq_slcr_devcfg_enable(void);
 extern u32 zynq_slcr_get_idcode(void);
+extern void zynq_ddrc_init(void);
 
 /* Driver extern functions */
 extern int zynq_sdhci_init(u32 regbase);
index 66f416f99cd2047add335617baf2a253405d2c7d..5e2f027ba4de678aa6bddd0632a775f58afd8ae4 100644 (file)
@@ -622,6 +622,7 @@ static inline u8 is_omap54xx(void)
 #define OMAP4430_ES2_3 0x44300230
 #define OMAP4460_ES1_0 0x44600100
 #define OMAP4460_ES1_1 0x44600110
+#define OMAP4470_ES1_0 0x44700100
 
 /* omap5 */
 #define OMAP5430_SILICON_ID_INVALID    0
index 07690f97b16a9ca9e2095233b65f60c4c23ff364..4b8d928956afdfe26cffba7fd4d9d02c6c0146bb 100644 (file)
@@ -399,7 +399,8 @@ int get_clocks (void)
         * AN2919.
         */
 #if defined(CONFIG_MPC8540) || defined(CONFIG_MPC8541) || \
-       defined(CONFIG_MPC8560) || defined(CONFIG_MPC8555)
+       defined(CONFIG_MPC8560) || defined(CONFIG_MPC8555) || \
+       defined(CONFIG_P1022)
        gd->arch.i2c1_clk = sys_info.freq_systembus;
 #elif defined(CONFIG_MPC8544)
        /*
index 85ec74ba94adbfeedef1e339d10f06a3ded6d034..bc132673a51a73f8c8cac62440c35bdf685a104d 100644 (file)
@@ -44,6 +44,11 @@ SECTIONS
        }
        _edata  =  .;
 
+       . = ALIGN(4);
+       .u_boot_list : {
+               KEEP(*(SORT(.u_boot_list*)));
+       }
+
        . = .;
        __start___ex_table = .;
        __ex_table : { *(__ex_table) }
diff --git a/board/atmel/at91sam9m10g45ek/config.mk b/board/atmel/at91sam9m10g45ek/config.mk
deleted file mode 100644 (file)
index 9d3c5ae..0000000
+++ /dev/null
@@ -1 +0,0 @@
-CONFIG_SYS_TEXT_BASE = 0x73f00000
diff --git a/board/atmel/at91sam9x5ek/config.mk b/board/atmel/at91sam9x5ek/config.mk
deleted file mode 100644 (file)
index 6589a12..0000000
+++ /dev/null
@@ -1 +0,0 @@
-CONFIG_SYS_TEXT_BASE = 0x26f00000
index 4a309ad17f575697e0b1b539d930ebacc7d314da..97caf64d4040fe33e0c00fca362bbdc09ddbac7b 100644 (file)
@@ -17,6 +17,7 @@
 #include <lcd.h>
 #include <atmel_lcdc.h>
 #include <atmel_mci.h>
+#include <micrel.h>
 #include <net.h>
 #include <netdev.h>
 
@@ -178,6 +179,8 @@ int board_init(void)
 #ifdef CONFIG_MACB
        if (has_emac())
                at91_macb_hw_init();
+       if (has_gmac())
+               at91_gmac_hw_init();
 #endif
 #ifdef CONFIG_LCD
        if (has_lcdc())
@@ -193,6 +196,21 @@ int dram_init(void)
        return 0;
 }
 
+int board_phy_config(struct phy_device *phydev)
+{
+       /* rx data delay */
+       ksz9021_phy_extended_write(phydev,
+                                  MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x2222);
+       /* tx data delay */
+       ksz9021_phy_extended_write(phydev,
+                                  MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, 0x2222);
+       /* rx/tx clock delay */
+       ksz9021_phy_extended_write(phydev,
+                                  MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0xf2f4);
+
+       return 0;
+}
+
 int board_eth_init(bd_t *bis)
 {
        int rc = 0;
@@ -200,6 +218,8 @@ int board_eth_init(bd_t *bis)
 #ifdef CONFIG_MACB
        if (has_emac())
                rc = macb_eth_initialize(0, (void *)ATMEL_BASE_EMAC, 0x00);
+       if (has_gmac())
+               rc = macb_eth_initialize(0, (void *)ATMEL_BASE_GMAC, 0x00);
 #endif
 
        return rc;
index 79ab44904e19a8ad293896c7fb2b3ef410b7ff3f..f664f6de6b398b03848fffa3344a4c6f6564eed5 100644 (file)
@@ -622,7 +622,6 @@ int board_video_skip(void)
 static void setup_display(void)
 {
        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
-       struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
        struct iomuxc *iomux = (struct iomuxc *)IOMUXC_BASE_ADDR;
        int reg;
 
@@ -633,10 +632,6 @@ static void setup_display(void)
        reg |=  MXC_CCM_CCGR3_LDB_DI0_MASK;
        writel(reg, &mxc_ccm->CCGR3);
 
-       /* set PFD1_FRAC to 0x13 == 455 MHz (480*18)/0x13 */
-       writel(ANATOP_PFD_480_PFD1_FRAC_MASK, &anatop->pfd_480_clr);
-       writel(0x13<<ANATOP_PFD_480_PFD1_FRAC_SHIFT, &anatop->pfd_480_set);
-
        /* set LDB0, LDB1 clk select to 011/011 */
        reg = readl(&mxc_ccm->cs2cdr);
        reg &= ~(MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK
@@ -666,7 +661,8 @@ static void setup_display(void)
        writel(reg, &iomux->gpr[2]);
 
        reg = readl(&iomux->gpr[3]);
-       reg = (reg & ~IOMUXC_GPR3_LVDS0_MUX_CTL_MASK)
+       reg = (reg & ~(IOMUXC_GPR3_LVDS0_MUX_CTL_MASK
+                       |IOMUXC_GPR3_HDMI_MUX_CTL_MASK))
            | (IOMUXC_GPR3_MUX_SRC_IPU1_DI0
               <<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET);
        writel(reg, &iomux->gpr[3]);
index bbf0f75a4d7ea182539ea8ac766b8d8609c3e7e5..5e76d2ac5e8a3ecec1eb203cbbffb7b4759619bd 100644 (file)
@@ -7,8 +7,7 @@ Conga-QEVAl Evaluation Carrier board with qmx6 quad module.
 1. Boot source, boot from SD card
 ---------------------------------
 
-This version of u-boot works only on the SD card. By default, the
-Congatec board can boot only from the SPI-NOR.
+By default, the Congatec board can boot only from the SPI-NOR.
 But, with the u-boot version provided with the board you can write boot
 registers to force the board to reboot and boot from the SD slot. If
 "bmode" command is not available from your pre-installed u-boot, these
index b9dbf81b3f89b0024a0c1c2bca0ee704bc456070..7f151e38cf911b05521f7a53cbf048ad5820cf51 100644 (file)
@@ -102,7 +102,11 @@ void board_init_r(gd_t *gd, ulong dest_addr)
        env_relocate();
 #endif
 
-       i2c_init(CONFIG_SYS_FSL_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#ifdef CONFIG_SYS_I2C
+       i2c_init_all();
+#else
+       i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
 
        gd->ram_size = initdram(0);
 #ifdef CONFIG_SPL_NAND_BOOT
index a24c22b1ad44fe737e222e745036ced8ff8bf3bb..9e91f68eb0b3282c801593bb060b59e3e3236e5a 100644 (file)
@@ -27,9 +27,6 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* MII mode defines */
-#define RMII_MODE_ENABLE       0x4D
-
 static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
 
 #ifdef CONFIG_SPL_BUILD
@@ -158,7 +155,8 @@ int board_eth_init(bd_t *bis)
                        eth_setenv_enetaddr("ethaddr", mac_addr);
        }
 
-       writel(RMII_MODE_ENABLE, &cdev->miisel);
+       writel((GMII1_SEL_RMII | RMII1_IO_CLK_EN),
+              &cdev->miisel);
 
        rv = cpsw_register(&cpsw_data);
        if (rv < 0)
index f53c5bbd4b50f4e42781fabb13ac74f62e9902e4..e40b0bd44df890887a38e12e3f0685fde66a8f05 100644 (file)
@@ -31,8 +31,6 @@
 DECLARE_GLOBAL_DATA_PTR;
 
 /* MII mode defines */
-#define MII_MODE_ENABLE                0x0
-#define RGMII_MODE_ENABLE      0xA
 #define RMII_RGMII2_MODE_ENABLE        0x49
 
 static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
diff --git a/board/siemens/common/board.c b/board/siemens/common/board.c
new file mode 100644 (file)
index 0000000..6279c32
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+ * Common board functions for siemens AM335X based boards
+ * (C) Copyright 2013 Siemens Schweiz AG
+ * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Based on:
+ * U-Boot file:/board/ti/am335x/board.c
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <spl.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/omap.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/mmc_host_def.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+#include <asm/emif.h>
+#include <asm/gpio.h>
+#include <i2c.h>
+#include <miiphy.h>
+#include <cpsw.h>
+#include <watchdog.h>
+#include "../common/factoryset.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_SPL_BUILD
+void set_uart_mux_conf(void)
+{
+       enable_uart0_pin_mux();
+}
+
+void set_mux_conf_regs(void)
+{
+       /* Initalize the board header */
+       enable_i2c0_pin_mux();
+       i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+       if (read_eeprom() < 0)
+               puts("Could not get board ID.\n");
+
+       enable_board_pin_mux();
+}
+
+void sdram_init(void)
+{
+       spl_siemens_board_init();
+       board_init_ddr();
+
+       return;
+}
+#endif /* #ifdef CONFIG_SPL_BUILD */
+
+#ifndef CONFIG_SPL_BUILD
+/*
+ * Basic board specific setup.  Pinmux has been handled already.
+ */
+int board_init(void)
+{
+#if defined(CONFIG_HW_WATCHDOG)
+       hw_watchdog_init();
+#endif /* defined(CONFIG_HW_WATCHDOG) */
+       i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+       if (read_eeprom() < 0)
+               puts("Could not get board ID.\n");
+
+       gd->bd->bi_arch_number = CONFIG_MACH_TYPE;
+       gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
+
+#ifdef CONFIG_FACTORYSET
+       factoryset_read_eeprom(CONFIG_SYS_I2C_EEPROM_ADDR);
+#endif
+       gpmc_init();
+
+#ifdef CONFIG_VIDEO
+       board_video_init();
+#endif
+
+       return 0;
+}
+#endif /* #ifndef CONFIG_SPL_BUILD */
+
+#define OSC    (V_OSCK/1000000)
+const struct dpll_params dpll_ddr = {
+               DDR_PLL_FREQ, OSC-1, 1, -1, -1, -1, -1};
+
+const struct dpll_params *get_dpll_ddr_params(void)
+{
+       return &dpll_ddr;
+}
+
+#ifdef CONFIG_BOARD_LATE_INIT
+int board_late_init(void)
+{
+       omap_nand_switch_ecc(1, 8);
+
+       return 0;
+}
+#endif
+
+#ifndef CONFIG_SPL_BUILD
+#if defined(BOARD_DFU_BUTTON_GPIO)
+/*
+ * This command returns the status of the user button on
+ * Input - none
+ * Returns -   1 if button is held down
+ *             0 if button is not held down
+ */
+static int
+do_userbutton(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       int button = 0;
+       int gpio;
+
+       gpio = BOARD_DFU_BUTTON_GPIO;
+       gpio_request(gpio, "DFU");
+       gpio_direction_input(gpio);
+       if (gpio_get_value(gpio))
+               button = 1;
+       else
+               button = 0;
+
+       gpio_free(gpio);
+       if (!button) {
+               /* LED0 - RED=1: GPIO2_0 2*32 = 64 */
+               gpio_request(BOARD_DFU_BUTTON_LED, "");
+               gpio_direction_output(BOARD_DFU_BUTTON_LED, 1);
+               gpio_set_value(BOARD_DFU_BUTTON_LED, 1);
+       }
+
+       return button;
+}
+
+U_BOOT_CMD(
+       dfubutton, CONFIG_SYS_MAXARGS, 1, do_userbutton,
+       "Return the status of the DFU button",
+       ""
+);
+#endif
+
+static int
+do_usertestwdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       printf("\n\n\n Go into infinite loop\n\n\n");
+       while (1)
+               ;
+       return 0;
+};
+
+U_BOOT_CMD(
+       testwdt, CONFIG_SYS_MAXARGS, 1, do_usertestwdt,
+       "Sends U-Boot into infinite loop",
+       ""
+);
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+void enable_caches(void)
+{
+       printf("Enable d-cache\n");
+       /* Enable D-cache. I-cache is already enabled in start.S */
+       dcache_enable();
+}
+#endif /* CONFIG_SYS_DCACHE_OFF */
+#endif /* !CONFIG_SPL_BUILD */
diff --git a/board/siemens/common/factoryset.c b/board/siemens/common/factoryset.c
new file mode 100644 (file)
index 0000000..eda9141
--- /dev/null
@@ -0,0 +1,284 @@
+/*
+ *
+ * Read FactorySet information from EEPROM into global structure.
+ * (C) Copyright 2013 Siemens Schweiz AG
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#if !defined(CONFIG_SPL_BUILD)
+
+#include <common.h>
+#include <i2c.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/unaligned.h>
+#include <net.h>
+#include <usbdescriptors.h>
+#include "factoryset.h"
+
+#define EEPR_PG_SZ             0x80
+#define EEPROM_FATORYSET_OFFSET        0x400
+#define OFF_PG            EEPROM_FATORYSET_OFFSET/EEPR_PG_SZ
+
+/* Global variable that contains necessary information from FactorySet */
+struct factorysetcontainer factory_dat;
+
+#define fact_get_char(i) *((char *)&eeprom_buf[i])
+
+static int fact_match(unsigned char *eeprom_buf, uchar *s1, int i2)
+{
+       if (s1 == NULL)
+               return -1;
+
+       while (*s1 == fact_get_char(i2++))
+               if (*s1++ == '=')
+                       return i2;
+
+       if (*s1 == '\0' && fact_get_char(i2-1) == '=')
+               return i2;
+
+       return -1;
+}
+
+static int get_factory_val(unsigned char *eeprom_buf, int size, uchar *name,
+                       uchar *buf, int len)
+{
+       int i, nxt = 0;
+
+       for (i = 0; fact_get_char(i) != '\0'; i = nxt + 1) {
+               int val, n;
+
+               for (nxt = i; fact_get_char(nxt) != '\0'; ++nxt) {
+                       if (nxt >= size)
+                               return -1;
+               }
+
+               val = fact_match(eeprom_buf, (uchar *)name, i);
+               if (val < 0)
+                       continue;
+
+               /* found; copy out */
+               for (n = 0; n < len; ++n, ++buf) {
+                       *buf = fact_get_char(val++);
+                       if (*buf == '\0')
+                               return n;
+               }
+
+               if (n)
+                       *--buf = '\0';
+
+               printf("env_buf [%d bytes] too small for value of \"%s\"\n",
+                      len, name);
+
+               return n;
+       }
+       return -1;
+}
+
+static
+int get_factory_record_val(unsigned char *eeprom_buf, int size,        uchar *record,
+       uchar *name, uchar *buf, int len)
+{
+       int ret = -1;
+       int i, nxt = 0;
+       int c;
+       unsigned char end = 0xff;
+
+       for (i = 0; fact_get_char(i) != end; i = nxt) {
+               nxt = i + 1;
+               if (fact_get_char(i) == '>') {
+                       int pos;
+                       int endpos;
+                       int z;
+
+                       c = strncmp((char *)&eeprom_buf[i + 1], (char *)record,
+                                   strlen((char *)record));
+                       if (c == 0) {
+                               /* record found */
+                               pos = i + strlen((char *)record) + 2;
+                               nxt = pos;
+                               /* search for "<" */
+                               c = -1;
+                               for (z = pos; fact_get_char(z) != end; z++) {
+                                       if ((fact_get_char(z) == '<')  ||
+                                           (fact_get_char(z) == '>')) {
+                                               endpos = z;
+                                               nxt = endpos;
+                                               c = 0;
+                                               break;
+                                       }
+                               }
+                       }
+                       if (c == 0) {
+                               /* end found -> call get_factory_val */
+                               eeprom_buf[endpos] = end;
+                               ret = get_factory_val(&eeprom_buf[pos],
+                                       size - pos, name, buf, len);
+                               /* fix buffer */
+                               eeprom_buf[endpos] = '<';
+                               debug("%s: %s.%s = %s\n",
+                                     __func__, record, name, buf);
+                               return ret;
+                       }
+               }
+       }
+       return ret;
+}
+
+int factoryset_read_eeprom(int i2c_addr)
+{
+       int i, pages = 0, size = 0;
+       unsigned char eeprom_buf[0x3c00], hdr[4], buf[MAX_STRING_LENGTH];
+       unsigned char *cp, *cp1;
+
+#if defined(CONFIG_DFU_FUNCTION)
+       factory_dat.usb_vendor_id = CONFIG_G_DNL_VENDOR_NUM;
+       factory_dat.usb_product_id = CONFIG_G_DNL_PRODUCT_NUM;
+#endif
+       if (i2c_probe(i2c_addr))
+               goto err;
+
+       if (i2c_read(i2c_addr, EEPROM_FATORYSET_OFFSET, 2, hdr, sizeof(hdr)))
+               goto err;
+
+       if ((hdr[0] != 0x99) || (hdr[1] != 0x80)) {
+               printf("FactorySet is not right in eeprom.\n");
+               return 1;
+       }
+
+       /* get FactorySet size */
+       size = (hdr[2] << 8) + hdr[3] + sizeof(hdr);
+       if (size > 0x3bfa)
+               size = 0x3bfa;
+
+       pages = size / EEPR_PG_SZ;
+
+       /*
+        * read the eeprom using i2c
+        * I can not read entire eeprom in once, so separate into several
+        * times. Furthermore, fetch eeprom take longer time, so we fetch
+        * data after every time we got a record from eeprom
+        */
+       debug("Read eeprom page :\n");
+       for (i = 0; i < pages; i++)
+               if (i2c_read(i2c_addr, (OFF_PG + i) * EEPR_PG_SZ, 2,
+                            eeprom_buf + (i * EEPR_PG_SZ), EEPR_PG_SZ))
+                       goto err;
+
+       if (size % EEPR_PG_SZ)
+               if (i2c_read(i2c_addr, (OFF_PG + pages) * EEPR_PG_SZ, 2,
+                            eeprom_buf + (pages * EEPR_PG_SZ),
+                            (size % EEPR_PG_SZ)))
+                       goto err;
+
+       /* we do below just for eeprom align */
+       for (i = 0; i < size; i++)
+               if (eeprom_buf[i] == '\n')
+                       eeprom_buf[i] = 0;
+
+       /* skip header */
+       size -= sizeof(hdr);
+       cp = (uchar *)eeprom_buf + sizeof(hdr);
+
+       /* get mac address */
+       get_factory_record_val(cp, size, (uchar *)"ETH1", (uchar *)"mac",
+                              buf, MAX_STRING_LENGTH);
+       cp1 = buf;
+       for (i = 0; i < 6; i++) {
+               factory_dat.mac[i] = simple_strtoul((char *)cp1, NULL, 16);
+               cp1 += 3;
+       }
+
+#if defined(CONFIG_DFU_FUNCTION)
+       /* read vid and pid for dfu mode */
+       if (0 <= get_factory_record_val(cp, size, (uchar *)"USBD1",
+                                       (uchar *)"vid", buf,
+                                       MAX_STRING_LENGTH)) {
+               factory_dat.usb_vendor_id = simple_strtoul((char *)buf,
+                                                          NULL, 16);
+       }
+
+       if (0 <= get_factory_record_val(cp, size, (uchar *)"USBD1",
+                                       (uchar *)"pid", buf,
+                                       MAX_STRING_LENGTH)) {
+               factory_dat.usb_product_id = simple_strtoul((char *)buf,
+                                                           NULL, 16);
+       }
+       printf("DFU USB: VID = 0x%4x, PID = 0x%4x\n", factory_dat.usb_vendor_id,
+              factory_dat.usb_product_id);
+#endif
+       if (0 <= get_factory_record_val(cp, size, (uchar *)"DEV",
+                                       (uchar *)"id", buf,
+                                       MAX_STRING_LENGTH)) {
+               if (strncmp((const char *)buf, "PXM50", 5) == 0)
+                       factory_dat.pxm50 = 1;
+               else
+                       factory_dat.pxm50 = 0;
+       }
+       debug("PXM50: %d\n", factory_dat.pxm50);
+#if defined(CONFIG_VIDEO)
+       if (0 <= get_factory_record_val(cp, size, (uchar *)"DISP1",
+                                       (uchar *)"name", factory_dat.disp_name,
+                                       MAX_STRING_LENGTH)) {
+               debug("display name: %s\n", factory_dat.disp_name);
+       }
+
+#endif
+       return 0;
+
+err:
+       printf("Could not read the EEPROM; something fundamentally wrong on the I2C bus.\n");
+       return 1;
+}
+
+static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
+
+static int factoryset_mac_setenv(void)
+{
+       uint8_t mac_addr[6];
+
+       debug("FactorySet: Set mac address\n");
+       if (is_valid_ether_addr(factory_dat.mac)) {
+               memcpy(mac_addr, factory_dat.mac, 6);
+       } else {
+               uint32_t mac_hi, mac_lo;
+
+               debug("Warning: FactorySet: <ethaddr> not set. Fallback to E-fuse\n");
+               mac_lo = readl(&cdev->macid0l);
+               mac_hi = readl(&cdev->macid0h);
+
+               mac_addr[0] = mac_hi & 0xFF;
+               mac_addr[1] = (mac_hi & 0xFF00) >> 8;
+               mac_addr[2] = (mac_hi & 0xFF0000) >> 16;
+               mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
+               mac_addr[4] = mac_lo & 0xFF;
+               mac_addr[5] = (mac_lo & 0xFF00) >> 8;
+               if (!is_valid_ether_addr(mac_addr)) {
+                       printf("Warning: ethaddr not set by FactorySet or E-fuse. Set <ethaddr> variable to overcome this.\n");
+                       return -1;
+               }
+       }
+
+       eth_setenv_enetaddr("ethaddr", mac_addr);
+       return 0;
+}
+
+int factoryset_setenv(void)
+{
+       int ret = 0;
+
+       if (factoryset_mac_setenv() < 0)
+               ret = -1;
+
+       return ret;
+}
+
+int g_dnl_bind_fixup(struct usb_device_descriptor *dev)
+{
+       put_unaligned(factory_dat.usb_vendor_id, &dev->idVendor);
+       put_unaligned(factory_dat.usb_product_id, &dev->idProduct);
+       return 0;
+}
+#endif /* defined(CONFIG_SPL_BUILD) */
diff --git a/board/siemens/common/factoryset.h b/board/siemens/common/factoryset.h
new file mode 100644 (file)
index 0000000..445f384
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Common board functions for siemens AM335X based boards
+ * (C) Copyright 2013 Siemens Schweiz AG
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __FACTORYSET_H
+#define __FACTORYSET_H
+
+#define MAX_STRING_LENGTH      32
+
+struct factorysetcontainer {
+       uchar mac[6];
+       int usb_vendor_id;
+       int usb_product_id;
+       int pxm50;
+#if defined(CONFIG_VIDEO)
+       unsigned char disp_name[MAX_STRING_LENGTH];
+#endif
+};
+
+int factoryset_read_eeprom(int i2c_addr);
+int factoryset_setenv(void);
+extern struct factorysetcontainer factory_dat;
+
+#endif /* __FACTORYSET_H */
diff --git a/board/siemens/dxr2/Makefile b/board/siemens/dxr2/Makefile
new file mode 100644 (file)
index 0000000..a09b467
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# Makefile
+#
+# (C) Copyright 2013 Siemens Schweiz AG
+# (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+#
+# Based on:
+# u-boot:/board/ti/am335x/Makefile
+# Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)../common)
+endif
+
+LIB    = $(obj)lib$(BOARD).o
+
+ifdef CONFIG_SPL_BUILD
+COBJS  := mux.o
+endif
+
+COBJS  += board.o
+ifndef CONFIG_SPL_BUILD
+COBJS += ../common/factoryset.o
+endif
+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))
+
+clean:
+       rm -f $(SOBJS) $(OBJS)
+
+distclean:     clean
+       rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/siemens/dxr2/board.c b/board/siemens/dxr2/board.c
new file mode 100644 (file)
index 0000000..af9d84f
--- /dev/null
@@ -0,0 +1,241 @@
+/*
+ * Board functions for TI AM335X based dxr2 board
+ * (C) Copyright 2013 Siemens Schweiz AG
+ * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Based on:
+ *
+ * Board functions for TI AM335X based boards
+ * u-boot:/board/ti/am335x/board.c
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <spl.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/omap.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/mmc_host_def.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+#include <asm/emif.h>
+#include <asm/gpio.h>
+#include <i2c.h>
+#include <miiphy.h>
+#include <cpsw.h>
+#include <watchdog.h>
+#include "board.h"
+#include "../common/factoryset.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_SPL_BUILD
+static struct dxr2_baseboard_id __attribute__((section(".data"))) settings;
+
+const struct ddr3_data ddr3_default = {
+       0x33524444, 0x56312e33, 0x0100, 0x0001, 0x003A, 0x008A, 0x010B,
+       0x00C4, 0x0888A39B, 0x26247FDA, 0x501F821F, 0x0006, 0x61C04AB2,
+       0x00000618,
+};
+
+static void set_default_ddr3_timings(void)
+{
+       printf("Set default DDR3 settings\n");
+       settings.ddr3 = ddr3_default;
+}
+
+static void print_ddr3_timings(void)
+{
+       printf("\n\nDDR3 Timing parameters:\n");
+       printf("Diff     Eeprom  Default\n");
+       PRINTARGS(magic);
+       PRINTARGS(version);
+       PRINTARGS(ddr3_sratio);
+       PRINTARGS(iclkout);
+
+       PRINTARGS(dt0rdsratio0);
+       PRINTARGS(dt0wdsratio0);
+       PRINTARGS(dt0fwsratio0);
+       PRINTARGS(dt0wrsratio0);
+
+       PRINTARGS(sdram_tim1);
+       PRINTARGS(sdram_tim2);
+       PRINTARGS(sdram_tim3);
+
+       PRINTARGS(emif_ddr_phy_ctlr_1);
+
+       PRINTARGS(sdram_config);
+       PRINTARGS(ref_ctrl);
+}
+
+static void print_chip_data(void)
+{
+       printf("\n");
+       printf("Device: '%s'\n", settings.chip.sdevname);
+       printf("HW version: '%s'\n", settings.chip.shwver);
+}
+#endif /* CONFIG_SPL_BUILD */
+
+/*
+ * Read header information from EEPROM into global structure.
+ */
+static int read_eeprom(void)
+{
+       /* Check if baseboard eeprom is available */
+       if (i2c_probe(CONFIG_SYS_I2C_EEPROM_ADDR)) {
+               printf("Could not probe the EEPROM; something fundamentally wrong on the I2C bus.\n");
+               return 1;
+       }
+
+#ifdef CONFIG_SPL_BUILD
+       /* Read Siemens eeprom data (DDR3) */
+       if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, EEPROM_ADDR_DDR3, 2,
+                    (uchar *)&settings.ddr3, sizeof(struct ddr3_data))) {
+               printf("Could not read the EEPROM; something fundamentally wrong on the I2C bus.\nUse default DDR3 timings\n");
+               set_default_ddr3_timings();
+       }
+       /* Read Siemens eeprom data (CHIP) */
+       if (i2c_read(CONFIG_SYS_I2C_EEPROM_ADDR, EEPROM_ADDR_CHIP, 2,
+                    (uchar *)&settings.chip, sizeof(settings.chip)))
+               printf("Could not read chip settings\n");
+
+       if (ddr3_default.magic == settings.ddr3.magic &&
+           ddr3_default.version == settings.ddr3.version) {
+               printf("Using DDR3 settings from EEPROM\n");
+       } else {
+               if (ddr3_default.magic != settings.ddr3.magic)
+                       printf("Error: No valid DDR3 data in eeprom.\n");
+               if (ddr3_default.version != settings.ddr3.version)
+                       printf("Error: DDR3 data version does not match.\n");
+
+               printf("Using default settings\n");
+               set_default_ddr3_timings();
+       }
+
+       if (MAGIC_CHIP == settings.chip.magic) {
+               printf("Valid chip data in eeprom\n");
+               print_chip_data();
+       } else {
+               printf("Error: No chip data in eeprom\n");
+       }
+
+       print_ddr3_timings();
+#endif
+       return 0;
+}
+
+#ifdef CONFIG_SPL_BUILD
+static void board_init_ddr(void)
+{
+struct emif_regs dxr2_ddr3_emif_reg_data = {
+       .zq_config = 0x50074BE4,
+};
+
+struct ddr_data dxr2_ddr3_data = {
+       .datadldiff0 = PHY_DLL_LOCK_DIFF,
+};
+
+struct cmd_control dxr2_ddr3_cmd_ctrl_data = {
+       .cmd0dldiff = 0,
+       .cmd1dldiff = 0,
+       .cmd2dldiff = 0,
+};
+       /* pass values from eeprom */
+       dxr2_ddr3_emif_reg_data.sdram_tim1 = settings.ddr3.sdram_tim1;
+       dxr2_ddr3_emif_reg_data.sdram_tim2 = settings.ddr3.sdram_tim2;
+       dxr2_ddr3_emif_reg_data.sdram_tim3 = settings.ddr3.sdram_tim3;
+       dxr2_ddr3_emif_reg_data.emif_ddr_phy_ctlr_1 =
+               settings.ddr3.emif_ddr_phy_ctlr_1;
+       dxr2_ddr3_emif_reg_data.sdram_config = settings.ddr3.sdram_config;
+       dxr2_ddr3_emif_reg_data.ref_ctrl = settings.ddr3.ref_ctrl;
+
+       dxr2_ddr3_data.datardsratio0 = settings.ddr3.dt0rdsratio0;
+       dxr2_ddr3_data.datawdsratio0 = settings.ddr3.dt0wdsratio0;
+       dxr2_ddr3_data.datafwsratio0 = settings.ddr3.dt0fwsratio0;
+       dxr2_ddr3_data.datawrsratio0 = settings.ddr3.dt0wrsratio0;
+
+       dxr2_ddr3_cmd_ctrl_data.cmd0csratio = settings.ddr3.ddr3_sratio;
+       dxr2_ddr3_cmd_ctrl_data.cmd0iclkout = settings.ddr3.iclkout;
+       dxr2_ddr3_cmd_ctrl_data.cmd1csratio = settings.ddr3.ddr3_sratio;
+       dxr2_ddr3_cmd_ctrl_data.cmd1iclkout = settings.ddr3.iclkout;
+       dxr2_ddr3_cmd_ctrl_data.cmd2csratio = settings.ddr3.ddr3_sratio;
+       dxr2_ddr3_cmd_ctrl_data.cmd2iclkout = settings.ddr3.iclkout;
+
+       config_ddr(DDR_PLL_FREQ, DXR2_IOCTRL_VAL, &dxr2_ddr3_data,
+                  &dxr2_ddr3_cmd_ctrl_data, &dxr2_ddr3_emif_reg_data, 0);
+}
+
+static void spl_siemens_board_init(void)
+{
+       return;
+}
+#endif /* if def CONFIG_SPL_BUILD */
+
+#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
+       (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
+static void cpsw_control(int enabled)
+{
+       /* VTP can be added here */
+
+       return;
+}
+
+static struct cpsw_slave_data cpsw_slaves[] = {
+       {
+               .slave_reg_ofs  = 0x208,
+               .sliver_reg_ofs = 0xd80,
+               .phy_id         = 0,
+               .phy_if         = PHY_INTERFACE_MODE_MII,
+       },
+};
+
+static struct cpsw_platform_data cpsw_data = {
+       .mdio_base              = CPSW_MDIO_BASE,
+       .cpsw_base              = CPSW_BASE,
+       .mdio_div               = 0xff,
+       .channels               = 4,
+       .cpdma_reg_ofs          = 0x800,
+       .slaves                 = 1,
+       .slave_data             = cpsw_slaves,
+       .ale_reg_ofs            = 0xd00,
+       .ale_entries            = 1024,
+       .host_port_reg_ofs      = 0x108,
+       .hw_stats_reg_ofs       = 0x900,
+       .bd_ram_ofs             = 0x2000,
+       .mac_control            = (1 << 5),
+       .control                = cpsw_control,
+       .host_port_num          = 0,
+       .version                = CPSW_CTRL_VERSION_2,
+};
+
+#if defined(CONFIG_DRIVER_TI_CPSW) || \
+       (defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET))
+int board_eth_init(bd_t *bis)
+{
+       struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
+       int n = 0;
+       int rv;
+
+       factoryset_setenv();
+
+       /* Set rgmii mode and enable rmii clock to be sourced from chip */
+       writel((RMII_MODE_ENABLE | RMII_CHIPCKL_ENABLE), &cdev->miisel);
+
+       rv = cpsw_register(&cpsw_data);
+       if (rv < 0)
+               printf("Error %d registering CPSW switch\n", rv);
+       else
+               n += rv;
+       return n;
+}
+#endif /* #if defined(CONFIG_DRIVER_TI_CPSW) */
+#endif /* #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) */
+
+#include "../common/board.c"
diff --git a/board/siemens/dxr2/board.h b/board/siemens/dxr2/board.h
new file mode 100644 (file)
index 0000000..2be78fb
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ * board.h
+ *
+ * (C) Copyright 2013 Siemens Schweiz AG
+ * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Based on:
+ * TI AM335x boards information header
+ * u-boot:/board/ti/am335x/board.h
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+#define PARGS3(x)      settings.ddr3.x-ddr3_default.x, \
+                       settings.ddr3.x, ddr3_default.x
+#define PRINTARGS(y)   printf("%x, %8x, %8x : "#y"\n", PARGS3(y))
+#define MAGIC_CHIP     0x50494843
+
+/* Automatic generated definition */
+/* Wed, 19 Jun 2013 10:57:48 +0200 */
+/* From file: draco/ddr3-data-micron.txt */
+struct ddr3_data {
+       unsigned int magic;                     /* 0x33524444 */
+       unsigned int version;                   /* 0x56312e33 */
+       unsigned short int ddr3_sratio;         /* 0x0100 */
+       unsigned short int iclkout;             /* 0x0001 */
+       unsigned short int dt0rdsratio0;        /* 0x003A */
+       unsigned short int dt0wdsratio0;        /* 0x008A */
+       unsigned short int dt0fwsratio0;        /* 0x010B */
+       unsigned short int dt0wrsratio0;        /* 0x00C4 */
+       unsigned int sdram_tim1;                /* 0x0888A39B */
+       unsigned int sdram_tim2;                /* 0x26247FDA */
+       unsigned int sdram_tim3;                /* 0x501F821F */
+       unsigned short int emif_ddr_phy_ctlr_1; /* 0x0006 */
+       unsigned int sdram_config;              /* 0x61C04AB2 */
+       unsigned int ref_ctrl;                  /* 0x00000618 */
+};
+
+struct chip_data {
+       unsigned int  magic;
+       char sdevname[16];
+       char shwver[7];
+};
+
+struct dxr2_baseboard_id {
+       struct ddr3_data ddr3;
+       struct chip_data chip;
+};
+
+/*
+ * We have three pin mux functions that must exist.  We must be able to enable
+ * uart0, for initial output and i2c0 to read the main EEPROM.  We then have a
+ * main pinmux function that can be overridden to enable all other pinmux that
+ * is required on the board.
+ */
+void enable_uart0_pin_mux(void);
+void enable_uart1_pin_mux(void);
+void enable_uart2_pin_mux(void);
+void enable_uart3_pin_mux(void);
+void enable_uart4_pin_mux(void);
+void enable_uart5_pin_mux(void);
+void enable_i2c0_pin_mux(void);
+void enable_board_pin_mux(void);
+#endif
diff --git a/board/siemens/dxr2/mux.c b/board/siemens/dxr2/mux.c
new file mode 100644 (file)
index 0000000..bc80b79
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * pinmux setup for siemens dxr2 board
+ *
+ * (C) Copyright 2013 Siemens Schweiz AG
+ * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Based on:
+ * u-boot:/board/ti/am335x/mux.c
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/mux.h>
+#include <asm/io.h>
+#include <i2c.h>
+#include "board.h"
+
+static struct module_pin_mux uart0_pin_mux[] = {
+       {OFFSET(uart0_rxd), (MODE(0) | PULLUP_EN | RXACTIVE)},  /* UART0_RXD */
+       {OFFSET(uart0_txd), (MODE(0) | PULLUDEN)},              /* UART0_TXD */
+       {-1},
+};
+
+static struct module_pin_mux uart3_pin_mux[] = {
+       {OFFSET(spi0_cs1), (MODE(1) | PULLUP_EN | RXACTIVE)},   /* UART3_RXD */
+       {OFFSET(ecap0_in_pwm0_out), (MODE(1) | PULLUDEN)},      /* UART3_TXD */
+       {-1},
+};
+
+static struct module_pin_mux i2c0_pin_mux[] = {
+       {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE |
+                       PULLUDEN | SLEWCTRL)}, /* I2C_DATA */
+       {OFFSET(i2c0_scl), (MODE(0) | RXACTIVE |
+                       PULLUDEN | SLEWCTRL)}, /* I2C_SCLK */
+       {-1},
+};
+
+static struct module_pin_mux nand_pin_mux[] = {
+       {OFFSET(gpmc_ad0), (MODE(0) | PULLUP_EN | RXACTIVE)},   /* NAND AD0 */
+       {OFFSET(gpmc_ad1), (MODE(0) | PULLUP_EN | RXACTIVE)},   /* NAND AD1 */
+       {OFFSET(gpmc_ad2), (MODE(0) | PULLUP_EN | RXACTIVE)},   /* NAND AD2 */
+       {OFFSET(gpmc_ad3), (MODE(0) | PULLUP_EN | RXACTIVE)},   /* NAND AD3 */
+       {OFFSET(gpmc_ad4), (MODE(0) | PULLUP_EN | RXACTIVE)},   /* NAND AD4 */
+       {OFFSET(gpmc_ad5), (MODE(0) | PULLUP_EN | RXACTIVE)},   /* NAND AD5 */
+       {OFFSET(gpmc_ad6), (MODE(0) | PULLUP_EN | RXACTIVE)},   /* NAND AD6 */
+       {OFFSET(gpmc_ad7), (MODE(0) | PULLUP_EN | RXACTIVE)},   /* NAND AD7 */
+       {OFFSET(gpmc_wait0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* NAND WAIT */
+       {OFFSET(gpmc_wpn), (MODE(7) | PULLUP_EN | RXACTIVE)},   /* NAND_WPN */
+       {OFFSET(gpmc_csn0), (MODE(0) | PULLUDEN)},      /* NAND_CS0 */
+       {OFFSET(gpmc_advn_ale), (MODE(0) | PULLUDEN)}, /* NAND_ADV_ALE */
+       {OFFSET(gpmc_oen_ren), (MODE(0) | PULLUDEN)},   /* NAND_OE */
+       {OFFSET(gpmc_wen), (MODE(0) | PULLUDEN)},       /* NAND_WEN */
+       {OFFSET(gpmc_be0n_cle), (MODE(0) | PULLUDEN)},  /* NAND_BE_CLE */
+       {-1},
+};
+
+static struct module_pin_mux gpios_pin_mux[] = {
+       /* DFU button GPIO0_27*/
+       {OFFSET(gpmc_ad11), (MODE(7) | PULLUDEN | RXACTIVE)},
+       {OFFSET(gpmc_csn3), MODE(7) },                  /* LED0 GPIO2_0 */
+       {OFFSET(emu0), MODE(7)},                        /* LED1 GPIO3_7 */
+       {-1},
+};
+
+static struct module_pin_mux ethernet_pin_mux[] = {
+       {OFFSET(mii1_col), (MODE(3) | RXACTIVE)},
+       {OFFSET(mii1_crs), (MODE(1) | RXACTIVE)},
+       {OFFSET(mii1_rxerr), (MODE(1) | RXACTIVE)},
+       {OFFSET(mii1_txen), (MODE(1))},
+       {OFFSET(mii1_rxdv), (MODE(3) | RXACTIVE)},
+       {OFFSET(mii1_txd3), (MODE(7) | RXACTIVE)},
+       {OFFSET(mii1_txd2), (MODE(7) | RXACTIVE)},
+       {OFFSET(mii1_txd1), (MODE(1))},
+       {OFFSET(mii1_txd0), (MODE(1))},
+       {OFFSET(mii1_txclk), (MODE(1) | RXACTIVE)},
+       {OFFSET(mii1_rxclk), (MODE(1) | RXACTIVE)},
+       {OFFSET(mii1_rxd3), (MODE(1) | RXACTIVE)},
+       {OFFSET(mii1_rxd2), (MODE(1))},
+       {OFFSET(mii1_rxd1), (MODE(1) | RXACTIVE)},
+       {OFFSET(mii1_rxd0), (MODE(1) | RXACTIVE)},
+       {OFFSET(rmii1_refclk), (MODE(0) | RXACTIVE)},
+       {OFFSET(mdio_data), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(mdio_clk), (MODE(0) | PULLUP_EN)},
+       {-1},
+};
+
+void enable_uart0_pin_mux(void)
+{
+       configure_module_pin_mux(uart0_pin_mux);
+}
+
+void enable_uart3_pin_mux(void)
+{
+       configure_module_pin_mux(uart3_pin_mux);
+}
+
+void enable_i2c0_pin_mux(void)
+{
+       configure_module_pin_mux(i2c0_pin_mux);
+}
+
+void enable_board_pin_mux(void)
+{
+       enable_uart3_pin_mux();
+       configure_module_pin_mux(nand_pin_mux);
+       configure_module_pin_mux(ethernet_pin_mux);
+       configure_module_pin_mux(gpios_pin_mux);
+}
diff --git a/board/siemens/pxm2/Makefile b/board/siemens/pxm2/Makefile
new file mode 100644 (file)
index 0000000..a09b467
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# Makefile
+#
+# (C) Copyright 2013 Siemens Schweiz AG
+# (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+#
+# Based on:
+# u-boot:/board/ti/am335x/Makefile
+# Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)../common)
+endif
+
+LIB    = $(obj)lib$(BOARD).o
+
+ifdef CONFIG_SPL_BUILD
+COBJS  := mux.o
+endif
+
+COBJS  += board.o
+ifndef CONFIG_SPL_BUILD
+COBJS += ../common/factoryset.o
+endif
+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))
+
+clean:
+       rm -f $(SOBJS) $(OBJS)
+
+distclean:     clean
+       rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/siemens/pxm2/board.c b/board/siemens/pxm2/board.c
new file mode 100644 (file)
index 0000000..2c1841f
--- /dev/null
@@ -0,0 +1,429 @@
+/*
+ * Board functions for TI AM335X based pxm2 board
+ * (C) Copyright 2013 Siemens Schweiz AG
+ * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Based on:
+ * u-boot:/board/ti/am335x/board.c
+ *
+ * Board functions for TI AM335X based boards
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <spl.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/omap.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/mmc_host_def.h>
+#include <asm/arch/sys_proto.h>
+#include "../../../drivers/video/da8xx-fb.h"
+#include <asm/io.h>
+#include <asm/emif.h>
+#include <asm/gpio.h>
+#include <i2c.h>
+#include <miiphy.h>
+#include <cpsw.h>
+#include <watchdog.h>
+#include "board.h"
+#include "../common/factoryset.h"
+#include "pmic.h"
+#include <nand.h>
+#include <bmp_layout.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_SPL_BUILD
+static void board_init_ddr(void)
+{
+struct emif_regs pxm2_ddr3_emif_reg_data = {
+       .sdram_config = 0x41805332,
+       .sdram_tim1 = 0x666b3c9,
+       .sdram_tim2 = 0x243631ca,
+       .sdram_tim3 = 0x33f,
+       .emif_ddr_phy_ctlr_1 = 0x100005,
+       .zq_config = 0,
+       .ref_ctrl = 0x81a,
+};
+
+struct ddr_data pxm2_ddr3_data = {
+       .datardsratio0 = 0x81204812,
+       .datawdsratio0 = 0,
+       .datafwsratio0 = 0x8020080,
+       .datawrsratio0 = 0x4010040,
+       .datauserank0delay = 1,
+       .datadldiff0 = PHY_DLL_LOCK_DIFF,
+};
+
+struct cmd_control pxm2_ddr3_cmd_ctrl_data = {
+       .cmd0csratio = 0x80,
+       .cmd0dldiff = 0,
+       .cmd0iclkout = 0,
+       .cmd1csratio = 0x80,
+       .cmd1dldiff = 0,
+       .cmd1iclkout = 0,
+       .cmd2csratio = 0x80,
+       .cmd2dldiff = 0,
+       .cmd2iclkout = 0,
+};
+
+       config_ddr(DDR_PLL_FREQ, DXR2_IOCTRL_VAL, &pxm2_ddr3_data,
+                  &pxm2_ddr3_cmd_ctrl_data, &pxm2_ddr3_emif_reg_data, 0);
+}
+
+/*
+ * voltage switching for MPU frequency switching.
+ * @module = mpu - 0, core - 1
+ * @vddx_op_vol_sel = vdd voltage to set
+ */
+
+#define MPU    0
+#define CORE   1
+
+int voltage_update(unsigned int module, unsigned char vddx_op_vol_sel)
+{
+       uchar buf[4];
+       unsigned int reg_offset;
+
+       if (module == MPU)
+               reg_offset = PMIC_VDD1_OP_REG;
+       else
+               reg_offset = PMIC_VDD2_OP_REG;
+
+       /* Select VDDx OP   */
+       if (i2c_read(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1))
+               return 1;
+
+       buf[0] &= ~PMIC_OP_REG_CMD_MASK;
+
+       if (i2c_write(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1))
+               return 1;
+
+       /* Configure VDDx OP  Voltage */
+       if (i2c_read(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1))
+               return 1;
+
+       buf[0] &= ~PMIC_OP_REG_SEL_MASK;
+       buf[0] |= vddx_op_vol_sel;
+
+       if (i2c_write(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1))
+               return 1;
+
+       if (i2c_read(PMIC_CTRL_I2C_ADDR, reg_offset, 1, buf, 1))
+               return 1;
+
+       if ((buf[0] & PMIC_OP_REG_SEL_MASK) != vddx_op_vol_sel)
+               return 1;
+
+       return 0;
+}
+
+#define OSC     (V_OSCK/1000000)
+
+const struct dpll_params dpll_mpu_pxm2 = {
+               720, OSC-1, 1, -1, -1, -1, -1};
+
+void spl_siemens_board_init(void)
+{
+       uchar buf[4];
+       /*
+        * pxm2 PMIC code.  All boards currently want an MPU voltage
+        * of 1.2625V and CORE voltage of 1.1375V to operate at
+        * 720MHz.
+        */
+       if (i2c_probe(PMIC_CTRL_I2C_ADDR))
+               return;
+
+       /* VDD1/2 voltage selection register access by control i/f */
+       if (i2c_read(PMIC_CTRL_I2C_ADDR, PMIC_DEVCTRL_REG, 1, buf, 1))
+               return;
+
+       buf[0] |= PMIC_DEVCTRL_REG_SR_CTL_I2C_SEL_CTL_I2C;
+
+       if (i2c_write(PMIC_CTRL_I2C_ADDR, PMIC_DEVCTRL_REG, 1, buf, 1))
+               return;
+
+       /* Frequency switching for OPP 120 */
+       if (voltage_update(MPU, PMIC_OP_REG_SEL_1_2_6) ||
+           voltage_update(CORE, PMIC_OP_REG_SEL_1_1_3)) {
+               printf("voltage update failed\n");
+       }
+}
+#endif /* if def CONFIG_SPL_BUILD */
+
+int read_eeprom(void)
+{
+       /* nothing ToDo here for this board */
+
+       return 0;
+}
+
+#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
+       (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
+static void cpsw_control(int enabled)
+{
+       /* VTP can be added here */
+
+       return;
+}
+
+static struct cpsw_slave_data cpsw_slaves[] = {
+       {
+               .slave_reg_ofs  = 0x208,
+               .sliver_reg_ofs = 0xd80,
+               .phy_id         = 0,
+               .phy_if         = PHY_INTERFACE_MODE_RMII,
+       },
+       {
+               .slave_reg_ofs  = 0x308,
+               .sliver_reg_ofs = 0xdc0,
+               .phy_id         = 1,
+               .phy_if         = PHY_INTERFACE_MODE_RMII,
+       },
+};
+
+static struct cpsw_platform_data cpsw_data = {
+       .mdio_base              = CPSW_MDIO_BASE,
+       .cpsw_base              = CPSW_BASE,
+       .mdio_div               = 0xff,
+       .channels               = 4,
+       .cpdma_reg_ofs          = 0x800,
+       .slaves                 = 1,
+       .slave_data             = cpsw_slaves,
+       .ale_reg_ofs            = 0xd00,
+       .ale_entries            = 1024,
+       .host_port_reg_ofs      = 0x108,
+       .hw_stats_reg_ofs       = 0x900,
+       .bd_ram_ofs             = 0x2000,
+       .mac_control            = (1 << 5),
+       .control                = cpsw_control,
+       .host_port_num          = 0,
+       .version                = CPSW_CTRL_VERSION_2,
+};
+#endif /* #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) */
+
+#if defined(CONFIG_DRIVER_TI_CPSW) || \
+       (defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET))
+int board_eth_init(bd_t *bis)
+{
+       int n = 0;
+#if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) || \
+       (defined(CONFIG_SPL_ETH_SUPPORT) && defined(CONFIG_SPL_BUILD))
+       struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
+#ifdef CONFIG_FACTORYSET
+       int rv;
+       if (!is_valid_ether_addr(factory_dat.mac))
+               printf("Error: no valid mac address\n");
+       else
+               eth_setenv_enetaddr("ethaddr", factory_dat.mac);
+#endif /* #ifdef CONFIG_FACTORYSET */
+
+       /* Set rgmii mode and enable rmii clock to be sourced from chip */
+       writel(RGMII_MODE_ENABLE , &cdev->miisel);
+
+       rv = cpsw_register(&cpsw_data);
+       if (rv < 0)
+               printf("Error %d registering CPSW switch\n", rv);
+       else
+               n += rv;
+#endif
+       return n;
+}
+#endif /* #if defined(CONFIG_DRIVER_TI_CPSW) */
+
+#if defined(CONFIG_VIDEO) && !defined(CONFIG_SPL_BUILD)
+static struct da8xx_panel lcd_panels[] = {
+       /* AUO G156XW01 V1 */
+       [0] = {
+               .name = "AUO_G156XW01_V1",
+               .width = 1376,
+               .height = 768,
+               .hfp = 14,
+               .hbp = 64,
+               .hsw = 56,
+               .vfp = 1,
+               .vbp = 28,
+               .vsw = 3,
+               .pxl_clk = 60000000,
+               .invert_pxl_clk = 0,
+       },
+       /* AUO B101EVN06 V0 */
+       [1] = {
+               .name = "AUO_B101EVN06_V0",
+               .width = 1280,
+               .height = 800,
+               .hfp = 52,
+               .hbp = 84,
+               .hsw = 36,
+               .vfp = 3,
+               .vbp = 14,
+               .vsw = 6,
+               .pxl_clk = 60000000,
+               .invert_pxl_clk = 0,
+       },
+       /*
+        * Settings from factoryset
+        * stored in EEPROM
+        */
+       [2] = {
+               .name = "factoryset",
+               .width = 0,
+               .height = 0,
+               .hfp = 0,
+               .hbp = 0,
+               .hsw = 0,
+               .vfp = 0,
+               .vbp = 0,
+               .vsw = 0,
+               .pxl_clk = 60000000,
+               .invert_pxl_clk = 0,
+       },
+};
+
+static const struct display_panel disp_panel = {
+       WVGA,
+       32,
+       16,
+       COLOR_ACTIVE,
+};
+
+static const struct lcd_ctrl_config lcd_cfg = {
+       &disp_panel,
+       .ac_bias                = 255,
+       .ac_bias_intrpt         = 0,
+       .dma_burst_sz           = 16,
+       .bpp                    = 32,
+       .fdd                    = 0x80,
+       .tft_alt_mode           = 0,
+       .stn_565_mode           = 0,
+       .mono_8bit_mode         = 0,
+       .invert_line_clock      = 1,
+       .invert_frm_clock       = 1,
+       .sync_edge              = 0,
+       .sync_ctrl              = 1,
+       .raster_order           = 0,
+};
+
+static int set_gpio(int gpio, int state)
+{
+       gpio_request(gpio, "temp");
+       gpio_direction_output(gpio, state);
+       gpio_set_value(gpio, state);
+       gpio_free(gpio);
+       return 0;
+}
+
+static int enable_backlight(void)
+{
+       set_gpio(BOARD_LCD_POWER, 1);
+       set_gpio(BOARD_BACK_LIGHT, 1);
+       set_gpio(BOARD_TOUCH_POWER, 1);
+       return 0;
+}
+
+static int enable_pwm(void)
+{
+       struct pwmss_regs *pwmss = (struct pwmss_regs *)PWMSS0_BASE;
+       struct pwmss_ecap_regs *ecap;
+       int ticks = PWM_TICKS;
+       int duty = PWM_DUTY;
+
+       ecap = (struct pwmss_ecap_regs *)AM33XX_ECAP0_BASE;
+       /* enable clock */
+       setbits_le32(&pwmss->clkconfig, ECAP_CLK_EN);
+       /* TimeStam Counter register */
+       writel(0xdb9, &ecap->tsctr);
+       /* config period */
+       writel(ticks - 1, &ecap->cap3);
+       writel(ticks - 1, &ecap->cap1);
+       setbits_le16(&ecap->ecctl2,
+                    (ECTRL2_MDSL_ECAP | ECTRL2_SYNCOSEL_MASK | 0xd0));
+       /* config duty */
+       writel(duty, &ecap->cap2);
+       writel(duty, &ecap->cap4);
+       /* start */
+       setbits_le16(&ecap->ecctl2, ECTRL2_CTRSTP_FREERUN);
+       return 0;
+}
+
+static struct dpll_regs dpll_lcd_regs = {
+       .cm_clkmode_dpll = CM_WKUP + 0x98,
+       .cm_idlest_dpll = CM_WKUP + 0x48,
+       .cm_clksel_dpll = CM_WKUP + 0x54,
+};
+
+/* no console on this board */
+int board_cfb_skip(void)
+{
+       return 1;
+}
+
+#define PLL_GET_M(v) ((v >> 8) & 0x7ff)
+#define PLL_GET_N(v) (v & 0x7f)
+
+static int get_clk(struct dpll_regs *dpll_regs)
+{
+       unsigned int val;
+       unsigned int m, n;
+       int f = 0;
+
+       val = readl(dpll_regs->cm_clksel_dpll);
+       m = PLL_GET_M(val);
+       n = PLL_GET_N(val);
+       f = (m * V_OSCK) / n;
+
+       return f;
+};
+
+int clk_get(int clk)
+{
+       return get_clk(&dpll_lcd_regs);
+};
+
+static int conf_disp_pll(int m, int n)
+{
+       struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
+       struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL;
+       struct dpll_params dpll_lcd = {m, n, -1, -1, -1, -1, -1};
+
+       u32 *const clk_domains[] = {
+               &cmper->lcdclkctrl,
+               0
+       };
+       u32 *const clk_modules_explicit_en[] = {
+               &cmper->lcdclkctrl,
+               &cmper->lcdcclkstctrl,
+               &cmper->epwmss0clkctrl,
+               0
+       };
+       do_enable_clocks(clk_domains, clk_modules_explicit_en, 1);
+       writel(0x0, &cmdpll->clklcdcpixelclk);
+
+       do_setup_dpll(&dpll_lcd_regs, &dpll_lcd);
+
+       return 0;
+}
+
+static int board_video_init(void)
+{
+       /* set 300 MHz */
+       conf_disp_pll(25, 2);
+       if (factory_dat.pxm50)
+               da8xx_video_init(&lcd_panels[0], &lcd_cfg, lcd_cfg.bpp);
+       else
+               da8xx_video_init(&lcd_panels[1], &lcd_cfg, lcd_cfg.bpp);
+
+       enable_pwm();
+       enable_backlight();
+
+       return 0;
+}
+#endif
+#include "../common/board.c"
diff --git a/board/siemens/pxm2/board.h b/board/siemens/pxm2/board.h
new file mode 100644 (file)
index 0000000..0362612
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * board.h
+ *
+ * (C) Copyright 2013 Siemens Schweiz AG
+ * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Based on:
+ * TI AM335x boards information header
+ * u-boot:/board/ti/am335x/board.h
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+void enable_uart0_pin_mux(void);
+void enable_i2c0_pin_mux(void);
+void enable_board_pin_mux(void);
+#endif
diff --git a/board/siemens/pxm2/mux.c b/board/siemens/pxm2/mux.c
new file mode 100644 (file)
index 0000000..c64b0d2
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ * pinmux setup for siemens pxm2 board
+ *
+ * (C) Copyright 2013 Siemens Schweiz AG
+ * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Based on:
+ * u-boot:/board/ti/am335x/mux.c
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/mux.h>
+#include <asm/io.h>
+#include <i2c.h>
+#include "board.h"
+
+static struct module_pin_mux uart0_pin_mux[] = {
+       {OFFSET(uart0_rxd), (MODE(0) | PULLUP_EN | RXACTIVE)},  /* UART0_RXD */
+       {OFFSET(uart0_txd), (MODE(0) | PULLUDEN)},              /* UART0_TXD */
+       {OFFSET(nnmi), (MODE(0) | PULLUP_EN | RXACTIVE)},       /* UART0_TXD */
+       {-1},
+};
+
+#ifdef CONFIG_NAND
+static struct module_pin_mux nand_pin_mux[] = {
+       {OFFSET(gpmc_ad0), (MODE(0) | PULLUP_EN | RXACTIVE)},   /* NAND AD0 */
+       {OFFSET(gpmc_ad1), (MODE(0) | PULLUP_EN | RXACTIVE)},   /* NAND AD1 */
+       {OFFSET(gpmc_ad2), (MODE(0) | PULLUP_EN | RXACTIVE)},   /* NAND AD2 */
+       {OFFSET(gpmc_ad3), (MODE(0) | PULLUP_EN | RXACTIVE)},   /* NAND AD3 */
+       {OFFSET(gpmc_ad4), (MODE(0) | PULLUP_EN | RXACTIVE)},   /* NAND AD4 */
+       {OFFSET(gpmc_ad5), (MODE(0) | PULLUP_EN | RXACTIVE)},   /* NAND AD5 */
+       {OFFSET(gpmc_ad6), (MODE(0) | PULLUP_EN | RXACTIVE)},   /* NAND AD6 */
+       {OFFSET(gpmc_ad7), (MODE(0) | PULLUP_EN | RXACTIVE)},   /* NAND AD7 */
+       {OFFSET(gpmc_wait0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* NAND WAIT */
+       {OFFSET(gpmc_wpn), (MODE(7) | PULLUP_EN | RXACTIVE)},   /* NAND_WPN */
+       {OFFSET(gpmc_csn0), (MODE(0) | PULLUDEN)},      /* NAND_CS0 */
+       {OFFSET(gpmc_advn_ale), (MODE(0) | PULLUDEN)},  /* NAND_ADV_ALE */
+       {OFFSET(gpmc_oen_ren), (MODE(0) | PULLUDEN)},   /* NAND_OE */
+       {OFFSET(gpmc_wen), (MODE(0) | PULLUDEN)},       /* NAND_WEN */
+       {OFFSET(gpmc_be0n_cle), (MODE(0) | PULLUDEN)},  /* NAND_BE_CLE */
+       {OFFSET(gpmc_a11), MODE(7) | RXACTIVE | PULLUP_EN}, /* RGMII2_RD0 */
+       {OFFSET(mcasp0_ahclkx), MODE(7) | PULLUDEN},    /* MCASP0_AHCLKX */
+       {-1},
+};
+#endif
+
+static struct module_pin_mux i2c0_pin_mux[] = {
+       {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE | PULLUDEN | SLEWCTRL)},
+       {OFFSET(i2c0_scl), (MODE(0) | RXACTIVE | PULLUDEN | SLEWCTRL)},
+       {-1},
+};
+
+static struct module_pin_mux i2c1_pin_mux[] = {
+       {OFFSET(spi0_d1), (MODE(2) | RXACTIVE | PULLUDEN | SLEWCTRL)},
+       {OFFSET(spi0_cs0), (MODE(2) | RXACTIVE | PULLUDEN | SLEWCTRL)},
+       {-1},
+};
+
+#ifndef CONFIG_NO_ETH
+static struct module_pin_mux rgmii1_pin_mux[] = {
+       {OFFSET(mii1_txen), MODE(2)},                   /* RGMII1_TCTL */
+       {OFFSET(mii1_rxdv), MODE(2) | RXACTIVE},        /* RGMII1_RCTL */
+       {OFFSET(mii1_txd3), MODE(2)},                   /* RGMII1_TD3 */
+       {OFFSET(mii1_txd2), MODE(2)},                   /* RGMII1_TD2 */
+       {OFFSET(mii1_txd1), MODE(2)},                   /* RGMII1_TD1 */
+       {OFFSET(mii1_txd0), MODE(2)},                   /* RGMII1_TD0 */
+       {OFFSET(mii1_txclk), MODE(2)},                  /* RGMII1_TCLK */
+       {OFFSET(mii1_rxclk), MODE(2) | RXACTIVE},       /* RGMII1_RCLK */
+       {OFFSET(mii1_rxd3), MODE(2) | RXACTIVE},        /* RGMII1_RD3 */
+       {OFFSET(mii1_rxd2), MODE(2) | RXACTIVE},        /* RGMII1_RD2 */
+       {OFFSET(mii1_rxd1), MODE(2) | RXACTIVE},        /* RGMII1_RD1 */
+       {OFFSET(mii1_rxd0), MODE(2) | RXACTIVE},        /* RGMII1_RD0 */
+       {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */
+       {OFFSET(mdio_clk), MODE(0) | PULLUP_EN},        /* MDIO_CLK */
+       {-1},
+};
+
+static struct module_pin_mux rgmii2_pin_mux[] = {
+       {OFFSET(gpmc_a0), MODE(2)},                     /* RGMII2_TCTL */
+       {OFFSET(gpmc_a1), MODE(2) | RXACTIVE},          /* RGMII2_RCTL */
+       {OFFSET(gpmc_a2), MODE(2)},                     /* RGMII2_TD3 */
+       {OFFSET(gpmc_a3), MODE(2)},                     /* RGMII2_TD2 */
+       {OFFSET(gpmc_a4), MODE(2)},                     /* RGMII2_TD1 */
+       {OFFSET(gpmc_a5), MODE(2)},                     /* RGMII2_TD0 */
+       {OFFSET(gpmc_a6), MODE(7)},                     /* RGMII2_TCLK */
+       {OFFSET(gpmc_a7), MODE(2) | RXACTIVE},          /* RGMII2_RCLK */
+       {OFFSET(gpmc_a8), MODE(2) | RXACTIVE},          /* RGMII2_RD3 */
+       {OFFSET(gpmc_a9), MODE(7)},                     /* RGMII2_RD2 */
+       {OFFSET(gpmc_a10), MODE(2) | RXACTIVE},         /* RGMII2_RD1 */
+       {OFFSET(mdio_data), MODE(0) | RXACTIVE | PULLUP_EN}, /* MDIO_DATA */
+       {OFFSET(mdio_clk), MODE(0) | PULLUP_EN},        /* MDIO_CLK */
+       {-1},
+};
+#endif
+
+#ifdef CONFIG_MMC
+static struct module_pin_mux mmc0_pin_mux[] = {
+       {OFFSET(mmc0_dat3), (MODE(0) | RXACTIVE | PULLUP_EN)},  /* MMC0_DAT3 */
+       {OFFSET(mmc0_dat2), (MODE(0) | RXACTIVE | PULLUP_EN)},  /* MMC0_DAT2 */
+       {OFFSET(mmc0_dat1), (MODE(0) | RXACTIVE | PULLUP_EN)},  /* MMC0_DAT1 */
+       {OFFSET(mmc0_dat0), (MODE(0) | RXACTIVE | PULLUP_EN)},  /* MMC0_DAT0 */
+       {OFFSET(mmc0_clk), (MODE(0) | RXACTIVE | PULLUP_EN)},   /* MMC0_CLK */
+       {OFFSET(mmc0_cmd), (MODE(0) | RXACTIVE | PULLUP_EN)},   /* MMC0_CMD */
+       {OFFSET(mcasp0_aclkr), (MODE(4) | RXACTIVE)},           /* MMC0_WP */
+       {OFFSET(spi0_cs1), (MODE(5) | RXACTIVE | PULLUDEN)},    /* MMC0_CD */
+       {-1},
+};
+#endif
+
+static struct module_pin_mux lcdc_pin_mux[] = {
+       {OFFSET(lcd_data0), (MODE(0) | PULLUDDIS)},     /* LCD_DAT0 */
+       {OFFSET(lcd_data1), (MODE(0) | PULLUDDIS)},     /* LCD_DAT1 */
+       {OFFSET(lcd_data2), (MODE(0) | PULLUDDIS)},     /* LCD_DAT2 */
+       {OFFSET(lcd_data3), (MODE(0) | PULLUDDIS)},     /* LCD_DAT3 */
+       {OFFSET(lcd_data4), (MODE(0) | PULLUDDIS)},     /* LCD_DAT4 */
+       {OFFSET(lcd_data5), (MODE(0) | PULLUDDIS)},     /* LCD_DAT5 */
+       {OFFSET(lcd_data6), (MODE(0) | PULLUDDIS)},     /* LCD_DAT6 */
+       {OFFSET(lcd_data7), (MODE(0) | PULLUDDIS)},     /* LCD_DAT7 */
+       {OFFSET(lcd_data8), (MODE(0) | PULLUDDIS)},     /* LCD_DAT8 */
+       {OFFSET(lcd_data9), (MODE(0) | PULLUDDIS)},     /* LCD_DAT9 */
+       {OFFSET(lcd_data10), (MODE(0) | PULLUDDIS)},    /* LCD_DAT10 */
+       {OFFSET(lcd_data11), (MODE(0) | PULLUDDIS)},    /* LCD_DAT11 */
+       {OFFSET(lcd_data12), (MODE(0) | PULLUDDIS)},    /* LCD_DAT12 */
+       {OFFSET(lcd_data13), (MODE(0) | PULLUDDIS)},    /* LCD_DAT13 */
+       {OFFSET(lcd_data14), (MODE(0) | PULLUDDIS)},    /* LCD_DAT14 */
+       {OFFSET(lcd_data15), (MODE(0) | PULLUDDIS)},    /* LCD_DAT15 */
+       {OFFSET(gpmc_ad8), (MODE(1))},                  /* LCD_DAT16 */
+       {OFFSET(gpmc_ad9), (MODE(1))},          /* LCD_DAT17 */
+       {OFFSET(gpmc_ad10), (MODE(1))},         /* LCD_DAT18 */
+       {OFFSET(gpmc_ad11), (MODE(1))},         /* LCD_DAT19 */
+       {OFFSET(gpmc_ad12), (MODE(1))},         /* LCD_DAT20 */
+       {OFFSET(gpmc_ad13), (MODE(1))},         /* LCD_DAT21 */
+       {OFFSET(gpmc_ad14), (MODE(1))},         /* LCD_DAT22 */
+       {OFFSET(gpmc_ad15), (MODE(1))},         /* LCD_DAT23 */
+       {OFFSET(lcd_vsync), (MODE(0))},         /* LCD_VSYNC */
+       {OFFSET(lcd_hsync), (MODE(0))},         /* LCD_HSYNC */
+       {OFFSET(lcd_pclk), (MODE(0))},          /* LCD_PCLK */
+       {OFFSET(lcd_ac_bias_en), (MODE(0))},    /* LCD_AC_BIAS_EN */
+       {-1},
+};
+
+static struct module_pin_mux ecap0_pin_mux[] = {
+       {OFFSET(ecap0_in_pwm0_out), (MODE(0))},
+       {-1},
+};
+
+static struct module_pin_mux gpio_pin_mux[] = {
+       {OFFSET(mcasp0_fsx), MODE(7)}, /* GPIO3_15 LCD power*/
+       {OFFSET(mcasp0_axr0), MODE(7)}, /* GPIO3_16 Backlight */
+       {OFFSET(gpmc_a9), MODE(7)}, /* GPIO1_25 Touch power */
+       {-1},
+};
+void enable_i2c0_pin_mux(void)
+{
+       configure_module_pin_mux(i2c0_pin_mux);
+}
+
+void enable_uart0_pin_mux(void)
+{
+       configure_module_pin_mux(uart0_pin_mux);
+}
+
+void enable_board_pin_mux(void)
+{
+       configure_module_pin_mux(uart0_pin_mux);
+       configure_module_pin_mux(i2c1_pin_mux);
+#ifdef CONFIG_NAND
+       configure_module_pin_mux(nand_pin_mux);
+#endif
+#ifndef CONFIG_NO_ETH
+       configure_module_pin_mux(rgmii1_pin_mux);
+       configure_module_pin_mux(rgmii2_pin_mux);
+#endif
+#ifdef CONFIG_MMC
+       configure_module_pin_mux(mmc0_pin_mux);
+#endif
+       configure_module_pin_mux(lcdc_pin_mux);
+       configure_module_pin_mux(gpio_pin_mux);
+       configure_module_pin_mux(ecap0_pin_mux);
+}
diff --git a/board/siemens/pxm2/pmic.h b/board/siemens/pxm2/pmic.h
new file mode 100644 (file)
index 0000000..c6347e5
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * (C) Copyright 2013 Siemens Schweiz AG
+ * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Based on:
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#ifndef PMIC_H
+#define PMIC_H
+
+/*
+ * The PMIC on this board is a TPS65910.
+ */
+
+#define PMIC_SR_I2C_ADDR               0x12
+#define PMIC_CTRL_I2C_ADDR             0x2D
+/* PMIC Register offsets */
+#define PMIC_VDD1_REG                  0x21
+#define PMIC_VDD1_OP_REG               0x22
+#define PMIC_VDD2_REG                  0x24
+#define PMIC_VDD2_OP_REG               0x25
+#define PMIC_DEVCTRL_REG               0x3f
+
+/* VDD2 & VDD1 control register (VDD2_REG & VDD1_REG) */
+#define PMIC_VGAIN_SEL_MASK            (0x3 << 6)
+#define PMIC_ILMAX_MASK                        (0x1 << 5)
+#define PMIC_TSTEP_MASK                        (0x7 << 2)
+#define PMIC_ST_MASK                   (0x3)
+
+#define PMIC_REG_VGAIN_SEL_X1          (0x0 << 6)
+#define PMIC_REG_VGAIN_SEL_X1_0                (0x1 << 6)
+#define PMIC_REG_VGAIN_SEL_X3          (0x2 << 6)
+#define PMIC_REG_VGAIN_SEL_X4          (0x3 << 6)
+
+#define PMIC_REG_ILMAX_1_0_A           (0x0 << 5)
+#define PMIC_REG_ILMAX_1_5_A           (0x1 << 5)
+
+#define PMIC_REG_TSTEP_                        (0x0 << 2)
+#define PMIC_REG_TSTEP_12_5            (0x1 << 2)
+#define PMIC_REG_TSTEP_9_4             (0x2 << 2)
+#define PMIC_REG_TSTEP_7_5             (0x3 << 2)
+#define PMIC_REG_TSTEP_6_25            (0x4 << 2)
+#define PMIC_REG_TSTEP_4_7             (0x5 << 2)
+#define PMIC_REG_TSTEP_3_12            (0x6 << 2)
+#define PMIC_REG_TSTEP_2_5             (0x7 << 2)
+
+#define PMIC_REG_ST_OFF                        (0x0)
+#define PMIC_REG_ST_ON_HI_POW          (0x1)
+#define PMIC_REG_ST_OFF_1              (0x2)
+#define PMIC_REG_ST_ON_LOW_POW         (0x3)
+
+
+/* VDD2 & VDD1 voltage selection register. (VDD2_OP_REG & VDD1_OP_REG) */
+#define PMIC_OP_REG_SEL                                (0x7F)
+
+#define PMIC_OP_REG_CMD_MASK                   (0x1 << 7)
+#define PMIC_OP_REG_CMD_OP                     (0x0 << 7)
+#define PMIC_OP_REG_CMD_SR                     (0x1 << 7)
+
+#define PMIC_OP_REG_SEL_MASK                   (0x7F)
+#define PMIC_OP_REG_SEL_1_1_3                  (0x2E)  /* 1.1375 V */
+#define PMIC_OP_REG_SEL_1_2_6                  (0x38)  /* 1.2625 V */
+
+/* Device control register . (DEVCTRL_REG) */
+#define PMIC_DEVCTRL_REG_SR_CTL_I2C_MASK       (0x1 << 4)
+#define PMIC_DEVCTRL_REG_SR_CTL_I2C_SEL_SR_I2C (0x0 << 4)
+#define PMIC_DEVCTRL_REG_SR_CTL_I2C_SEL_CTL_I2C        (0x1 << 4)
+
+#endif
diff --git a/board/siemens/rut/Makefile b/board/siemens/rut/Makefile
new file mode 100644 (file)
index 0000000..a09b467
--- /dev/null
@@ -0,0 +1,49 @@
+#
+# Makefile
+#
+# (C) Copyright 2013 Siemens Schweiz AG
+# (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+#
+# Based on:
+# u-boot:/board/ti/am335x/Makefile
+# Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+include $(TOPDIR)/config.mk
+ifneq ($(OBJTREE),$(SRCTREE))
+$(shell mkdir -p $(obj)../common)
+endif
+
+LIB    = $(obj)lib$(BOARD).o
+
+ifdef CONFIG_SPL_BUILD
+COBJS  := mux.o
+endif
+
+COBJS  += board.o
+ifndef CONFIG_SPL_BUILD
+COBJS += ../common/factoryset.o
+endif
+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))
+
+clean:
+       rm -f $(SOBJS) $(OBJS)
+
+distclean:     clean
+       rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/siemens/rut/board.c b/board/siemens/rut/board.c
new file mode 100644 (file)
index 0000000..f2b0476
--- /dev/null
@@ -0,0 +1,432 @@
+/*
+ * Board functions for TI AM335X based rut board
+ * (C) Copyright 2013 Siemens Schweiz AG
+ * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Based on:
+ * u-boot:/board/ti/am335x/board.c
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <spi.h>
+#include <spl.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/omap.h>
+#include <asm/arch/ddr_defs.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/mmc_host_def.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/io.h>
+#include <asm/emif.h>
+#include <asm/gpio.h>
+#include <i2c.h>
+#include <miiphy.h>
+#include <cpsw.h>
+#include <video.h>
+#include <watchdog.h>
+#include "board.h"
+#include "../common/factoryset.h"
+#include "../../../drivers/video/da8xx-fb.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * Read header information from EEPROM into global structure.
+ */
+static int read_eeprom(void)
+{
+       return 0;
+}
+
+#ifdef CONFIG_SPL_BUILD
+static void board_init_ddr(void)
+{
+struct emif_regs rut_ddr3_emif_reg_data = {
+       .sdram_config = 0x61C04AB2,
+       .sdram_tim1 = 0x0888A39B,
+       .sdram_tim2 = 0x26337FDA,
+       .sdram_tim3 = 0x501F830F,
+       .emif_ddr_phy_ctlr_1 = 0x6,
+       .zq_config = 0x50074BE4,
+       .ref_ctrl = 0x93B,
+};
+
+struct ddr_data rut_ddr3_data = {
+       .datardsratio0 = 0x3b,
+       .datawdsratio0 = 0x85,
+       .datafwsratio0 = 0x100,
+       .datawrsratio0 = 0xc1,
+       .datauserank0delay = 1,
+       .datadldiff0 = PHY_DLL_LOCK_DIFF,
+};
+
+struct cmd_control rut_ddr3_cmd_ctrl_data = {
+       .cmd0csratio = 0x40,
+       .cmd0dldiff = 0,
+       .cmd0iclkout = 1,
+       .cmd1csratio = 0x40,
+       .cmd1dldiff = 0,
+       .cmd1iclkout = 1,
+       .cmd2csratio = 0x40,
+       .cmd2dldiff = 0,
+       .cmd2iclkout = 1,
+};
+
+       config_ddr(DDR_PLL_FREQ, RUT_IOCTRL_VAL, &rut_ddr3_data,
+                  &rut_ddr3_cmd_ctrl_data, &rut_ddr3_emif_reg_data, 0);
+}
+
+static void spl_siemens_board_init(void)
+{
+       return;
+}
+#endif /* if def CONFIG_SPL_BUILD */
+
+#if defined(CONFIG_DRIVER_TI_CPSW)
+static void cpsw_control(int enabled)
+{
+       /* VTP can be added here */
+
+       return;
+}
+
+static struct cpsw_slave_data cpsw_slaves[] = {
+       {
+               .slave_reg_ofs  = 0x208,
+               .sliver_reg_ofs = 0xd80,
+               .phy_id         = 1,
+               .phy_if         = PHY_INTERFACE_MODE_RMII,
+       },
+       {
+               .slave_reg_ofs  = 0x308,
+               .sliver_reg_ofs = 0xdc0,
+               .phy_id         = 0,
+               .phy_if         = PHY_INTERFACE_MODE_RMII,
+       },
+};
+
+static struct cpsw_platform_data cpsw_data = {
+       .mdio_base              = CPSW_MDIO_BASE,
+       .cpsw_base              = CPSW_BASE,
+       .mdio_div               = 0xff,
+       .channels               = 8,
+       .cpdma_reg_ofs          = 0x800,
+       .slaves                 = 1,
+       .slave_data             = cpsw_slaves,
+       .ale_reg_ofs            = 0xd00,
+       .ale_entries            = 1024,
+       .host_port_reg_ofs      = 0x108,
+       .hw_stats_reg_ofs       = 0x900,
+       .bd_ram_ofs             = 0x2000,
+       .mac_control            = (1 << 5),
+       .control                = cpsw_control,
+       .host_port_num          = 0,
+       .version                = CPSW_CTRL_VERSION_2,
+};
+
+#if defined(CONFIG_DRIVER_TI_CPSW) || \
+       (defined(CONFIG_USB_ETHER) && defined(CONFIG_MUSB_GADGET))
+int board_eth_init(bd_t *bis)
+{
+       struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
+       int n = 0;
+       int rv;
+
+#ifndef CONFIG_SPL_BUILD
+       factoryset_setenv();
+#endif
+
+       /* Set rgmii mode and enable rmii clock to be sourced from chip */
+       writel((RMII_MODE_ENABLE | RMII_CHIPCKL_ENABLE), &cdev->miisel);
+
+       rv = cpsw_register(&cpsw_data);
+       if (rv < 0)
+               printf("Error %d registering CPSW switch\n", rv);
+       else
+               n += rv;
+       return n;
+}
+#endif /* #if defined(CONFIG_DRIVER_TI_CPSW) */
+#endif /* #if (defined(CONFIG_DRIVER_TI_CPSW) && !defined(CONFIG_SPL_BUILD)) */
+
+#if defined(CONFIG_HW_WATCHDOG)
+static bool hw_watchdog_init_done;
+static int  hw_watchdog_trigger_level;
+
+void hw_watchdog_reset(void)
+{
+       if (!hw_watchdog_init_done)
+               return;
+
+       hw_watchdog_trigger_level = hw_watchdog_trigger_level ? 0 : 1;
+       gpio_set_value(WATCHDOG_TRIGGER_GPIO, hw_watchdog_trigger_level);
+}
+
+void hw_watchdog_init(void)
+{
+       gpio_request(WATCHDOG_TRIGGER_GPIO, "watchdog_trigger");
+       gpio_direction_output(WATCHDOG_TRIGGER_GPIO, hw_watchdog_trigger_level);
+
+       hw_watchdog_reset();
+
+       hw_watchdog_init_done = 1;
+}
+#endif /* defined(CONFIG_HW_WATCHDOG) */
+
+#if defined(CONFIG_VIDEO) && !defined(CONFIG_SPL_BUILD)
+static struct da8xx_panel lcd_panels[] = {
+       /* FORMIKE, 4.3", 480x800, KWH043MC17-F01 */
+       [0] = {
+               .name   = "KWH043MC17-F01",
+               .width  = 480,
+               .height = 800,
+               .hfp = 50,              /* no spec, "don't care" values */
+               .hbp = 50,
+               .hsw = 50,
+               .vfp = 50,
+               .vbp = 50,
+               .vsw = 50,
+               .pxl_clk = 35910000,    /* tCYCD=20ns, max 50MHz, 60fps */
+               .invert_pxl_clk = 1,
+       },
+       /* FORMIKE, 4.3", 480x800, KWH043ST20-F01 */
+       [1] = {
+               .name   = "KWH043ST20-F01",
+               .width  = 480,
+               .height = 800,
+               .hfp = 50,              /* no spec, "don't care" values */
+               .hbp = 50,
+               .hsw = 50,
+               .vfp = 50,
+               .vbp = 50,
+               .vsw = 50,
+               .pxl_clk = 35910000,    /* tCYCD=20ns, max 50MHz, 60fps */
+               .invert_pxl_clk = 1,
+       },
+       /* Multi-Inno, 4.3", 480x800, MI0430VT-1 */
+       [2] = {
+               .name   = "MI0430VT-1",
+               .width  = 480,
+               .height = 800,
+               .hfp = 50,              /* no spec, "don't care" values */
+               .hbp = 50,
+               .hsw = 50,
+               .vfp = 50,
+               .vbp = 50,
+               .vsw = 50,
+               .pxl_clk = 35910000,    /* tCYCD=20ns, max 50MHz, 60fps */
+               .invert_pxl_clk = 1,
+       },
+};
+
+static const struct display_panel disp_panels[] = {
+       [0] = {
+               WVGA,
+               16,     /* RGB 888 */
+               16,
+               COLOR_ACTIVE,
+       },
+       [1] = {
+               WVGA,
+               16,     /* RGB 888 */
+               16,
+               COLOR_ACTIVE,
+       },
+       [2] = {
+               WVGA,
+               24,     /* RGB 888 */
+               16,
+               COLOR_ACTIVE,
+       },
+};
+
+static const struct lcd_ctrl_config lcd_cfgs[] = {
+       [0] = {
+               &disp_panels[0],
+               .ac_bias                = 255,
+               .ac_bias_intrpt         = 0,
+               .dma_burst_sz           = 16,
+               .bpp                    = 16,
+               .fdd                    = 0x80,
+               .tft_alt_mode           = 0,
+               .stn_565_mode           = 0,
+               .mono_8bit_mode         = 0,
+               .invert_line_clock      = 1,
+               .invert_frm_clock       = 1,
+               .sync_edge              = 0,
+               .sync_ctrl              = 1,
+               .raster_order           = 0,
+       },
+       [1] = {
+               &disp_panels[1],
+               .ac_bias                = 255,
+               .ac_bias_intrpt         = 0,
+               .dma_burst_sz           = 16,
+               .bpp                    = 16,
+               .fdd                    = 0x80,
+               .tft_alt_mode           = 0,
+               .stn_565_mode           = 0,
+               .mono_8bit_mode         = 0,
+               .invert_line_clock      = 1,
+               .invert_frm_clock       = 1,
+               .sync_edge              = 0,
+               .sync_ctrl              = 1,
+               .raster_order           = 0,
+       },
+       [2] = {
+               &disp_panels[2],
+               .ac_bias                = 255,
+               .ac_bias_intrpt         = 0,
+               .dma_burst_sz           = 16,
+               .bpp                    = 24,
+               .fdd                    = 0x80,
+               .tft_alt_mode           = 0,
+               .stn_565_mode           = 0,
+               .mono_8bit_mode         = 0,
+               .invert_line_clock      = 1,
+               .invert_frm_clock       = 1,
+               .sync_edge              = 0,
+               .sync_ctrl              = 1,
+               .raster_order           = 0,
+       },
+
+};
+
+/* no console on this board */
+int board_cfb_skip(void)
+{
+       return 1;
+}
+
+#define PLL_GET_M(v) ((v >> 8) & 0x7ff)
+#define PLL_GET_N(v) (v & 0x7f)
+
+static struct dpll_regs dpll_lcd_regs = {
+       .cm_clkmode_dpll = CM_WKUP + 0x98,
+       .cm_idlest_dpll = CM_WKUP + 0x48,
+       .cm_clksel_dpll = CM_WKUP + 0x54,
+};
+
+static int get_clk(struct dpll_regs *dpll_regs)
+{
+       unsigned int val;
+       unsigned int m, n;
+       int f = 0;
+
+       val = readl(dpll_regs->cm_clksel_dpll);
+       m = PLL_GET_M(val);
+       n = PLL_GET_N(val);
+       f = (m * V_OSCK) / n;
+
+       return f;
+};
+
+
+
+int clk_get(int clk)
+{
+       return get_clk(&dpll_lcd_regs);
+};
+
+static int conf_disp_pll(int m, int n)
+{
+       struct cm_perpll *cmper = (struct cm_perpll *)CM_PER;
+       struct cm_dpll *cmdpll = (struct cm_dpll *)CM_DPLL;
+       struct dpll_params dpll_lcd = {m, n, -1, -1, -1, -1, -1};
+#if defined(DISPL_PLL_SPREAD_SPECTRUM)
+       struct cm_wkuppll *cmwkup = (struct cm_wkuppll *)CM_WKUP;
+#endif
+
+       u32 *const clk_domains[] = {
+               &cmper->lcdclkctrl,
+               0
+       };
+       u32 *const clk_modules_explicit_en[] = {
+               &cmper->lcdclkctrl,
+               &cmper->lcdcclkstctrl,
+               &cmper->spi1clkctrl,
+               0
+       };
+       do_enable_clocks(clk_domains, clk_modules_explicit_en, 1);
+       /* 0x44e0_0500 write lcdc pixel clock mux Linux hat hier 0 */
+       writel(0x0, &cmdpll->clklcdcpixelclk);
+
+       do_setup_dpll(&dpll_lcd_regs, &dpll_lcd);
+
+#if defined(DISPL_PLL_SPREAD_SPECTRUM)
+       writel(0x64, &cmwkup->resv6[3]); /* 0x50 */
+       writel(0x800, &cmwkup->resv6[2]); /* 0x4c */
+       writel(readl(&cmwkup->clkmoddplldisp) | (1 << 12),
+              &cmwkup->clkmoddplldisp); /* 0x98 */
+#endif
+       return 0;
+}
+
+static int set_gpio(int gpio, int state)
+{
+       gpio_request(gpio, "temp");
+       gpio_direction_output(gpio, state);
+       gpio_set_value(gpio, state);
+       gpio_free(gpio);
+       return 0;
+}
+
+static int enable_lcd(void)
+{
+       unsigned char buf[1];
+
+       set_gpio(BOARD_LCD_RESET, 1);
+
+       /* spi lcd init */
+       kwh043st20_f01_spi_startup(1, 0, 5000000, SPI_MODE_3);
+
+       /* backlight on */
+       buf[0] = 0xf;
+       i2c_write(0x24, 0x7, 1, buf, 1);
+       buf[0] = 0x3f;
+       i2c_write(0x24, 0x8, 1, buf, 1);
+       return 0;
+}
+
+int arch_early_init_r(void)
+{
+       enable_lcd();
+       return 0;
+}
+
+static int board_video_init(void)
+{
+       int i;
+       int anzdisp = ARRAY_SIZE(lcd_panels);
+       int display = 1;
+
+       for (i = 0; i < anzdisp; i++) {
+               if (strncmp((const char *)factory_dat.disp_name,
+                           lcd_panels[i].name,
+                   strlen((const char *)factory_dat.disp_name)) == 0) {
+                       printf("DISPLAY: %s\n", factory_dat.disp_name);
+                       break;
+               }
+       }
+       if (i == anzdisp) {
+               i = 1;
+               printf("%s: %s not found, using default %s\n", __func__,
+                      factory_dat.disp_name, lcd_panels[i].name);
+       }
+       conf_disp_pll(25, 2);
+       da8xx_video_init(&lcd_panels[display], &lcd_cfgs[display],
+                        lcd_cfgs[display].bpp);
+
+       return 0;
+}
+
+
+#endif /* ifdef CONFIG_VIDEO */
+#include "../common/board.c"
diff --git a/board/siemens/rut/board.h b/board/siemens/rut/board.h
new file mode 100644 (file)
index 0000000..0362612
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * board.h
+ *
+ * (C) Copyright 2013 Siemens Schweiz AG
+ * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Based on:
+ * TI AM335x boards information header
+ * u-boot:/board/ti/am335x/board.h
+ *
+ * Copyright (C) 2011, Texas Instruments, Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef _BOARD_H_
+#define _BOARD_H_
+
+void enable_uart0_pin_mux(void);
+void enable_i2c0_pin_mux(void);
+void enable_board_pin_mux(void);
+#endif
diff --git a/board/siemens/rut/mux.c b/board/siemens/rut/mux.c
new file mode 100644 (file)
index 0000000..1eced01
--- /dev/null
@@ -0,0 +1,347 @@
+/*
+ * pinmux setup for siemens rut board
+ *
+ * (C) Copyright 2013 Siemens Schweiz AG
+ * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Based on:
+ * u-boot:/board/ti/am335x/mux.c
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/mux.h>
+#include <asm/io.h>
+#include <i2c.h>
+
+static struct module_pin_mux uart0_pin_mux[] = {
+       {OFFSET(uart0_rxd), (MODE(0) | PULLUDDIS | RXACTIVE)},  /* UART0_RXD */
+       {OFFSET(uart0_txd), (MODE(0) | PULLUDDIS)},             /* UART0_TXD */
+       {-1},
+};
+
+static struct module_pin_mux ddr_pin_mux[] = {
+       {OFFSET(ddr_resetn), (MODE(0))},
+       {OFFSET(ddr_csn0), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_ck), (MODE(0))},
+       {OFFSET(ddr_nck), (MODE(0))},
+       {OFFSET(ddr_casn), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_rasn), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_wen), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_ba0), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_ba1), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_ba2), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_a0), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_a1), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_a2), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_a3), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_a4), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_a5), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_a6), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_a7), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_a8), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_a9), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_a10), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_a11), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_a12), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_a13), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_a14), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_a15), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_odt), (MODE(0))},
+       {OFFSET(ddr_d0), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_d1), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_d2), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_d3), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_d4), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_d5), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_d6), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_d7), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_d8), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_d9), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_d10), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_d11), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_d12), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_d13), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_d14), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_d15), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_dqm0), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_dqm1), (MODE(0) | PULLUP_EN)},
+       {OFFSET(ddr_dqs0), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_dqsn0), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(ddr_dqs1), (MODE(0) | RXACTIVE)},
+       {OFFSET(ddr_dqsn1), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(ddr_vref), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(ddr_vtp), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {-1},
+};
+
+static struct module_pin_mux lcd_pin_mux[] = {
+       {OFFSET(gpmc_ad8), (MODE(1))},
+       {OFFSET(gpmc_ad9), (MODE(1))},
+       {OFFSET(gpmc_ad10), (MODE(1))},
+       {OFFSET(gpmc_ad11), (MODE(1))},
+       {OFFSET(gpmc_ad12), (MODE(1))},
+       {OFFSET(gpmc_ad13), (MODE(1))},
+       {OFFSET(gpmc_ad14), (MODE(1))},
+       {OFFSET(gpmc_ad15), (MODE(1))},
+       {OFFSET(lcd_data0), (MODE(0) | PULLUDDIS)},
+       {OFFSET(lcd_data1), (MODE(0) | PULLUDDIS)},
+       {OFFSET(lcd_data2), (MODE(0) | PULLUDDIS)},
+       {OFFSET(lcd_data3), (MODE(0) | PULLUDDIS)},
+       {OFFSET(lcd_data4), (MODE(0) | PULLUDDIS)},
+       {OFFSET(lcd_data5), (MODE(0) | PULLUDDIS)},
+       {OFFSET(lcd_data6), (MODE(0) | PULLUDDIS)},
+       {OFFSET(lcd_data7), (MODE(0) | PULLUDDIS)},
+       {OFFSET(lcd_data8), (MODE(0) | PULLUDDIS)},
+       {OFFSET(lcd_data9), (MODE(0) | PULLUDDIS)},
+       {OFFSET(lcd_data10), (MODE(0) | PULLUDDIS)},
+       {OFFSET(lcd_data11), (MODE(0) | PULLUDDIS)},
+       {OFFSET(lcd_data12), (MODE(0) | PULLUDDIS)},
+       {OFFSET(lcd_data13), (MODE(0) | PULLUDDIS)},
+       {OFFSET(lcd_data14), (MODE(0) | PULLUDDIS)},
+       {OFFSET(lcd_data15), (MODE(0) | PULLUDDIS)},
+       {OFFSET(lcd_vsync), (MODE(0))},
+       {OFFSET(lcd_hsync), (MODE(0))},
+       {OFFSET(lcd_pclk), (MODE(0))},
+       {OFFSET(lcd_ac_bias_en), (MODE(0))},
+       {-1},
+};
+
+static struct module_pin_mux mmc0_pin_mux[] = {
+       {OFFSET(mmc0_dat3), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(mmc0_dat2), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(mmc0_dat1), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(mmc0_dat0), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(mmc0_clk), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(mmc0_cmd), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {-1},
+};
+
+static struct module_pin_mux mii_pin_mux[] = {
+       {OFFSET(mii1_crs), (MODE(1) | RXACTIVE)},
+       {OFFSET(mii1_rxerr), (MODE(1) | RXACTIVE)},
+       {OFFSET(mii1_txen), (MODE(1))},
+       {OFFSET(mii1_txd1), (MODE(1))},
+       {OFFSET(mii1_txd0), (MODE(1))},
+       {OFFSET(mii1_rxd1), (MODE(1) | RXACTIVE)},
+       {OFFSET(mii1_rxd0), (MODE(1) | RXACTIVE)},
+       {OFFSET(rmii1_refclk), (MODE(0) | RXACTIVE)},
+       {OFFSET(mdio_data), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(mdio_clk), (MODE(0) | PULLUP_EN)},
+       {-1},
+};
+
+static struct module_pin_mux gpio_pin_mux[] = {
+       {OFFSET(mii1_col), (MODE(7) | RXACTIVE)},
+       {OFFSET(uart1_ctsn), (MODE(7) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(uart1_rtsn), (MODE(7) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(uart1_rxd), (MODE(7) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(uart1_txd), (MODE(7) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(mii1_rxdv), (MODE(7) | RXACTIVE)},
+       {OFFSET(mii1_txd3), (MODE(7) | RXACTIVE)},
+       {OFFSET(mii1_txd2), (MODE(7) | RXACTIVE)},
+       {OFFSET(mii1_txclk), (MODE(7) | RXACTIVE)},
+       {OFFSET(mii1_rxclk), (MODE(7) | RXACTIVE)},
+       {OFFSET(mii1_rxd3), (MODE(7) | RXACTIVE)},
+       {OFFSET(mii1_rxd2), (MODE(7) | RXACTIVE)},
+       {OFFSET(gpmc_a0), (MODE(7) | RXACTIVE)},
+       {OFFSET(gpmc_a1), (MODE(7) | RXACTIVE)},
+       {OFFSET(gpmc_a4), (MODE(7) | RXACTIVE)},
+       {OFFSET(gpmc_a5), (MODE(7) | RXACTIVE)},
+       {OFFSET(gpmc_a6), (MODE(7) | RXACTIVE)},
+       {OFFSET(gpmc_a7), (MODE(7) | RXACTIVE)},
+       {OFFSET(gpmc_a8), (MODE(7) | RXACTIVE)},
+       {OFFSET(gpmc_a9), (MODE(7) | RXACTIVE)},
+       {OFFSET(gpmc_a10), (MODE(7) | RXACTIVE)},
+       {OFFSET(gpmc_a11), (MODE(7) | RXACTIVE)},
+       {OFFSET(gpmc_wpn), (MODE(7) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(gpmc_be1n), (MODE(7) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(gpmc_csn1), (MODE(7) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(gpmc_csn2), (MODE(7) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(gpmc_csn3), (MODE(7) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(mcasp0_aclkr), (MODE(7) | RXACTIVE)},
+       {OFFSET(mcasp0_fsr), (MODE(7))},
+       {OFFSET(mcasp0_axr1), (MODE(7) | RXACTIVE)},
+       {OFFSET(mcasp0_ahclkx), (MODE(7) | RXACTIVE)},
+       {OFFSET(xdma_event_intr0), (MODE(7) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(xdma_event_intr1), (MODE(7) | RXACTIVE | PULLUDDIS)},
+       {-1},
+};
+
+static struct module_pin_mux i2c0_pin_mux[] = {
+       {OFFSET(i2c0_sda), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(i2c0_scl), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {-1},
+};
+
+static struct module_pin_mux i2c1_pin_mux[] = {
+       {OFFSET(uart0_ctsn), (MODE(3) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(uart0_rtsn), (MODE(3) | RXACTIVE | PULLUDDIS)},
+       {-1},
+};
+
+static struct module_pin_mux usb0_pin_mux[] = {
+       {OFFSET(usb0_dm), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(usb0_dp), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(usb0_ce), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(usb0_id), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(usb0_vbus), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(usb0_drvvbus), (MODE(0))},
+       {-1},
+};
+
+static struct module_pin_mux usb1_pin_mux[] = {
+       {OFFSET(usb1_dm), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(usb1_dp), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(usb1_ce), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(usb1_id), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(usb1_vbus), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(usb1_drvvbus), (MODE(0))},
+       {-1},
+};
+
+static struct module_pin_mux spi0_pin_mux[] = {
+       {OFFSET(spi0_sclk), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(spi0_d0), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(spi0_d1), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(spi0_cs0), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(spi0_cs1), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {-1},
+};
+
+static struct module_pin_mux spi1_pin_mux[] = {
+       {OFFSET(mcasp0_aclkx), (MODE(3) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(mcasp0_fsx), (MODE(3) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(mcasp0_axr0), (MODE(3) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(mcasp0_ahclkr), (MODE(3) | RXACTIVE | PULLUP_EN)},
+       {-1},
+};
+
+static struct module_pin_mux jtag_pin_mux[] = {
+       {OFFSET(tms), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(tdi), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(tdo), (MODE(0) | PULLUP_EN)},
+       {OFFSET(tck), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(ntrst), (MODE(0) | RXACTIVE)},
+       {-1},
+};
+
+static struct module_pin_mux nand_pin_mux[] = {
+       {OFFSET(gpmc_ad0), (MODE(0) | RXACTIVE)},
+       {OFFSET(gpmc_ad1), (MODE(0) | RXACTIVE)},
+       {OFFSET(gpmc_ad2), (MODE(0) | RXACTIVE)},
+       {OFFSET(gpmc_ad3), (MODE(0) | RXACTIVE)},
+       {OFFSET(gpmc_ad4), (MODE(0) | RXACTIVE)},
+       {OFFSET(gpmc_ad5), (MODE(0) | RXACTIVE)},
+       {OFFSET(gpmc_ad6), (MODE(0) | RXACTIVE)},
+       {OFFSET(gpmc_ad7), (MODE(0) | RXACTIVE)},
+       {OFFSET(gpmc_advn_ale), (MODE(0) | PULLUP_EN)},
+       {OFFSET(gpmc_be0n_cle), (MODE(0) | PULLUP_EN)},
+       {OFFSET(gpmc_csn0), (MODE(0) | PULLUP_EN)},
+       {OFFSET(gpmc_oen_ren), (MODE(0) | PULLUP_EN)},
+       {OFFSET(gpmc_wen), (MODE(0) | PULLUP_EN)},
+       {-1},
+};
+
+static struct module_pin_mux ainx_pin_mux[] = {
+       {OFFSET(ain7), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(ain6), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(ain5), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(ain4), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(ain3), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(ain2), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(ain1), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(ain0), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {-1},
+};
+
+static struct module_pin_mux rtc_pin_mux[] = {
+       {OFFSET(osc1_in), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(osc1_out), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(rtc_porz), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(enz_kaldo_1p8v), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {-1},
+};
+
+static struct module_pin_mux gpmc_pin_mux[] = {
+       {OFFSET(gpmc_wait0), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(gpmc_clk), (MODE(0) | RXACTIVE)},
+       {-1},
+};
+
+static struct module_pin_mux pmic_pin_mux[] = {
+       {OFFSET(pmic_power_en), (MODE(0) | PULLUP_EN)},
+       {-1},
+};
+
+static struct module_pin_mux osc_pin_mux[] = {
+       {OFFSET(osc0_in), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(osc0_out), (MODE(0) | PULLUP_EN)},
+       {-1},
+};
+
+static struct module_pin_mux pwm_pin_mux[] = {
+       {OFFSET(ecap0_in_pwm0_out), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(gpmc_a2), (MODE(6))},
+       {OFFSET(gpmc_a3), (MODE(6))},
+       {-1},
+};
+
+static struct module_pin_mux emu_pin_mux[] = {
+       {OFFSET(emu0), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {OFFSET(emu1), (MODE(0) | RXACTIVE | PULLUP_EN)},
+       {-1},
+};
+
+static struct module_pin_mux vref_pin_mux[] = {
+       {OFFSET(vrefp), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(vrefn), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {-1},
+};
+
+static struct module_pin_mux misc_pin_mux[] = {
+       {OFFSET(porz), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(nnmi), (MODE(0) | RXACTIVE | PULLUDDIS)},
+       {OFFSET(ext_wakeup), (MODE(0) | RXACTIVE)},
+       {-1},
+};
+
+void enable_uart0_pin_mux(void)
+{
+       configure_module_pin_mux(uart0_pin_mux);
+}
+
+void enable_i2c0_pin_mux(void)
+{
+       configure_module_pin_mux(i2c0_pin_mux);
+}
+
+void enable_board_pin_mux(void)
+{
+       configure_module_pin_mux(ddr_pin_mux);
+       configure_module_pin_mux(lcd_pin_mux);
+       configure_module_pin_mux(mmc0_pin_mux);
+       configure_module_pin_mux(mii_pin_mux);
+       configure_module_pin_mux(gpio_pin_mux);
+       configure_module_pin_mux(i2c1_pin_mux);
+       configure_module_pin_mux(usb0_pin_mux);
+       configure_module_pin_mux(usb1_pin_mux);
+       configure_module_pin_mux(spi0_pin_mux);
+       configure_module_pin_mux(spi1_pin_mux);
+       configure_module_pin_mux(jtag_pin_mux);
+       configure_module_pin_mux(nand_pin_mux);
+       configure_module_pin_mux(ainx_pin_mux);
+       configure_module_pin_mux(rtc_pin_mux);
+       configure_module_pin_mux(gpmc_pin_mux);
+       configure_module_pin_mux(pmic_pin_mux);
+       configure_module_pin_mux(osc_pin_mux);
+       configure_module_pin_mux(pwm_pin_mux);
+       configure_module_pin_mux(emu_pin_mux);
+       configure_module_pin_mux(vref_pin_mux);
+       configure_module_pin_mux(misc_pin_mux);
+}
index 67b524673a106a1ebb08526f96f4afaff880f9dd..2a30ab89817df5881aca0a75241df847715f2a92 100644 (file)
@@ -13,7 +13,33 @@ documented in TI's reference designs:
 - AM335x EVM SK
 - Beaglebone White
 - Beaglebone Black
-'
+
+Customization
+=============
+
+Given that all of the above boards are reference platforms (and the
+Beaglebone platforms are OSHA), it is likely that this platform code and
+configuration will be used as the basis of a custom platform.  It is
+worth noting that aside from things such as NAND or MMC only being
+required if a custom platform makes use of these blocks, the following
+are required, depending on design:
+
+- GPIO is only required if DDR3 power is controlled in a way similar to
+  EVM SK
+- SPI is only required for SPI flash, or exposing the SPI bus.
+
+The following blocks are required:
+- I2C, to talk with the PMIC and ensure that we do not run afoul of
+  errata 1.0.24.
+
+When removing options as part of customization,
+CONFIG_EXTRA_ENV_SETTINGS will need additional care to update for your
+needs and to remove no longer relevant options as in some cases we
+define additional text blocks (such as for NAND or DFU strings).  Also
+note that all of the SPL options are grouped together, rather than with
+the IP blocks, so both areas will need their choices updated to reflect
+the custom design.
+
 NAND
 ====
 
index 04c37e2db6b3ad177fd43a082c772e33e298ac28..cc0442612ffe237fbde2255c330a31d80205ba37 100644 (file)
 
 DECLARE_GLOBAL_DATA_PTR;
 
-/* MII mode defines */
-#define MII_MODE_ENABLE                0x0
-#define RGMII_MODE_ENABLE      0x3A
-
 /* GPIO that controls power to DDR on EVM-SK */
 #define GPIO_DDR_VTT_EN                7
 
@@ -460,7 +456,7 @@ int board_eth_init(bd_t *bis)
                cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if =
                                PHY_INTERFACE_MODE_MII;
        } else {
-               writel(RGMII_MODE_ENABLE, &cdev->miisel);
+               writel((RGMII_MODE_ENABLE | RGMII_INT_DELAY), &cdev->miisel);
                cpsw_slaves[0].phy_if = cpsw_slaves[1].phy_if =
                                PHY_INTERFACE_MODE_RGMII;
        }
index 25daaa9ffb140eadf925ab8981ef7aed1bdb363a..79270a9e94e2e2e6a1e85b29d2b6c84ff228dd9a 100644 (file)
@@ -28,7 +28,6 @@ int board_init(void)
 {
        gpmc_init();
 
-       gd->bd->bi_arch_number = MACH_TYPE_OMAP_4430SDP;
        gd->bd->bi_boot_params = (0x80000000 + 0x100); /* boot param addr */
 
        return 0;
@@ -66,7 +65,8 @@ void set_muxconf_regs_essential(void)
                   sizeof(wkup_padconf_array_essential) /
                   sizeof(struct pad_conf_entry));
 
-       if (omap_revision() >= OMAP4460_ES1_0)
+       if ((omap_revision() >= OMAP4460_ES1_0) &&
+                       (omap_revision() < OMAP4470_ES1_0))
                do_set_mux((*ctrl)->control_padconf_wkup_base,
                                 wkup_padconf_array_essential_4460,
                                 sizeof(wkup_padconf_array_essential_4460) /
index c173f0cc51f498b1c1c9cf7514f28b0ec1d8223d..f7f1c59ac5455fd44f53ccfb98de1344ce084ac3 100644 (file)
@@ -65,6 +65,23 @@ int board_eth_init(bd_t *bis)
 {
        u32 ret = 0;
 
+#ifdef CONFIG_XILINX_AXIEMAC
+       ret |= xilinx_axiemac_initialize(bis, XILINX_AXIEMAC_BASEADDR,
+                                               XILINX_AXIDMA_BASEADDR);
+#endif
+#ifdef CONFIG_XILINX_EMACLITE
+       u32 txpp = 0;
+       u32 rxpp = 0;
+# ifdef CONFIG_XILINX_EMACLITE_TX_PING_PONG
+       txpp = 1;
+# endif
+# ifdef CONFIG_XILINX_EMACLITE_RX_PING_PONG
+       rxpp = 1;
+# endif
+       ret |= xilinx_emaclite_initialize(bis, XILINX_EMACLITE_BASEADDR,
+                       txpp, rxpp);
+#endif
+
 #if defined(CONFIG_ZYNQ_GEM)
 # if defined(CONFIG_ZYNQ_GEM0)
        ret |= zynq_gem_initialize(bis, ZYNQ_GEM_BASEADDR0,
@@ -100,5 +117,7 @@ int dram_init(void)
 {
        gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
 
+       zynq_ddrc_init();
+
        return 0;
 }
index be810c78eda9df70edab05761fe24cf056274af0..48aa0bf1021258dd22e1fecc27a277dcae96306a 100644 (file)
@@ -204,6 +204,7 @@ mx23evk                      arm         arm926ejs   mx23evk             freesca
 m28evk                       arm         arm926ejs   m28evk              denx           mxs            m28evk
 mx28evk                      arm         arm926ejs   mx28evk             freescale      mxs            mx28evk:ENV_IS_IN_MMC
 mx28evk_nand                 arm         arm926ejs   mx28evk             freescale      mxs            mx28evk:ENV_IS_IN_NAND
+mx28evk_auart_console        arm         arm926ejs   mx28evk             freescale      mxs            mx28evk:MXS_AUART,MXS_AUART_BASE=MXS_UARTAPP3_BASE,ENV_IS_IN_MMC
 sc_sps_1                     arm         arm926ejs   sc_sps_1            schulercontrol mxs
 nhk8815                      arm         arm926ejs   nhk8815             st             nomadik
 nhk8815_onenand              arm         arm926ejs   nhk8815             st             nomadik       nhk8815:BOOT_ONENAND
@@ -254,6 +255,9 @@ am335x_evm_uart5             arm         armv7       am335x              ti
 am335x_evm_usbspl            arm         armv7       am335x              ti             am33xx      am335x_evm:SERIAL1,CONS_INDEX=1,NAND,SPL_USBETH_SUPPORT
 am335x_boneblack             arm         armv7       am335x              ti             am33xx      am335x_evm:SERIAL1,CONS_INDEX=1,EMMC_BOOT
 am43xx_evm                   arm         armv7       am43xx              ti             am33xx      am43xx_evm:SERIAL1,CONS_INDEX=1
+dxr2                         arm         armv7       dxr2                siemens        am33xx
+pxm2                         arm         armv7       pxm2                siemens        am33xx
+rut                          arm         armv7       rut                 siemens        am33xx
 ti814x_evm                   arm         armv7       ti814x              ti             am33xx
 ti816x_evm                   arm         armv7       ti816x              ti             am33xx
 pcm051                       arm         armv7       pcm051              phytec         am33xx      pcm051
index 56a5a626e6a937678af53b5905b654243885be02..2c88091e6de1be3f02d29304eedf5368368482dd 100644 (file)
@@ -135,6 +135,7 @@ static const table_entry_t uimage_type[] = {
        {       IH_TYPE_SCRIPT,     "script",     "Script",             },
        {       IH_TYPE_STANDALONE, "standalone", "Standalone Program", },
        {       IH_TYPE_UBLIMAGE,   "ublimage",   "Davinci UBL image",},
+       {       IH_TYPE_MXSIMAGE,   "mxsimage",   "Freescale MXS Boot Image",},
        {       -1,                 "",           "",                   },
 };
 
index b55ed563a5e0307edc26c5369cb74c4a424c8d27..48913f6659f101e9009d54b5886bab44f0fafccd 100644 (file)
--- a/config.mk
+++ b/config.mk
@@ -220,6 +220,15 @@ LDFLAGS_FINAL += --gc-sections
 endif
 
 # TODO(sjg@chromium.org): Is this correct on Mac OS?
+
+# MXSImage needs LibSSL
+ifneq ($(CONFIG_MX23)$(CONFIG_MX28),)
+HOSTLIBS       += -lssl -lcrypto
+# Add CONFIG_MXS into host CFLAGS, so we can check whether or not register
+# the mxsimage support within tools/mxsimage.c .
+HOSTCFLAGS     += -DCONFIG_MXS
+endif
+
 ifdef CONFIG_FIT_SIGNATURE
 HOSTLIBS       += -lssl -lcrypto
 
index ac9a2137c8b5569be1da310f032757faaf89c85d..312a6a612e694716e751dcca4bc3454c7c38ff2e 100644 (file)
@@ -67,7 +67,7 @@ CONFIG_SPL_POST_MEM_SUPPORT (post/drivers/memory.o)
 CONFIG_SPL_NAND_LOAD (drivers/mtd/nand/nand_spl_load.o)
 CONFIG_SPL_SPI_LOAD (drivers/mtd/spi/spi_spl_load.o)
 CONFIG_SPL_RAM_DEVICE (common/spl/spl.c)
-
+CONFIG_SPL_WATCHDOG_SUPPORT (drivers/watchdog/libwatchdog.o)
 
 Normally CPU is assumed to be the same between the SPL and normal
 u-boot build.  However it is possible to specify a different CPU for
index b483744ea5987b84aa1c05c608cac13967aa625e..41f3bd786084a46a4321c946e040ac1d4038b757 100644 (file)
@@ -19,17 +19,6 @@ To use PMECC in this driver, the user needs to set:
           It can be 2, 4, 8, 12 or 24.
        2. The PMECC sector size: CONFIG_PMECC_SECTOR_SIZE.
           It only can be 512 or 1024.
-       3. The PMECC index lookup table's offsets in ROM code: CONFIG_PMECC_INDEX_TABLE_OFFSET.
-          In the chip datasheet section "Boot Stragegies", you can find
-          two Galois Field Table in the ROM code. One table is for 512-bytes
-          sector. Another is for 1024-byte sector. Each Galois Field includes
-          two sub-table: indext table & alpha table.
-          In the beginning of each Galois Field Table is the index table,
-          Alpha table is in the following.
-          So the index table's offset is same as the Galois Field Table.
-
-          Please set CONFIG_PMECC_INDEX_TABLE_OFFSET correctly according the
-          Galois Field Table's offset base on the sector size you used.
 
 Take AT91SAM9X5EK as an example, the board definition file likes:
 
@@ -38,7 +27,4 @@ Take AT91SAM9X5EK as an example, the board definition file likes:
 #define CONFIG_ATMEL_NAND_HW_PMECC     1
 #define CONFIG_PMECC_CAP               2
 #define CONFIG_PMECC_SECTOR_SIZE       512
-#define CONFIG_PMECC_INDEX_TABLE_OFFSET        0x8000
 
-NOTE: If you use 1024 as the sector size, then need set 0x10000 as the
- CONFIG_PMECC_INDEX_TABLE_OFFSET
index 802eb90f1de6b352dc383f69cdc234b0b64cccd9..dcda2005af93439ca42e85c5b7ffb1ccd4233586 100644 (file)
@@ -15,9 +15,6 @@ Booting from NOR flash does not require to use this image type.
 For more details refer Chapter 2 - System Boot and section 2.14
 (flash header description) of the processor's manual.
 
-This implementation does not use at the moment the secure boot feature
-of the processor. The image is generated disabling all security fields.
-
 Command syntax:
 --------------
 ./tools/mkimage -l <mx u-boot_file>
@@ -86,6 +83,33 @@ Configuration command line syntax:
                                Example:
                                BOOT_FROM spi
 
+       CSF                     value
+
+                               Total size of CSF (Command Sequence File)
+                               used for Secure Boot/ High Assurance Boot
+                               (HAB).
+
+                               Using this command will populate the IVT
+                               (Initial Vector Table) CSF pointer and adjust
+                               the length fields only. The CSF itself needs
+                               to be generated with Freescale tools and
+                               'manually' appended to the u-boot.imx file.
+
+                               The CSF is then simply concatenated
+                               to the u-boot image, making a signed bootloader,
+                               that the processor can verify
+                               if the fuses for the keys are burned.
+
+                               Further infos how to configure the SOC to verify
+                               the bootloader can be found in the "High
+                               Assurance Boot Version Application Programming
+                               Interface Reference Manual" as part of the
+                               Freescale Code Signing Tool, available on the
+                               manufacturer's website.
+
+                               Example:
+                               CSF 0x2000
+
        DATA                    type address value
 
                                type: word=4, halfword=2, byte=1
diff --git a/doc/README.mxc_hab b/doc/README.mxc_hab
new file mode 100644 (file)
index 0000000..97f8b7d
--- /dev/null
@@ -0,0 +1,48 @@
+High Assurance Boot (HAB) for i.MX6 CPUs
+
+To authenticate U-Boot only by the CPU there is no code required in
+U-Boot itself. However, the U-Boot image to be programmed into the
+boot media needs to be properly constructed, i.e. it must contain a
+proper Command Sequence File (CSF).
+
+The Initial Vector Table contains a pointer to the CSF. Please see
+doc/README.imximage for how to prepare u-boot.imx.
+
+The CSF itself is being generated by Freescale HAB tools.
+
+mkimage will output additional information about "HAB Blocks"
+which can be used in the Freescale tooling to authenticate U-Boot
+(entries in the CSF file).
+
+Image Type:   Freescale IMX Boot Image
+Image Ver:    2 (i.MX53/6 compatible)
+Data Size:    327680 Bytes = 320.00 kB = 0.31 MB
+Load Address: 177ff420
+Entry Point:  17800000
+HAB Blocks:   177ff400 00000000 0004dc00
+              ^^^^^^^^ ^^^^^^^^ ^^^^^^^^
+               |       |          |
+               |       |          -------- (1)
+               |       |
+               |       ------------------- (2)
+               |
+               --------------------------- (3)
+
+(1)    Size of area in file u-boot.imx to sign
+       This area should include the IVT, the Boot Data the DCD
+       and U-Boot itself.
+(2)    Start of area in u-boot.imx to sign
+(3)    Start of area in RAM to authenticate
+
+CONFIG_SECURE_BOOT currently enables only an additional command
+'hab_status' in U-Boot to retrieve the HAB status and events. This
+can be useful while developing and testing HAB.
+
+Commands to generate a signed U-Boot using Freescale HAB tools:
+cst --o U-Boot_CSF.bin < U-Boot.CSF
+objcopy -I binary -O binary --pad-to 0x2000 --gap-fill=0x00 \
+       U-Boot_CSF.bin U-Boot_CSF_pad.bin
+cat u-boot.imx U-Boot_CSF_pad.bin > u-boot-signed.imx
+
+NOTE: U-Boot_CSF.bin needs to be padded to the value specified in
+the imximage.cfg file.
diff --git a/doc/README.mxsimage b/doc/README.mxsimage
new file mode 100644 (file)
index 0000000..88a2caf
--- /dev/null
@@ -0,0 +1,165 @@
+Freescale i.MX233/i.MX28 SB image generator via mkimage
+=======================================================
+
+This tool allows user to produce SB BootStream encrypted with a zero key.
+Such a BootStream is then bootable on i.MX23/i.MX28.
+
+Usage -- producing image:
+=========================
+The mxsimage tool is targeted to be a simple replacement for the elftosb2 .
+To generate an image, write an image configuration file and run:
+
+ mkimage -A arm -O u-boot -T mxsimage -n <path to configuration file> \
+         <output bootstream file>
+
+The output bootstream file is usually using the .sb file extension. Note
+that the example configuration files for producing bootable BootStream with
+the U-Boot bootloader can be found under arch/arm/boot/cpu/arm926ejs/mxs/
+directory. See the following files:
+
+ mxsimage.mx23.cfg -- This is an example configuration for i.MX23
+ mxsimage.mx28.cfg -- This is an example configuration for i.MX28
+
+Each configuration file uses very simple instruction semantics and a few
+additional rules have to be followed so that a useful image can be produced.
+These semantics and rules will be outlined now.
+
+- Each line of the configuration file contains exactly one instruction.
+- Every numeric value must be encoded in hexadecimal and in format 0xabcdef12 .
+- The configuration file is a concatenation of blocks called "sections" and
+  optionally "DCD blocks" (see below).
+  - Each "section" is started by the "SECTION" instruction.
+  - The "SECTION" instruction has the following semantics:
+
+      SECTION u32_section_number [BOOTABLE]
+      - u32_section_number :: User-selected ID of the section
+      - BOOTABLE           :: Sets the section as bootable
+
+  - A bootable section is one from which the BootROM starts executing
+    subsequent instructions or code. Exactly one section must be selected
+    as bootable, usually the one containing the instructions and data to
+    load the bootloader.
+
+  - A "SECTION" must be immediatelly followed by a "TAG" instruction.
+  - The "TAG" instruction has the following semantics:
+
+      TAG [LAST]
+      - LAST               :: Flag denoting the last section in the file
+
+  - After a "TAG" unstruction, any of the following instructions may follow
+    in any order and any quantity:
+
+      NOOP
+      - This instruction does nothing
+
+      LOAD     u32_address string_filename
+      - Instructs the BootROM to load file pointed by "string_filename" onto
+        address "u32_address".
+
+      LOAD IVT u32_address u32_IVT_entry_point
+      - Crafts and loads IVT onto address "u32_address" with the entry point
+        of u32_IVT_entry_point.
+      - i.MX28-specific instruction!
+
+      LOAD DCD u32_address u32_DCD_block_ID
+      - Loads the DCD block with ID "u32_DCD_block_ID" onto address
+        "u32_address" and executes the contents of this DCD block
+      - i.MX28-specific instruction!
+
+      FILL u32_address u32_pattern u32_length
+      - Starts to write memory from addres "u32_address" with a pattern
+        specified by "u32_pattern". Writes exactly "u32_length" bytes of the
+       pattern.
+
+      JUMP [HAB] u32_address [u32_r0_arg]
+      - Jumps onto memory address specified by "u32_address" by setting this
+        address in PT. The BootROM will pass the "u32_r0_arg" value in ARM
+       register "r0" to the executed code if this option is specified.
+       Otherwise, ARM register "r0" will default to value 0x00000000. The
+       optional "HAB" flag is i.MX28-specific flag turning on the HAB boot.
+
+      CALL [HAB] u32_address [u32_r0_arg]
+      - See JUMP instruction above, as the operation is exactly the same with
+        one difference. The CALL instruction does allow returning into the
+       BootROM from the executed code. U-Boot makes use of this in it's SPL
+       code.
+
+      MODE string_mode
+      - Restart the CPU and start booting from device specified by the
+       "string_mode" argument. The "string_mode" differs for each CPU
+       and can be:
+         i.MX23, string_mode = USB/I2C/SPI1_FLASH/SPI2_FLASH/NAND_BCH
+                               JTAG/SPI3_EEPROM/SD_SSP0/SD_SSP1
+         i.MX28, string_mode = USB/I2C/SPI2_FLASH/SPI3_FLASH/NAND_BCH
+                               JTAG/SPI2_EEPROM/SD_SSP0/SD_SSP1
+
+  - An optional "DCD" blocks can be added at the begining of the configuration
+    file. Note that the DCD is only supported on i.MX28.
+    - The DCD blocks must be inserted before the first "section" in the
+      configuration file.
+    - The DCD block has the following semantics:
+
+        DCD u32_DCD_block_ID
+       - u32_DCD_block_ID      :: The ID number of the DCD block, must match
+                                  the ID number used by "LOAD DCD" instruction.
+
+    - The DCD block must be followed by one of the following instructions. All
+      of the instructions operate either on 1, 2 or 4 bytes. This is selected by
+      the 'n' suffix of the instruction:
+
+       WRITE.n u32_address u32_value
+       - Write the "u32_value" to the "u32_address" address.
+
+       ORR.n u32_address u32_value
+       - Read the "u32_address", perform a bitwise-OR with the "u32_value" and
+         write the result back to "u32_address".
+
+       ANDC.n u32_address u32_value
+       - Read the "u32_address", perform a bitwise-AND with the complement of
+         "u32_value" and write the result back to "u32_address".
+
+       EQZ.n u32_address u32_count
+       - Read the "u32_address" at most "u32_count" times and test if the value
+         read is zero. If it is, break the loop earlier.
+
+       NEZ.n u32_address u32_count
+       - Read the "u32_address" at most "u32_count" times and test if the value
+         read is non-zero. If it is, break the loop earlier.
+
+       EQ.n u32_address u32_mask
+       - Read the "u32_address" in a loop and test if the result masked with
+         "u32_mask" equals the "u32_mask". If the values are equal, break the
+         reading loop.
+
+       NEQ.n u32_address u32_mask
+       - Read the "u32_address" in a loop and test if the result masked with
+         "u32_mask" does not equal the "u32_mask". If the values are not equal,
+         break the reading loop.
+
+       NOOP
+       - This instruction does nothing.
+
+- If the verbose output from the BootROM is enabled, the BootROM will produce a
+  letter on the Debug UART for each instruction it started processing. Here is a
+  mapping between the above instructions and the BootROM verbose output:
+
+   H -- SB Image header loaded
+   T -- TAG instruction
+   N -- NOOP instruction
+   L -- LOAD instruction
+   F -- FILL instruction
+   J -- JUMP instruction
+   C -- CALL instruction
+   M -- MODE instruction
+
+Usage -- verifying image:
+=========================
+
+The mxsimage can also verify and dump contents of an image. Use the following
+syntax to verify and dump contents of an image:
+
+ mkimage -l <input bootstream file>
+
+This will output all the information from the SB image header and all the
+instructions contained in the SB image. It will also check if the various
+checksums in the SB image are correct.
index 23229148d997201d5575dd2cfa889b6cbc34c2e9..af0978675ea84c77399a4a3e7229a8dc8f4f3f83 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Memory Setup stuff - taken from blob memsetup.S
+ * Copyright (C) 2013 Bo Shen <voice.shen@atmel.com>
  *
  * Copyright (C) 2009 Jens Scharsig (js_at_ng@scharsoft.de)
  *
@@ -8,16 +8,6 @@
  * SPDX-License-Identifier:    GPL-2.0+
  */
 
-/*
- * WARNING:
- *
- * As the code is right now, it expects all PIO ports A,B,C,...
- * to be evenly spaced in the memory map:
- * ATMEL_BASE_PIOA + port * sizeof at91pio_t
- * This might not necessaryly be true in future Atmel SoCs.
- * This code should be fixed to use a pointer array to the ports.
- */
-
 #include <config.h>
 #include <common.h>
 #include <asm/io.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/at91_pio.h>
 
+static struct at91_port *at91_pio_get_port(unsigned port)
+{
+       switch (port) {
+       case AT91_PIO_PORTA:
+               return (struct at91_port *)ATMEL_BASE_PIOA;
+       case AT91_PIO_PORTB:
+               return (struct at91_port *)ATMEL_BASE_PIOB;
+       case AT91_PIO_PORTC:
+               return (struct at91_port *)ATMEL_BASE_PIOC;
+#if (ATMEL_PIO_PORTS > 3)
+       case AT91_PIO_PORTD:
+               return (struct at91_port *)ATMEL_BASE_PIOD;
+#if (ATMEL_PIO_PORTS > 4)
+       case AT91_PIO_PORTE:
+               return (struct at91_port *)ATMEL_BASE_PIOE;
+#endif
+#endif
+       default:
+               return NULL;
+       }
+}
+
 int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
 {
-       at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
-       u32             mask;
+       struct at91_port *at91_port = at91_pio_get_port(port);
+       u32 mask;
 
-       if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+       if (at91_port && (pin < 32)) {
                mask = 1 << pin;
                if (use_pullup)
-                       writel(1 << pin, &pio->port[port].puer);
+                       writel(1 << pin, &at91_port->puer);
                else
-                       writel(1 << pin, &pio->port[port].pudr);
-               writel(mask, &pio->port[port].per);
+                       writel(1 << pin, &at91_port->pudr);
+               writel(mask, &at91_port->per);
        }
+
        return 0;
 }
 
@@ -46,15 +59,16 @@ int at91_set_pio_pullup(unsigned port, unsigned pin, int use_pullup)
  */
 int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)
 {
-       at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
-       u32             mask;
+       struct at91_port *at91_port = at91_pio_get_port(port);
+       u32 mask;
 
-       if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+       if (at91_port && (pin < 32)) {
                mask = 1 << pin;
-               writel(mask, &pio->port[port].idr);
+               writel(mask, &at91_port->idr);
                at91_set_pio_pullup(port, pin, use_pullup);
-               writel(mask, &pio->port[port].per);
+               writel(mask, &at91_port->per);
        }
+
        return 0;
 }
 
@@ -63,23 +77,24 @@ int at91_set_pio_periph(unsigned port, unsigned pin, int use_pullup)
  */
 int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)
 {
-       at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
-       u32             mask;
+       struct at91_port *at91_port = at91_pio_get_port(port);
+       u32 mask;
 
-       if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+       if (at91_port && (pin < 32)) {
                mask = 1 << pin;
-               writel(mask, &pio->port[port].idr);
+               writel(mask, &at91_port->idr);
                at91_set_pio_pullup(port, pin, use_pullup);
 #if defined(CPU_HAS_PIO3)
-               writel(readl(&pio->port[port].abcdsr1) & ~mask,
-                       &pio->port[port].abcdsr1);
-               writel(readl(&pio->port[port].abcdsr2) & ~mask,
-                       &pio->port[port].abcdsr2);
+               writel(readl(&at91_port->abcdsr1) & ~mask,
+                      &at91_port->abcdsr1);
+               writel(readl(&at91_port->abcdsr2) & ~mask,
+                      &at91_port->abcdsr2);
 #else
-               writel(mask, &pio->port[port].asr);
+               writel(mask, &at91_port->asr);
 #endif
-               writel(mask, &pio->port[port].pdr);
+               writel(mask, &at91_port->pdr);
        }
+
        return 0;
 }
 
@@ -88,23 +103,24 @@ int at91_set_a_periph(unsigned port, unsigned pin, int use_pullup)
  */
 int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)
 {
-       at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
-       u32             mask;
+       struct at91_port *at91_port = at91_pio_get_port(port);
+       u32 mask;
 
-       if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+       if (at91_port && (pin < 32)) {
                mask = 1 << pin;
-               writel(mask, &pio->port[port].idr);
+               writel(mask, &at91_port->idr);
                at91_set_pio_pullup(port, pin, use_pullup);
 #if defined(CPU_HAS_PIO3)
-               writel(readl(&pio->port[port].abcdsr1) | mask,
-                       &pio->port[port].abcdsr1);
-               writel(readl(&pio->port[port].abcdsr2) & ~mask,
-                       &pio->port[port].abcdsr2);
+               writel(readl(&at91_port->abcdsr1) | mask,
+                      &at91_port->abcdsr1);
+               writel(readl(&at91_port->abcdsr2) & ~mask,
+                      &at91_port->abcdsr2);
 #else
-               writel(mask, &pio->port[port].bsr);
+               writel(mask, &at91_port->bsr);
 #endif
-               writel(mask, &pio->port[port].pdr);
+               writel(mask, &at91_port->pdr);
        }
+
        return 0;
 }
 
@@ -114,19 +130,20 @@ int at91_set_b_periph(unsigned port, unsigned pin, int use_pullup)
  */
 int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup)
 {
-       at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
-       u32             mask;
+       struct at91_port *at91_port = at91_pio_get_port(port);
+       u32 mask;
 
-       if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+       if (at91_port && (pin < 32)) {
                mask = 1 << pin;
-               writel(mask, &pio->port[port].idr);
+               writel(mask, &at91_port->idr);
                at91_set_pio_pullup(port, pin, use_pullup);
-               writel(readl(&pio->port[port].abcdsr1) & ~mask,
-                       &pio->port[port].abcdsr1);
-               writel(readl(&pio->port[port].abcdsr2) | mask,
-                       &pio->port[port].abcdsr2);
-               writel(mask, &pio->port[port].pdr);
+               writel(readl(&at91_port->abcdsr1) & ~mask,
+                      &at91_port->abcdsr1);
+               writel(readl(&at91_port->abcdsr2) | mask,
+                      &at91_port->abcdsr2);
+               writel(mask, &at91_port->pdr);
        }
+
        return 0;
 }
 
@@ -135,19 +152,20 @@ int at91_set_c_periph(unsigned port, unsigned pin, int use_pullup)
  */
 int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)
 {
-       at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
-       u32             mask;
+       struct at91_port *at91_port = at91_pio_get_port(port);
+       u32 mask;
 
-       if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+       if (at91_port && (pin < 32)) {
                mask = 1 << pin;
-               writel(mask, &pio->port[port].idr);
+               writel(mask, &at91_port->idr);
                at91_set_pio_pullup(port, pin, use_pullup);
-               writel(readl(&pio->port[port].abcdsr1) | mask,
-                       &pio->port[port].abcdsr1);
-               writel(readl(&pio->port[port].abcdsr2) | mask,
-                       &pio->port[port].abcdsr2);
-               writel(mask, &pio->port[port].pdr);
+               writel(readl(&at91_port->abcdsr1) | mask,
+                      &at91_port->abcdsr1);
+               writel(readl(&at91_port->abcdsr2) | mask,
+                      &at91_port->abcdsr2);
+               writel(mask, &at91_port->pdr);
        }
+
        return 0;
 }
 #endif
@@ -158,16 +176,17 @@ int at91_set_d_periph(unsigned port, unsigned pin, int use_pullup)
  */
 int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
 {
-       at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
-       u32             mask;
+       struct at91_port *at91_port = at91_pio_get_port(port);
+       u32 mask;
 
-       if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+       if (at91_port && (pin < 32)) {
                mask = 1 << pin;
-               writel(mask, &pio->port[port].idr);
+               writel(mask, &at91_port->idr);
                at91_set_pio_pullup(port, pin, use_pullup);
-               writel(mask, &pio->port[port].odr);
-               writel(mask, &pio->port[port].per);
+               writel(mask, &at91_port->odr);
+               writel(mask, &at91_port->per);
        }
+
        return 0;
 }
 
@@ -177,20 +196,21 @@ int at91_set_pio_input(unsigned port, u32 pin, int use_pullup)
  */
 int at91_set_pio_output(unsigned port, u32 pin, int value)
 {
-       at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
-       u32             mask;
+       struct at91_port *at91_port = at91_pio_get_port(port);
+       u32 mask;
 
        if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
                mask = 1 << pin;
-               writel(mask, &pio->port[port].idr);
-               writel(mask, &pio->port[port].pudr);
+               writel(mask, &at91_port->idr);
+               writel(mask, &at91_port->pudr);
                if (value)
-                       writel(mask, &pio->port[port].sodr);
+                       writel(mask, &at91_port->sodr);
                else
-                       writel(mask, &pio->port[port].codr);
-               writel(mask, &pio->port[port].oer);
-               writel(mask, &pio->port[port].per);
+                       writel(mask, &at91_port->codr);
+               writel(mask, &at91_port->oer);
+               writel(mask, &at91_port->per);
        }
+
        return 0;
 }
 
@@ -199,20 +219,21 @@ int at91_set_pio_output(unsigned port, u32 pin, int value)
  */
 int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)
 {
-       at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
-       u32             mask;
+       struct at91_port *at91_port = at91_pio_get_port(port);
+       u32 mask;
 
-       if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+       if (at91_port && (pin < 32)) {
                mask = 1 << pin;
                if (is_on) {
 #if defined(CPU_HAS_PIO3)
-                       writel(mask, &pio->port[port].ifscdr);
+                       writel(mask, &at91_port->ifscdr);
 #endif
-                       writel(mask, &pio->port[port].ifer);
+                       writel(mask, &at91_port->ifer);
                } else {
-                       writel(mask, &pio->port[port].ifdr);
+                       writel(mask, &at91_port->ifdr);
                }
        }
+
        return 0;
 }
 
@@ -222,19 +243,20 @@ int at91_set_pio_deglitch(unsigned port, unsigned pin, int is_on)
  */
 int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div)
 {
-       at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
-       u32             mask;
+       struct at91_port *at91_port = at91_pio_get_port(port);
+       u32 mask;
 
-       if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+       if (at91_port && (pin < 32)) {
                mask = 1 << pin;
                if (is_on) {
-                       writel(mask, &pio->port[port].ifscer);
-                       writel(div & PIO_SCDR_DIV, &pio->port[port].scdr);
-                       writel(mask, &pio->port[port].ifer);
+                       writel(mask, &at91_port->ifscer);
+                       writel(div & PIO_SCDR_DIV, &at91_port->scdr);
+                       writel(mask, &at91_port->ifer);
                } else {
-                       writel(mask, &pio->port[port].ifdr);
+                       writel(mask, &at91_port->ifdr);
                }
        }
+
        return 0;
 }
 
@@ -244,17 +266,18 @@ int at91_set_pio_debounce(unsigned port, unsigned pin, int is_on, int div)
  */
 int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on)
 {
-       at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
-       u32             mask;
+       struct at91_port *at91_port = at91_pio_get_port(port);
+       u32 mask;
 
-       if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+       if (at91_port && (pin < 32)) {
                mask = 1 << pin;
-               writel(mask, &pio->port[port].pudr);
+               writel(mask, &at91_port->pudr);
                if (is_on)
-                       writel(mask, &pio->port[port].ppder);
+                       writel(mask, &at91_port->ppder);
                else
-                       writel(mask, &pio->port[port].ppddr);
+                       writel(mask, &at91_port->ppddr);
        }
+
        return 0;
 }
 
@@ -263,14 +286,15 @@ int at91_set_pio_pulldown(unsigned port, unsigned pin, int is_on)
  */
 int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin)
 {
-       at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
-       u32             mask;
+       struct at91_port *at91_port = at91_pio_get_port(port);
+       u32 mask;
 
-       if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+       if (at91_port && (pin < 32)) {
                mask = 1 << pin;
-               writel(readl(&pio->port[port].schmitt) | mask,
-                       &pio->port[port].schmitt);
+               writel(readl(&at91_port->schmitt) | mask,
+                      &at91_port->schmitt);
        }
+
        return 0;
 }
 #endif
@@ -281,16 +305,17 @@ int at91_set_pio_disable_schmitt_trig(unsigned port, unsigned pin)
  */
 int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
 {
-       at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
-       u32             mask;
+       struct at91_port *at91_port = at91_pio_get_port(port);
+       u32 mask;
 
-       if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+       if (at91_port && (pin < 32)) {
                mask = 1 << pin;
                if (is_on)
-                       writel(mask, &pio->port[port].mder);
+                       writel(mask, &at91_port->mder);
                else
-                       writel(mask, &pio->port[port].mddr);
+                       writel(mask, &at91_port->mddr);
        }
+
        return 0;
 }
 
@@ -299,16 +324,17 @@ int at91_set_pio_multi_drive(unsigned port, unsigned pin, int is_on)
  */
 int at91_set_pio_value(unsigned port, unsigned pin, int value)
 {
-       at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
-       u32             mask;
+       struct at91_port *at91_port = at91_pio_get_port(port);
+       u32 mask;
 
-       if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+       if (at91_port && (pin < 32)) {
                mask = 1 << pin;
                if (value)
-                       writel(mask, &pio->port[port].sodr);
+                       writel(mask, &at91_port->sodr);
                else
-                       writel(mask, &pio->port[port].codr);
+                       writel(mask, &at91_port->codr);
        }
+
        return 0;
 }
 
@@ -317,13 +343,56 @@ int at91_set_pio_value(unsigned port, unsigned pin, int value)
  */
 int at91_get_pio_value(unsigned port, unsigned pin)
 {
-       u32             pdsr = 0;
-       at91_pio_t      *pio = (at91_pio_t *) ATMEL_BASE_PIOA;
-       u32             mask;
+       struct at91_port *at91_port = at91_pio_get_port(port);
+       u32 pdsr = 0, mask;
 
-       if ((port < ATMEL_PIO_PORTS) && (pin < 32)) {
+       if (at91_port && (pin < 32)) {
                mask = 1 << pin;
-               pdsr = readl(&pio->port[port].pdsr) & mask;
+               pdsr = readl(&at91_port->pdsr) & mask;
        }
+
        return pdsr != 0;
 }
+
+/* Common GPIO API */
+
+#define at91_gpio_to_port(gpio)                (gpio / 32)
+#define at91_gpio_to_pin(gpio)         (gpio % 32)
+
+int gpio_request(unsigned gpio, const char *label)
+{
+       return 0;
+}
+
+int gpio_free(unsigned gpio)
+{
+       return 0;
+}
+
+int gpio_direction_input(unsigned gpio)
+{
+       at91_set_pio_input(at91_gpio_to_port(gpio),
+                          at91_gpio_to_pin(gpio), 0);
+       return 0;
+}
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+       at91_set_pio_output(at91_gpio_to_port(gpio),
+                           at91_gpio_to_pin(gpio), value);
+       return 0;
+}
+
+int gpio_get_value(unsigned gpio)
+{
+       return at91_get_pio_value(at91_gpio_to_port(gpio),
+                                 at91_gpio_to_pin(gpio));
+}
+
+int gpio_set_value(unsigned gpio, int value)
+{
+       at91_set_pio_value(at91_gpio_to_port(gpio),
+                          at91_gpio_to_pin(gpio), value);
+
+       return 0;
+}
index e5a5d7532c9a918f0d08634fa09d1603b3e4eec8..245f9d0c6724a6ac865ac663effb55cfe5d5bfec 100644 (file)
@@ -410,7 +410,8 @@ int mxsmmc_initialize(bd_t *bis, int id, int (*wp)(int), int (*cd)(int))
        mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
 
        mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT |
-                        MMC_MODE_HS_52MHz | MMC_MODE_HS;
+                        MMC_MODE_HS_52MHz | MMC_MODE_HS |
+                        MMC_MODE_HC;
 
        /*
         * SSPCLK = 480 * 18 / 29 / 1 = 297.731 MHz
index f844990e381782803c99f350f60c52c8bd0b6368..da83f06e4734d186eb3661f8938bcad039e871a2 100644 (file)
@@ -16,6 +16,7 @@
 #include <asm/arch/gpio.h>
 #include <asm/arch/at91_pio.h>
 
+#include <malloc.h>
 #include <nand.h>
 #include <watchdog.h>
 
@@ -50,13 +51,13 @@ struct atmel_nand_host {
        void __iomem    *pmecc_index_of;
 
        /* data for pmecc computation */
-       int16_t pmecc_smu[(CONFIG_PMECC_CAP + 2) * (2 * CONFIG_PMECC_CAP + 1)];
-       int16_t pmecc_partial_syn[2 * CONFIG_PMECC_CAP + 1];
-       int16_t pmecc_si[2 * CONFIG_PMECC_CAP + 1];
-       int16_t pmecc_lmu[CONFIG_PMECC_CAP + 1]; /* polynomal order */
-       int     pmecc_mu[CONFIG_PMECC_CAP + 1];
-       int     pmecc_dmu[CONFIG_PMECC_CAP + 1];
-       int     pmecc_delta[CONFIG_PMECC_CAP + 1];
+       int16_t *pmecc_smu;
+       int16_t *pmecc_partial_syn;
+       int16_t *pmecc_si;
+       int16_t *pmecc_lmu; /* polynomal order */
+       int     *pmecc_mu;
+       int     *pmecc_dmu;
+       int     *pmecc_delta;
 };
 
 static struct atmel_nand_host pmecc_host;
@@ -109,6 +110,48 @@ static void __iomem *pmecc_get_alpha_to(struct atmel_nand_host *host)
                        table_size * sizeof(int16_t);
 }
 
+static void pmecc_data_free(struct atmel_nand_host *host)
+{
+       free(host->pmecc_partial_syn);
+       free(host->pmecc_si);
+       free(host->pmecc_lmu);
+       free(host->pmecc_smu);
+       free(host->pmecc_mu);
+       free(host->pmecc_dmu);
+       free(host->pmecc_delta);
+}
+
+static int pmecc_data_alloc(struct atmel_nand_host *host)
+{
+       const int cap = host->pmecc_corr_cap;
+       int size;
+
+       size = (2 * cap + 1) * sizeof(int16_t);
+       host->pmecc_partial_syn = malloc(size);
+       host->pmecc_si = malloc(size);
+       host->pmecc_lmu = malloc((cap + 1) * sizeof(int16_t));
+       host->pmecc_smu = malloc((cap + 2) * size);
+
+       size = (cap + 1) * sizeof(int);
+       host->pmecc_mu = malloc(size);
+       host->pmecc_dmu = malloc(size);
+       host->pmecc_delta = malloc(size);
+
+       if (host->pmecc_partial_syn &&
+                       host->pmecc_si &&
+                       host->pmecc_lmu &&
+                       host->pmecc_smu &&
+                       host->pmecc_mu &&
+                       host->pmecc_dmu &&
+                       host->pmecc_delta)
+               return 0;
+
+       /* error happened */
+       pmecc_data_free(host);
+       return -ENOMEM;
+
+}
+
 static void pmecc_gen_syndrome(struct mtd_info *mtd, int sector)
 {
        struct nand_chip *nand_chip = mtd->priv;
@@ -622,6 +665,99 @@ static void atmel_pmecc_core_init(struct mtd_info *mtd)
        pmecc_writel(host->pmecc, ctrl, PMECC_CTRL_ENABLE);
 }
 
+#ifdef CONFIG_SYS_NAND_ONFI_DETECTION
+/*
+ * get_onfi_ecc_param - Get ECC requirement from ONFI parameters
+ * @ecc_bits: store the ONFI ECC correct bits capbility
+ * @sector_size: in how many bytes that ONFI require to correct @ecc_bits
+ *
+ * Returns -1 if ONFI parameters is not supported. In this case @ecc_bits,
+ * @sector_size are initialize to 0.
+ * Return 0 if success to get the ECC requirement.
+ */
+static int get_onfi_ecc_param(struct nand_chip *chip,
+               int *ecc_bits, int *sector_size)
+{
+       *ecc_bits = *sector_size = 0;
+
+       if (chip->onfi_params.ecc_bits == 0xff)
+               /* TODO: the sector_size and ecc_bits need to be find in
+                * extended ecc parameter, currently we don't support it.
+                */
+               return -1;
+
+       *ecc_bits = chip->onfi_params.ecc_bits;
+
+       /* The default sector size (ecc codeword size) is 512 */
+       *sector_size = 512;
+
+       return 0;
+}
+
+/*
+ * pmecc_choose_ecc - Get ecc requirement from ONFI parameters. If
+ *                    pmecc_corr_cap or pmecc_sector_size is 0, then set it as
+ *                    ONFI ECC parameters.
+ * @host: point to an atmel_nand_host structure.
+ *        if host->pmecc_corr_cap is 0 then set it as the ONFI ecc_bits.
+ *        if host->pmecc_sector_size is 0 then set it as the ONFI sector_size.
+ * @chip: point to an nand_chip structure.
+ * @cap: store the ONFI ECC correct bits capbility
+ * @sector_size: in how many bytes that ONFI require to correct @ecc_bits
+ *
+ * Return 0 if success. otherwise return the error code.
+ */
+static int pmecc_choose_ecc(struct atmel_nand_host *host,
+               struct nand_chip *chip,
+               int *cap, int *sector_size)
+{
+       /* Get ECC requirement from ONFI parameters */
+       *cap = *sector_size = 0;
+       if (chip->onfi_version) {
+               if (!get_onfi_ecc_param(chip, cap, sector_size)) {
+                       MTDDEBUG(MTD_DEBUG_LEVEL1, "ONFI params, minimum required ECC: %d bits in %d bytes\n",
+                               *cap, *sector_size);
+               } else {
+                       dev_info(host->dev, "NAND chip ECC reqirement is in Extended ONFI parameter, we don't support yet.\n");
+               }
+       } else {
+               dev_info(host->dev, "NAND chip is not ONFI compliant, assume ecc_bits is 2 in 512 bytes");
+       }
+       if (*cap == 0 && *sector_size == 0) {
+               /* Non-ONFI compliant or use extended ONFI parameters */
+               *cap = 2;
+               *sector_size = 512;
+       }
+
+       /* If head file doesn't specify then use the one in ONFI parameters */
+       if (host->pmecc_corr_cap == 0) {
+               /* use the most fitable ecc bits (the near bigger one ) */
+               if (*cap <= 2)
+                       host->pmecc_corr_cap = 2;
+               else if (*cap <= 4)
+                       host->pmecc_corr_cap = 4;
+               else if (*cap <= 8)
+                       host->pmecc_corr_cap = 8;
+               else if (*cap <= 12)
+                       host->pmecc_corr_cap = 12;
+               else if (*cap <= 24)
+                       host->pmecc_corr_cap = 24;
+               else
+                       return -EINVAL;
+       }
+       if (host->pmecc_sector_size == 0) {
+               /* use the most fitable sector size (the near smaller one ) */
+               if (*sector_size >= 1024)
+                       host->pmecc_sector_size = 1024;
+               else if (*sector_size >= 512)
+                       host->pmecc_sector_size = 512;
+               else
+                       return -EINVAL;
+       }
+       return 0;
+}
+#endif
+
 static int atmel_pmecc_nand_init_params(struct nand_chip *nand,
                struct mtd_info *mtd)
 {
@@ -635,9 +771,45 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand,
        nand->ecc.correct = NULL;
        nand->ecc.hwctl = NULL;
 
-       cap = host->pmecc_corr_cap = CONFIG_PMECC_CAP;
-       sector_size = host->pmecc_sector_size = CONFIG_PMECC_SECTOR_SIZE;
-       host->pmecc_index_table_offset = CONFIG_PMECC_INDEX_TABLE_OFFSET;
+#ifdef CONFIG_SYS_NAND_ONFI_DETECTION
+       host->pmecc_corr_cap = host->pmecc_sector_size = 0;
+
+#ifdef CONFIG_PMECC_CAP
+       host->pmecc_corr_cap = CONFIG_PMECC_CAP;
+#endif
+#ifdef CONFIG_PMECC_SECTOR_SIZE
+       host->pmecc_sector_size = CONFIG_PMECC_SECTOR_SIZE;
+#endif
+       /* Get ECC requirement of ONFI parameters. And if CONFIG_PMECC_CAP or
+        * CONFIG_PMECC_SECTOR_SIZE not defined, then use ecc_bits, sector_size
+        * from ONFI.
+        */
+       if (pmecc_choose_ecc(host, nand, &cap, &sector_size)) {
+               dev_err(host->dev, "The NAND flash's ECC requirement(ecc_bits: %d, sector_size: %d) are not support!",
+                               cap, sector_size);
+               return -EINVAL;
+       }
+
+       if (cap > host->pmecc_corr_cap)
+               dev_info(host->dev, "WARNING: Using different ecc correct bits(%d bit) from Nand ONFI ECC reqirement (%d bit).\n",
+                               host->pmecc_corr_cap, cap);
+       if (sector_size < host->pmecc_sector_size)
+               dev_info(host->dev, "WARNING: Using different ecc correct sector size (%d bytes) from Nand ONFI ECC reqirement (%d bytes).\n",
+                               host->pmecc_sector_size, sector_size);
+#else  /* CONFIG_SYS_NAND_ONFI_DETECTION */
+       host->pmecc_corr_cap = CONFIG_PMECC_CAP;
+       host->pmecc_sector_size = CONFIG_PMECC_SECTOR_SIZE;
+#endif
+
+       cap = host->pmecc_corr_cap;
+       sector_size = host->pmecc_sector_size;
+
+       /* TODO: need check whether cap & sector_size is validate */
+
+       if (host->pmecc_sector_size == 512)
+               host->pmecc_index_table_offset = ATMEL_PMECC_INDEX_OFFSET_512;
+       else
+               host->pmecc_index_table_offset = ATMEL_PMECC_INDEX_OFFSET_1024;
 
        MTDDEBUG(MTD_DEBUG_LEVEL1,
                "Initialize PMECC params, cap: %d, sector: %d\n",
@@ -655,7 +827,8 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand,
        switch (mtd->writesize) {
        case 2048:
        case 4096:
-               host->pmecc_degree = PMECC_GF_DIMENSION_13;
+               host->pmecc_degree = (sector_size == 512) ?
+                       PMECC_GF_DIMENSION_13 : PMECC_GF_DIMENSION_14;
                host->pmecc_cw_len = (1 << host->pmecc_degree) - 1;
                host->pmecc_sector_number = mtd->writesize / sector_size;
                host->pmecc_bytes_per_sector = pmecc_get_ecc_bytes(
@@ -691,6 +864,12 @@ static int atmel_pmecc_nand_init_params(struct nand_chip *nand,
                return 0;
        }
 
+       /* Allocate data for PMECC computation */
+       if (pmecc_data_alloc(host)) {
+               dev_err(host->dev, "Cannot allocate memory for PMECC computation!\n");
+               return -ENOMEM;
+       }
+
        nand->ecc.read_page = atmel_nand_pmecc_read_page;
        nand->ecc.write_page = atmel_nand_pmecc_write_page;
        nand->ecc.strength = cap;
index e14a3598ca3e91465cafd2d613a84d807ca1ffd1..690e5724b4e57418c50a17306d8b340857ec15a0 100644 (file)
@@ -980,6 +980,8 @@ static int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
        if (fec_get_hwaddr(edev, dev_id, ethaddr) == 0) {
                debug("got MAC%d address from fuse: %pM\n", dev_id, ethaddr);
                memcpy(edev->enetaddr, ethaddr, 6);
+               if (!getenv("ethaddr"))
+                       eth_setenv_enetaddr("ethaddr", ethaddr);
        }
        return ret;
 err3:
index 1f7cc322e0533b87d2da41f574e849244f4f8d73..bf3983a00c67a5ce8b51292955f1a24064691dd9 100644 (file)
@@ -36,6 +36,7 @@
 #include <asm/io.h>
 #include <asm/dma-mapping.h>
 #include <asm/arch/clk.h>
+#include <asm-generic/errno.h>
 
 #include "macb.h"
 
@@ -397,9 +398,14 @@ static int macb_phy_init(struct macb_device *macb)
        }
 
 #ifdef CONFIG_PHYLIB
-       phydev->bus = macb->bus;
-       phydev->dev = netdev;
-       phydev->addr = macb->phy_addr;
+       /* need to consider other phy interface mode */
+       phydev = phy_connect(macb->bus, macb->phy_addr, netdev,
+                            PHY_INTERFACE_MODE_RGMII);
+       if (!phydev) {
+               printf("phy_connect failed\n");
+               return -ENODEV;
+       }
+
        phy_config(phydev);
 #endif
 
index 697f2bb4e8d31d0e072343fd2b026491790e96c4..4c45bfa363f14af03384102d3a5b373e146dbe44 100644 (file)
@@ -38,6 +38,7 @@ COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o
 COBJS-$(CONFIG_ZYNQ_SERIAL) += serial_zynq.o
 COBJS-$(CONFIG_BFIN_SERIAL) += serial_bfin.o
 COBJS-$(CONFIG_FSL_LPUART) += serial_lpuart.o
+COBJS-$(CONFIG_MXS_AUART) += mxs_auart.o
 
 ifndef CONFIG_SPL_BUILD
 COBJS-$(CONFIG_USB_TTY) += usbtty.o
diff --git a/drivers/serial/mxs_auart.c b/drivers/serial/mxs_auart.c
new file mode 100644 (file)
index 0000000..7cfe5bc
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Freescale i.MX23/i.MX28 AUART driver
+ *
+ * Copyright (C) 2013 Andreas Wass <andreas.wass@dalelven.com>
+ *
+ * Based on the MXC serial driver:
+ *
+ * (c) 2007 Sascha Hauer <s.hauer@pengutronix.de>
+ *
+ * Further based on the Linux mxs-auart.c driver:
+ *
+ * Freescale STMP37XX/STMP38X Application UART drkiver
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <serial.h>
+#include <linux/compiler.h>
+#include <asm/arch/regs-base.h>
+#include <asm/arch/regs-uartapp.h>
+#include <asm/arch/sys_proto.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifndef CONFIG_MXS_AUART_BASE
+#error "CONFIG_MXS_AUART_BASE must be set to the base UART to use"
+#endif
+
+/* AUART clock always supplied by XTAL and always 24MHz */
+#define MXS_AUART_CLK 24000000
+
+static struct mxs_uartapp_regs *get_uartapp_registers(void)
+{
+       return (struct mxs_uartapp_regs *)CONFIG_MXS_AUART_BASE;
+}
+
+/**
+ * Sets the baud rate and settings.
+ * The settings are: 8 data bits, no parit and 1 stop bit.
+ */
+void mxs_auart_setbrg(void)
+{
+       u32 div;
+       u32 linectrl = 0;
+       struct mxs_uartapp_regs *regs = get_uartapp_registers();
+
+       if (!gd->baudrate)
+               gd->baudrate = CONFIG_BAUDRATE;
+
+       /*
+        * From i.MX28 datasheet:
+        * div is calculated by calculating UARTCLK*32/baudrate, rounded to int
+        * div must be between 0xEC and 0x003FFFC0 inclusive
+        * Lowest 6 bits of div goes in BAUD_DIVFRAC part of LINECTRL register
+        * Next 16 bits goes in BAUD_DIVINT part of LINECTRL register
+        */
+       div = (MXS_AUART_CLK * 32) / gd->baudrate;
+       if (div < 0xEC || div > 0x003FFFC0)
+               return;
+
+       linectrl |= ((div & UARTAPP_LINECTRL_EXTRACT_BAUD_DIVFRAC_MASK) <<
+               UARTAPP_LINECTRL_BAUD_DIVFRAC_OFFSET) &
+               UARTAPP_LINECTRL_BAUD_DIVFRAC_MASK;
+       linectrl |= ((div >> UARTAPP_LINECTRL_EXTRACT_BAUD_DIVINT_OFFSET) <<
+               UARTAPP_LINECTRL_BAUD_DIVINT_OFFSET) &
+               UARTAPP_LINECTRL_BAUD_DIVINT_MASK;
+
+       /* Word length: 8 bits */
+       linectrl |= UARTAPP_LINECTRL_WLEN_8BITS;
+
+       /* Enable FIFOs. */
+       linectrl |= UARTAPP_LINECTRL_FEN_MASK;
+
+       /* Write above settings, no parity, 1 stop bit */
+       writel(linectrl, &regs->hw_uartapp_linectrl);
+}
+
+int mxs_auart_init(void)
+{
+       struct mxs_uartapp_regs *regs = get_uartapp_registers();
+       /* Reset everything */
+       mxs_reset_block(&regs->hw_uartapp_ctrl0_reg);
+       /* Disable interrupts */
+       writel(0, &regs->hw_uartapp_intr);
+       /* Set baud rate and settings */
+       serial_setbrg();
+       /* Disable RTS and CTS, ignore LINECTRL2 register */
+       writel(UARTAPP_CTRL2_RTSEN_MASK |
+                       UARTAPP_CTRL2_CTSEN_MASK |
+                       UARTAPP_CTRL2_USE_LCR2_MASK,
+                       &regs->hw_uartapp_ctrl2_clr);
+       /* Enable receiver, transmitter and UART */
+       writel(UARTAPP_CTRL2_RXE_MASK |
+                       UARTAPP_CTRL2_TXE_MASK |
+                       UARTAPP_CTRL2_UARTEN_MASK,
+                       &regs->hw_uartapp_ctrl2_set);
+       return 0;
+}
+
+void mxs_auart_putc(const char c)
+{
+       struct mxs_uartapp_regs *regs = get_uartapp_registers();
+       /* Wait in loop while the transmit FIFO is full */
+       while (readl(&regs->hw_uartapp_stat) & UARTAPP_STAT_TXFF_MASK)
+               ;
+
+       writel(c, &regs->hw_uartapp_data);
+
+       if (c == '\n')
+               mxs_auart_putc('\r');
+}
+
+int mxs_auart_tstc(void)
+{
+       struct mxs_uartapp_regs *regs = get_uartapp_registers();
+       /* Checks if receive FIFO is empty */
+       return !(readl(&regs->hw_uartapp_stat) & UARTAPP_STAT_RXFE_MASK);
+}
+
+int mxs_auart_getc(void)
+{
+       struct mxs_uartapp_regs *regs = get_uartapp_registers();
+       /* Wait until a character is available to read */
+       while (!mxs_auart_tstc())
+               ;
+       /* Read the character from the data register */
+       return readl(&regs->hw_uartapp_data) & 0xFF;
+}
+
+static struct serial_device mxs_auart_drv = {
+       .name = "mxs_auart_serial",
+       .start = mxs_auart_init,
+       .stop = NULL,
+       .setbrg = mxs_auart_setbrg,
+       .putc = mxs_auart_putc,
+       .puts = default_serial_puts,
+       .getc = mxs_auart_getc,
+       .tstc = mxs_auart_tstc,
+};
+
+void mxs_auart_initialize(void)
+{
+       serial_register(&mxs_auart_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+       return &mxs_auart_drv;
+}
index 118fbc305ca721ae980f8a6cf22d078d35c9df1c..35dc61e020c04b5e0efc37df211e28fff8f2a67d 100644 (file)
@@ -160,6 +160,7 @@ serial_initfunc(s3c44b0_serial_initialize);
 serial_initfunc(sa1100_serial_initialize);
 serial_initfunc(sh_serial_initialize);
 serial_initfunc(arm_dcc_initialize);
+serial_initfunc(mxs_auart_initialize);
 
 /**
  * serial_register() - Register serial driver with serial driver core
@@ -253,6 +254,7 @@ void serial_initialize(void)
        sa1100_serial_initialize();
        sh_serial_initialize();
        arm_dcc_initialize();
+       mxs_auart_initialize();
 
        serial_assign(default_serial_console()->name);
 }
index 72c8c2bad1940c68993f2019fa11e31f0a708339..d7a5663deb31aa12dc04408937e3e0800257a437 100644 (file)
@@ -39,15 +39,6 @@ typedef unsigned long dmaaddr_t;
 #define cpu_relax() do {} while (0)
 
 #define pr_debug(fmt, args...) debug(fmt, ##args)
-#define dev_dbg(dev, fmt, args...)             \
-       debug(fmt, ##args)
-#define dev_vdbg(dev, fmt, args...)            \
-       debug(fmt, ##args)
-#define dev_info(dev, fmt, args...)            \
-       printf(fmt, ##args)
-#define dev_err(dev, fmt, args...)             \
-       printf(fmt, ##args)
-#define printk printf
 
 #define WARN(condition, fmt, args...) ({       \
        int ret_warn = !!condition;             \
@@ -55,13 +46,6 @@ typedef unsigned long dmaaddr_t;
                printf(fmt, ##args);            \
        ret_warn; })
 
-#define KERN_DEBUG
-#define KERN_NOTICE
-#define KERN_WARNING
-#define KERN_ERR
-
-#define kfree(ptr) free(ptr)
-
 #define pm_runtime_get_sync(dev) do {} while (0)
 #define pm_runtime_put(dev) do {} while (0)
 #define pm_runtime_put_sync(dev) do {} while (0)
index 6dee1e930e4f9451ccb85a3c99a7b6b34ab3fed2..6c208c596e1eb0722c80bd84cbc645552ff07a1d 100644 (file)
@@ -41,6 +41,7 @@ COBJS-$(CONFIG_VIDEO_SM501) += sm501.o
 COBJS-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o
 COBJS-$(CONFIG_VIDEO_TEGRA) += tegra.o
 COBJS-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o
+COBJS-$(CONFIG_FORMIKE) += formike.o
 
 COBJS  := $(sort $(COBJS-y))
 SRCS   := $(COBJS:.o=.c)
diff --git a/drivers/video/formike.c b/drivers/video/formike.c
new file mode 100644 (file)
index 0000000..b9b6822
--- /dev/null
@@ -0,0 +1,511 @@
+/*
+ * LCD: Formike, TFT 4.3", 480x800, RGB24, KWH043ST20-F01, DriverIC NT35510-16
+ * LCD initialization via SPI
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ * Based on:
+ *
+ */
+#include <common.h>
+#include <errno.h>
+#include <spi.h>
+
+#define TAG_READ       0x80
+#define TAG_WRITE      0x00
+
+#define TAG_DATA       0x40
+#define TAG_COMMAND    0x00
+
+#define TAG_ADDR_H     0x20
+#define TAG_ADDR_L     0x00
+
+static int spi_write_tag_val(struct spi_slave *spi, unsigned char tag,
+                            unsigned char val)
+{
+       unsigned long flags = SPI_XFER_BEGIN;
+       u8 buf[2];
+       int ret;
+
+       buf[0] = tag;
+       buf[1] = val;
+       flags |= SPI_XFER_END;
+
+       ret = spi_xfer(spi, 16, buf, NULL, flags);
+#ifdef KWH043ST20_F01_SPI_DEBUG
+       printf("spi_write_tag_val: tag=%02X, val=%02X ret: %d\n",
+              tag, val, ret);
+#endif /* KWH043ST20_F01_SPI_DEBUG */
+       if (ret)
+               debug("%s: Failed to send: %d\n", __func__, ret);
+
+       return ret;
+}
+
+static void spi_write_dat(struct spi_slave *spi, unsigned int val)
+{
+       spi_write_tag_val(spi, TAG_WRITE|TAG_DATA, val);
+}
+
+static void spi_write_com(struct spi_slave *spi, unsigned int addr)
+{
+       spi_write_tag_val(spi, TAG_WRITE|TAG_COMMAND|TAG_ADDR_H,
+                         (addr & 0xff00) >> 8);
+       spi_write_tag_val(spi, TAG_WRITE|TAG_COMMAND|TAG_ADDR_L,
+                         (addr & 0x00ff) >> 0);
+}
+
+int kwh043st20_f01_spi_startup(unsigned int bus, unsigned int cs,
+       unsigned int max_hz, unsigned int spi_mode)
+{
+       struct spi_slave *spi;
+       int ret;
+
+       spi = spi_setup_slave(bus, cs, max_hz, spi_mode);
+       if (!spi) {
+               debug("%s: Failed to set up slave\n", __func__);
+               return -1;
+       }
+
+       ret = spi_claim_bus(spi);
+       if (ret) {
+               debug("%s: Failed to claim SPI bus: %d\n", __func__, ret);
+               goto err_claim_bus;
+       }
+
+
+       /* LV2 Page 1 enable */
+       spi_write_com(spi, 0xF000);     spi_write_dat(spi, 0x55);
+       spi_write_com(spi, 0xF001);     spi_write_dat(spi, 0xAA);
+       spi_write_com(spi, 0xF002);     spi_write_dat(spi, 0x52);
+       spi_write_com(spi, 0xF003);     spi_write_dat(spi, 0x08);
+       spi_write_com(spi, 0xF004);     spi_write_dat(spi, 0x01);
+
+       /* AVDD Set AVDD 5.2V */
+       spi_write_com(spi, 0xB000);     spi_write_dat(spi, 0x0D);
+       spi_write_com(spi, 0xB001);     spi_write_dat(spi, 0x0D);
+       spi_write_com(spi, 0xB002);     spi_write_dat(spi, 0x0D);
+
+       /* AVDD ratio */
+       spi_write_com(spi, 0xB600);     spi_write_dat(spi, 0x34);
+       spi_write_com(spi, 0xB601);     spi_write_dat(spi, 0x34);
+       spi_write_com(spi, 0xB602);     spi_write_dat(spi, 0x34);
+
+       /* AVEE  -5.2V */
+       spi_write_com(spi, 0xB100);     spi_write_dat(spi, 0x0D);
+       spi_write_com(spi, 0xB101);     spi_write_dat(spi, 0x0D);
+       spi_write_com(spi, 0xB102);     spi_write_dat(spi, 0x0D);
+
+       /* AVEE ratio */
+       spi_write_com(spi, 0xB700);     spi_write_dat(spi, 0x35);
+       spi_write_com(spi, 0xB701);     spi_write_dat(spi, 0x35);
+       spi_write_com(spi, 0xB702);     spi_write_dat(spi, 0x35);
+
+       /* VCL  -2.5V */
+       spi_write_com(spi, 0xB200);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xB201);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xB202);     spi_write_dat(spi, 0x00);
+
+       /* VCL ratio */
+       spi_write_com(spi, 0xB800);     spi_write_dat(spi, 0x24);
+       spi_write_com(spi, 0xB801);     spi_write_dat(spi, 0x24);
+       spi_write_com(spi, 0xB802);     spi_write_dat(spi, 0x24);
+
+       /* VGH 15V */
+       spi_write_com(spi, 0xBF00);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xB300);     spi_write_dat(spi, 0x08);
+       spi_write_com(spi, 0xB301);     spi_write_dat(spi, 0x08);
+       spi_write_com(spi, 0xB302);     spi_write_dat(spi, 0x08);
+
+       /* VGH ratio */
+       spi_write_com(spi, 0xB900);     spi_write_dat(spi, 0x34);
+       spi_write_com(spi, 0xB901);     spi_write_dat(spi, 0x34);
+       spi_write_com(spi, 0xB902);     spi_write_dat(spi, 0x34);
+
+       /* VGLX ratio */
+       spi_write_com(spi, 0xBA00);     spi_write_dat(spi, 0x24);
+       spi_write_com(spi, 0xBA01);     spi_write_dat(spi, 0x24);
+       spi_write_com(spi, 0xBA02);     spi_write_dat(spi, 0x24);
+
+       /* VGMP/VGSP 4.7V/0V */
+       spi_write_com(spi, 0xBC00);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xBC01);     spi_write_dat(spi, 0x88);
+       spi_write_com(spi, 0xBC02);     spi_write_dat(spi, 0x00);
+
+       /* VGMN/VGSN -4.7V/0V */
+       spi_write_com(spi, 0xBD00);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xBD01);     spi_write_dat(spi, 0x88);
+       spi_write_com(spi, 0xBD02);     spi_write_dat(spi, 0x00);
+
+       /* VCOM 1.525V */
+       spi_write_com(spi, 0xBE00);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xBE01);     spi_write_dat(spi, 0x7A);
+
+       /* Gamma Setting */
+       spi_write_com(spi, 0xD100);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD101);     spi_write_dat(spi, 0x05);
+       spi_write_com(spi, 0xD102);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD103);     spi_write_dat(spi, 0x15);
+       spi_write_com(spi, 0xD104);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD105);     spi_write_dat(spi, 0x30);
+       spi_write_com(spi, 0xD106);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD107);     spi_write_dat(spi, 0x47);
+       spi_write_com(spi, 0xD108);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD109);     spi_write_dat(spi, 0x5B);
+       spi_write_com(spi, 0xD10A);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD10B);     spi_write_dat(spi, 0x7D);
+       spi_write_com(spi, 0xD10C);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD10D);     spi_write_dat(spi, 0x9D);
+       spi_write_com(spi, 0xD10E);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD10F);     spi_write_dat(spi, 0xCC);
+       spi_write_com(spi, 0xD110);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD111);     spi_write_dat(spi, 0xF3);
+       spi_write_com(spi, 0xD112);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD113);     spi_write_dat(spi, 0x32);
+       spi_write_com(spi, 0xD114);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD115);     spi_write_dat(spi, 0x63);
+       spi_write_com(spi, 0xD116);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD117);     spi_write_dat(spi, 0xB1);
+       spi_write_com(spi, 0xD118);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD119);     spi_write_dat(spi, 0xF0);
+       spi_write_com(spi, 0xD11A);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD11B);     spi_write_dat(spi, 0xF2);
+       spi_write_com(spi, 0xD11C);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD11D);     spi_write_dat(spi, 0x2A);
+       spi_write_com(spi, 0xD11E);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD11F);     spi_write_dat(spi, 0x67);
+       spi_write_com(spi, 0xD120);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD121);     spi_write_dat(spi, 0x90);
+       spi_write_com(spi, 0xD122);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD123);     spi_write_dat(spi, 0xCB);
+       spi_write_com(spi, 0xD124);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD125);     spi_write_dat(spi, 0xF2);
+       spi_write_com(spi, 0xD126);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD127);     spi_write_dat(spi, 0x2A);
+       spi_write_com(spi, 0xD128);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD129);     spi_write_dat(spi, 0x51);
+       spi_write_com(spi, 0xD12A);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD12B);     spi_write_dat(spi, 0x80);
+       spi_write_com(spi, 0xD12C);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD12D);     spi_write_dat(spi, 0x9F);
+       spi_write_com(spi, 0xD12E);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD12F);     spi_write_dat(spi, 0xBE);
+       spi_write_com(spi, 0xD130);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD131);     spi_write_dat(spi, 0xF9);
+       spi_write_com(spi, 0xD132);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD133);     spi_write_dat(spi, 0xFF);
+
+       spi_write_com(spi, 0xD200);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD201);     spi_write_dat(spi, 0x05);
+       spi_write_com(spi, 0xD202);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD203);     spi_write_dat(spi, 0x15);
+       spi_write_com(spi, 0xD204);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD205);     spi_write_dat(spi, 0x30);
+       spi_write_com(spi, 0xD206);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD207);     spi_write_dat(spi, 0x47);
+       spi_write_com(spi, 0xD208);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD209);     spi_write_dat(spi, 0x5B);
+       spi_write_com(spi, 0xD20A);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD20B);     spi_write_dat(spi, 0x7D);
+       spi_write_com(spi, 0xD20C);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD20D);     spi_write_dat(spi, 0x9D);
+       spi_write_com(spi, 0xD20E);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD20F);     spi_write_dat(spi, 0xCC);
+       spi_write_com(spi, 0xD210);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD211);     spi_write_dat(spi, 0xF3);
+       spi_write_com(spi, 0xD212);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD213);     spi_write_dat(spi, 0x32);
+       spi_write_com(spi, 0xD214);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD215);     spi_write_dat(spi, 0x63);
+       spi_write_com(spi, 0xD216);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD217);     spi_write_dat(spi, 0xB1);
+       spi_write_com(spi, 0xD218);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD219);     spi_write_dat(spi, 0xF0);
+       spi_write_com(spi, 0xD21A);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD21B);     spi_write_dat(spi, 0xF2);
+       spi_write_com(spi, 0xD21C);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD21D);     spi_write_dat(spi, 0x2A);
+       spi_write_com(spi, 0xD21E);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD21F);     spi_write_dat(spi, 0x67);
+       spi_write_com(spi, 0xD220);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD221);     spi_write_dat(spi, 0x90);
+       spi_write_com(spi, 0xD222);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD223);     spi_write_dat(spi, 0xCB);
+       spi_write_com(spi, 0xD224);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD225);     spi_write_dat(spi, 0xF2);
+       spi_write_com(spi, 0xD226);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD227);     spi_write_dat(spi, 0x2A);
+       spi_write_com(spi, 0xD228);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD229);     spi_write_dat(spi, 0x51);
+       spi_write_com(spi, 0xD22A);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD22B);     spi_write_dat(spi, 0x80);
+       spi_write_com(spi, 0xD22C);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD22D);     spi_write_dat(spi, 0x9F);
+       spi_write_com(spi, 0xD22E);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD22F);     spi_write_dat(spi, 0xBE);
+       spi_write_com(spi, 0xD230);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD231);     spi_write_dat(spi, 0xF9);
+       spi_write_com(spi, 0xD232);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD233);     spi_write_dat(spi, 0xFF);
+
+       spi_write_com(spi, 0xD300);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD301);     spi_write_dat(spi, 0x05);
+       spi_write_com(spi, 0xD302);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD303);     spi_write_dat(spi, 0x15);
+       spi_write_com(spi, 0xD304);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD305);     spi_write_dat(spi, 0x30);
+       spi_write_com(spi, 0xD306);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD307);     spi_write_dat(spi, 0x47);
+       spi_write_com(spi, 0xD308);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD309);     spi_write_dat(spi, 0x5B);
+       spi_write_com(spi, 0xD30A);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD30B);     spi_write_dat(spi, 0x7D);
+       spi_write_com(spi, 0xD30C);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD30D);     spi_write_dat(spi, 0x9D);
+       spi_write_com(spi, 0xD30E);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD30F);     spi_write_dat(spi, 0xCC);
+       spi_write_com(spi, 0xD310);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD311);     spi_write_dat(spi, 0xF3);
+       spi_write_com(spi, 0xD312);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD313);     spi_write_dat(spi, 0x32);
+       spi_write_com(spi, 0xD314);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD315);     spi_write_dat(spi, 0x63);
+       spi_write_com(spi, 0xD316);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD317);     spi_write_dat(spi, 0xB1);
+       spi_write_com(spi, 0xD318);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD319);     spi_write_dat(spi, 0xF0);
+       spi_write_com(spi, 0xD31A);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD31B);     spi_write_dat(spi, 0xF2);
+       spi_write_com(spi, 0xD31C);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD31D);     spi_write_dat(spi, 0x2A);
+       spi_write_com(spi, 0xD31E);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD31F);     spi_write_dat(spi, 0x67);
+       spi_write_com(spi, 0xD320);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD321);     spi_write_dat(spi, 0x90);
+       spi_write_com(spi, 0xD322);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD323);     spi_write_dat(spi, 0xCB);
+       spi_write_com(spi, 0xD324);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD325);     spi_write_dat(spi, 0xF2);
+       spi_write_com(spi, 0xD326);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD327);     spi_write_dat(spi, 0x2A);
+       spi_write_com(spi, 0xD328);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD329);     spi_write_dat(spi, 0x51);
+       spi_write_com(spi, 0xD32A);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD32B);     spi_write_dat(spi, 0x80);
+       spi_write_com(spi, 0xD32C);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD32D);     spi_write_dat(spi, 0x9F);
+       spi_write_com(spi, 0xD32E);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD32F);     spi_write_dat(spi, 0xBE);
+       spi_write_com(spi, 0xD330);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD331);     spi_write_dat(spi, 0xF9);
+       spi_write_com(spi, 0xD332);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD333);     spi_write_dat(spi, 0xFF);
+
+       spi_write_com(spi, 0xD400);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD401);     spi_write_dat(spi, 0x05);
+       spi_write_com(spi, 0xD402);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD403);     spi_write_dat(spi, 0x15);
+       spi_write_com(spi, 0xD404);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD405);     spi_write_dat(spi, 0x30);
+       spi_write_com(spi, 0xD406);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD407);     spi_write_dat(spi, 0x47);
+       spi_write_com(spi, 0xD408);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD409);     spi_write_dat(spi, 0x5B);
+       spi_write_com(spi, 0xD40A);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD40B);     spi_write_dat(spi, 0x7D);
+       spi_write_com(spi, 0xD40C);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD40D);     spi_write_dat(spi, 0x9D);
+       spi_write_com(spi, 0xD40E);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD40F);     spi_write_dat(spi, 0xCC);
+       spi_write_com(spi, 0xD410);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD411);     spi_write_dat(spi, 0xF3);
+       spi_write_com(spi, 0xD412);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD413);     spi_write_dat(spi, 0x32);
+       spi_write_com(spi, 0xD414);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD415);     spi_write_dat(spi, 0x63);
+       spi_write_com(spi, 0xD416);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD417);     spi_write_dat(spi, 0xB1);
+       spi_write_com(spi, 0xD418);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD419);     spi_write_dat(spi, 0xF0);
+       spi_write_com(spi, 0xD41A);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD41B);     spi_write_dat(spi, 0xF2);
+       spi_write_com(spi, 0xD41C);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD41D);     spi_write_dat(spi, 0x2A);
+       spi_write_com(spi, 0xD41E);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD41F);     spi_write_dat(spi, 0x67);
+       spi_write_com(spi, 0xD420);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD421);     spi_write_dat(spi, 0x90);
+       spi_write_com(spi, 0xD422);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD423);     spi_write_dat(spi, 0xCB);
+       spi_write_com(spi, 0xD424);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD425);     spi_write_dat(spi, 0xF2);
+       spi_write_com(spi, 0xD426);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD427);     spi_write_dat(spi, 0x2A);
+       spi_write_com(spi, 0xD428);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD429);     spi_write_dat(spi, 0x51);
+       spi_write_com(spi, 0xD42A);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD42B);     spi_write_dat(spi, 0x80);
+       spi_write_com(spi, 0xD42C);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD42D);     spi_write_dat(spi, 0x9F);
+       spi_write_com(spi, 0xD42E);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD42F);     spi_write_dat(spi, 0xBE);
+       spi_write_com(spi, 0xD430);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD431);     spi_write_dat(spi, 0xF9);
+       spi_write_com(spi, 0xD432);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD433);     spi_write_dat(spi, 0xFF);
+
+       spi_write_com(spi, 0xD500);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD501);     spi_write_dat(spi, 0x05);
+       spi_write_com(spi, 0xD502);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD503);     spi_write_dat(spi, 0x15);
+       spi_write_com(spi, 0xD504);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD505);     spi_write_dat(spi, 0x30);
+       spi_write_com(spi, 0xD506);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD507);     spi_write_dat(spi, 0x47);
+       spi_write_com(spi, 0xD508);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD509);     spi_write_dat(spi, 0x5B);
+       spi_write_com(spi, 0xD50A);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD50B);     spi_write_dat(spi, 0x7D);
+       spi_write_com(spi, 0xD50C);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD50D);     spi_write_dat(spi, 0x9D);
+       spi_write_com(spi, 0xD50E);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD50F);     spi_write_dat(spi, 0xCC);
+       spi_write_com(spi, 0xD510);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD511);     spi_write_dat(spi, 0xF3);
+       spi_write_com(spi, 0xD512);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD513);     spi_write_dat(spi, 0x32);
+       spi_write_com(spi, 0xD514);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD515);     spi_write_dat(spi, 0x63);
+       spi_write_com(spi, 0xD516);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD517);     spi_write_dat(spi, 0xB1);
+       spi_write_com(spi, 0xD518);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD519);     spi_write_dat(spi, 0xF0);
+       spi_write_com(spi, 0xD51A);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD51B);     spi_write_dat(spi, 0xF2);
+       spi_write_com(spi, 0xD51C);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD51D);     spi_write_dat(spi, 0x2A);
+       spi_write_com(spi, 0xD51E);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD51F);     spi_write_dat(spi, 0x67);
+       spi_write_com(spi, 0xD520);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD521);     spi_write_dat(spi, 0x90);
+       spi_write_com(spi, 0xD522);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD523);     spi_write_dat(spi, 0xCB);
+       spi_write_com(spi, 0xD524);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD525);     spi_write_dat(spi, 0xF2);
+       spi_write_com(spi, 0xD526);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD527);     spi_write_dat(spi, 0x2A);
+       spi_write_com(spi, 0xD528);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD529);     spi_write_dat(spi, 0x51);
+       spi_write_com(spi, 0xD52A);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD52B);     spi_write_dat(spi, 0x80);
+       spi_write_com(spi, 0xD52C);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD52D);     spi_write_dat(spi, 0x9F);
+       spi_write_com(spi, 0xD52E);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD52F);     spi_write_dat(spi, 0xBE);
+       spi_write_com(spi, 0xD530);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD531);     spi_write_dat(spi, 0xF9);
+       spi_write_com(spi, 0xD532);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD533);     spi_write_dat(spi, 0xFF);
+
+       spi_write_com(spi, 0xD600);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD601);     spi_write_dat(spi, 0x05);
+       spi_write_com(spi, 0xD602);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD603);     spi_write_dat(spi, 0x15);
+       spi_write_com(spi, 0xD604);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD605);     spi_write_dat(spi, 0x30);
+       spi_write_com(spi, 0xD606);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD607);     spi_write_dat(spi, 0x47);
+       spi_write_com(spi, 0xD608);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD609);     spi_write_dat(spi, 0x5B);
+       spi_write_com(spi, 0xD60A);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD60B);     spi_write_dat(spi, 0x7D);
+       spi_write_com(spi, 0xD60C);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD60D);     spi_write_dat(spi, 0x9D);
+       spi_write_com(spi, 0xD60E);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD60F);     spi_write_dat(spi, 0xCC);
+       spi_write_com(spi, 0xD610);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xD611);     spi_write_dat(spi, 0xF3);
+       spi_write_com(spi, 0xD612);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD613);     spi_write_dat(spi, 0x32);
+       spi_write_com(spi, 0xD614);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD615);     spi_write_dat(spi, 0x63);
+       spi_write_com(spi, 0xD616);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD617);     spi_write_dat(spi, 0xB1);
+       spi_write_com(spi, 0xD618);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD619);     spi_write_dat(spi, 0xF0);
+       spi_write_com(spi, 0xD61A);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xD61B);     spi_write_dat(spi, 0xF2);
+       spi_write_com(spi, 0xD61C);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD61D);     spi_write_dat(spi, 0x2A);
+       spi_write_com(spi, 0xD61E);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD61F);     spi_write_dat(spi, 0x67);
+       spi_write_com(spi, 0xD620);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD621);     spi_write_dat(spi, 0x90);
+       spi_write_com(spi, 0xD622);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD623);     spi_write_dat(spi, 0xCB);
+       spi_write_com(spi, 0xD624);     spi_write_dat(spi, 0x02);
+       spi_write_com(spi, 0xD625);     spi_write_dat(spi, 0xF2);
+       spi_write_com(spi, 0xD626);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD627);     spi_write_dat(spi, 0x2A);
+       spi_write_com(spi, 0xD628);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD629);     spi_write_dat(spi, 0x51);
+       spi_write_com(spi, 0xD62A);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD62B);     spi_write_dat(spi, 0x80);
+       spi_write_com(spi, 0xD62C);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD62D);     spi_write_dat(spi, 0x9F);
+       spi_write_com(spi, 0xD62E);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD62F);     spi_write_dat(spi, 0xBE);
+       spi_write_com(spi, 0xD630);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD631);     spi_write_dat(spi, 0xF9);
+       spi_write_com(spi, 0xD632);     spi_write_dat(spi, 0x03);
+       spi_write_com(spi, 0xD633);     spi_write_dat(spi, 0xFF);
+
+       /* LV2 Page 0 enable */
+       spi_write_com(spi, 0xF000);     spi_write_dat(spi, 0x55);
+       spi_write_com(spi, 0xF001);     spi_write_dat(spi, 0xAA);
+       spi_write_com(spi, 0xF002);     spi_write_dat(spi, 0x52);
+       spi_write_com(spi, 0xF003);     spi_write_dat(spi, 0x08);
+       spi_write_com(spi, 0xF004);     spi_write_dat(spi, 0x00);
+
+       /* Display control */
+       spi_write_com(spi, 0xB100);     spi_write_dat(spi, 0xFC);
+       spi_write_com(spi, 0xB101);     spi_write_dat(spi, 0x00);
+
+       /* Source hold time */
+       spi_write_com(spi, 0xB600);     spi_write_dat(spi, 0x05);
+
+       /* Gate EQ control */
+       spi_write_com(spi, 0xB700);     spi_write_dat(spi, 0x70);
+       spi_write_com(spi, 0xB701);     spi_write_dat(spi, 0x70);
+
+       /* Source EQ control (Mode 2) */
+       spi_write_com(spi, 0xB800);     spi_write_dat(spi, 0x01);
+       spi_write_com(spi, 0xB801);     spi_write_dat(spi, 0x05);
+       spi_write_com(spi, 0xB802);     spi_write_dat(spi, 0x05);
+       spi_write_com(spi, 0xB803);     spi_write_dat(spi, 0x05);
+
+       /* Inversion mode  (Column) */
+       spi_write_com(spi, 0xBC00);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xBC01);     spi_write_dat(spi, 0x00);
+       spi_write_com(spi, 0xBC02);     spi_write_dat(spi, 0x00);
+
+       /* Timing control 8phase dual side/4H/4delay/RST_EN */
+       spi_write_com(spi, 0xC900);     spi_write_dat(spi, 0xD0);
+       spi_write_com(spi, 0xC901);     spi_write_dat(spi, 0x82);
+       spi_write_com(spi, 0xC902);     spi_write_dat(spi, 0x50);
+       spi_write_com(spi, 0xC903);     spi_write_dat(spi, 0x50);
+       spi_write_com(spi, 0xC904);     spi_write_dat(spi, 0x50);
+
+       spi_write_com(spi, 0x3A00);     spi_write_dat(spi, 0x55);
+       mdelay(120);
+       spi_write_com(spi, 0x1100);
+       mdelay(120);
+       spi_write_com(spi, 0x2900);
+       mdelay(120);
+       /* spi_write_com(spi, 0x2100);  spi_write_dat(spi, 0x00); */
+       spi_write_com(spi, 0x2C00);
+
+       return 0;
+err_claim_bus:
+       spi_free_slave(spi);
+       return -1;
+}
index 7e255ce8aef987daf37f52e0f00d41292162946a..3ade624702e9820f74f6e34cde4e34d31a6cb5a8 100644 (file)
@@ -18,6 +18,7 @@ COBJS-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o
 COBJS-$(CONFIG_S5P)               += s5p_wdt.o
 COBJS-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o
 COBJS-$(CONFIG_BFIN_WATCHDOG)  += bfin_wdt.o
+COBJS-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.o
 
 COBJS  := $(COBJS-y)
 SRCS   := $(COBJS:.o=.c)
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c
new file mode 100644 (file)
index 0000000..7ea4b60
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * omap_wdt.c
+ *
+ * (C) Copyright 2013
+ * Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * SPDX-License-Identifier:    GPL-2.0
+ *
+ * Based on:
+ *
+ * Watchdog driver for the TI OMAP 16xx & 24xx/34xx 32KHz (non-secure) watchdog
+ *
+ * commit 2d991a164a61858012651e13c59521975504e260
+ * Author: Bill Pemberton <wfp5p@virginia.edu>
+ * Date:   Mon Nov 19 13:21:41 2012 -0500
+ *
+ * watchdog: remove use of __devinit
+ *
+ * CONFIG_HOTPLUG is going away as an option so __devinit is no longer
+ * needed.
+ *
+ * Author: MontaVista Software, Inc.
+ *      <gdavis@mvista.com> or <source@mvista.com>
+ *
+ * History:
+ *
+ * 20030527: George G. Davis <gdavis@mvista.com>
+ *     Initially based on linux-2.4.19-rmk7-pxa1/drivers/char/sa1100_wdt.c
+ *     (c) Copyright 2000 Oleg Drokin <green@crimea.edu>
+ *     Based on SoftDog driver by Alan Cox <alan@lxorguk.ukuu.org.uk>
+ *
+ * Copyright (c) 2004 Texas Instruments.
+ *     1. Modified to support OMAP1610 32-KHz watchdog timer
+ *     2. Ported to 2.6 kernel
+ *
+ * Copyright (c) 2005 David Brownell
+ *     Use the driver model and standard identifiers; handle bigger timeouts.
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <asm/arch/hardware.h>
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/arch/cpu.h>
+
+/* Hardware timeout in seconds */
+#define WDT_HW_TIMEOUT 60
+
+static unsigned int wdt_trgr_pattern = 0x1234;
+
+void hw_watchdog_reset(void)
+{
+       struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
+
+       /* wait for posted write to complete */
+       while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WTGR)
+               ;
+
+       wdt_trgr_pattern = ~wdt_trgr_pattern;
+       writel(wdt_trgr_pattern, &wdt->wdtwtgr);
+
+       /* wait for posted write to complete */
+       while ((readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WTGR))
+               ;
+}
+
+static int omap_wdt_set_timeout(unsigned int timeout)
+{
+       struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
+       u32 pre_margin = GET_WLDR_VAL(timeout);
+
+       /* just count up at 32 KHz */
+       while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WLDR)
+               ;
+
+       writel(pre_margin, &wdt->wdtwldr);
+       while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WLDR)
+               ;
+
+       return 0;
+}
+
+void hw_watchdog_init(void)
+{
+       struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
+
+       /* initialize prescaler */
+       while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
+               ;
+
+       writel(WDT_WCLR_PRE | (PTV << WDT_WCLR_PTV_OFF), &wdt->wdtwclr);
+       while (readl(&wdt->wdtwwps) & WDT_WWPS_PEND_WCLR)
+               ;
+
+       omap_wdt_set_timeout(WDT_HW_TIMEOUT);
+
+       /* Sequence to enable the watchdog */
+       writel(0xBBBB, &wdt->wdtwspr);
+       while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
+               ;
+
+       writel(0x4444, &wdt->wdtwspr);
+       while ((readl(&wdt->wdtwwps)) & WDT_WWPS_PEND_WSPR)
+               ;
+}
+
+void hw_watchdog_disable(void)
+{
+       struct wd_timer *wdt = (struct wd_timer *)WDT_BASE;
+
+       /*
+        * Disable watchdog
+        */
+       writel(0xAAAA, &wdt->wdtwspr);
+       while (readl(&wdt->wdtwwps) != 0x0)
+               ;
+       writel(0x5555, &wdt->wdtwspr);
+       while (readl(&wdt->wdtwwps) != 0x0)
+               ;
+}
index 7969e0746a29e61183920c291694bb45c2a32a70..3de30fc28019f37a52d97bb4806a45d65a7f4384 100644 (file)
        "run mmcboot;" \
        "run nandboot;"
 
-/* USB Composite download gadget - g_dnl */
-#define CONFIG_USB_GADGET
-#define CONFIG_USBDOWNLOAD_GADGET
-
-/* USB TI's IDs */
-#define CONFIG_G_DNL_VENDOR_NUM 0x0403
-#define CONFIG_G_DNL_PRODUCT_NUM 0xBD00
-#define CONFIG_G_DNL_MANUFACTURER "Texas Instruments"
-
-/* USB Device Firmware Update support */
-#define CONFIG_DFU_FUNCTION
-#define CONFIG_DFU_MMC
-#define CONFIG_CMD_DFU
-#define DFU_ALT_INFO_MMC \
-       "boot part 0 1;" \
-       "rootfs part 0 2;" \
-       "MLO fat 0 1;" \
-       "MLO.raw mmc 100 100;" \
-       "u-boot.img.raw mmc 300 400;" \
-       "spl-os-args.raw mmc 80 80;" \
-       "spl-os-image.raw mmc 900 2000;" \
-       "spl-os-args fat 0 1;" \
-       "spl-os-image fat 0 1;" \
-       "u-boot.img fat 0 1;" \
-       "uEnv.txt fat 0 1"
-#ifdef CONFIG_NAND
-#define CONFIG_DFU_NAND
-#define DFU_ALT_INFO_NAND \
-       "SPL part 0 1;" \
-       "SPL.backup1 part 0 2;" \
-       "SPL.backup2 part 0 3;" \
-       "SPL.backup3 part 0 4;" \
-       "u-boot part 0 5;" \
-       "u-boot-spl-os part 0 6;" \
-       "kernel part 0 8;" \
-       "rootfs part 0 9"
-#endif
-
 /* NS16550 Configuration */
 #define CONFIG_SYS_NS16550_COM1                0x44e09000      /* Base EVM has UART0 */
 #define CONFIG_SYS_NS16550_COM2                0x48022000      /* UART1 */
 /* SPL */
 #ifndef CONFIG_NOR_BOOT
 #define CONFIG_SPL_YMODEM_SUPPORT
+
+/* CPSW support */
+#define CONFIG_SPL_ETH_SUPPORT
+
+/* USB gadget RNDIS */
+#define CONFIG_SPL_MUSB_NEW_SUPPORT
+
+/* General network SPL, both CPSW and USB gadget RNDIS */
 #define CONFIG_SPL_NET_SUPPORT
 #define CONFIG_SPL_ENV_SUPPORT
 #define CONFIG_SPL_NET_VCI_STRING      "AM335x U-Boot SPL"
-#define CONFIG_SPL_ETH_SUPPORT
+
+/* SPI flash. */
 #define CONFIG_SPL_SPI_SUPPORT
 #define CONFIG_SPL_SPI_FLASH_SUPPORT
 #define CONFIG_SPL_SPI_LOAD
 #define CONFIG_SPL_SPI_BUS             0
 #define CONFIG_SPL_SPI_CS              0
 #define CONFIG_SYS_SPI_U_BOOT_OFFS     0x20000
-#define CONFIG_SPL_MUSB_NEW_SUPPORT
+
 #define CONFIG_SPL_LDSCRIPT            "$(CPUDIR)/am33xx/u-boot-spl.lds"
 
 #ifdef CONFIG_NAND
 #endif
 
 /*
- * USB configuration
+ * USB configuration.  We enable MUSB support, both for host and for
+ * gadget.  We set USB0 as peripheral and USB1 as host, based on the
+ * board schematic and physical port wired to each.  Then for host we
+ * add mass storage support and for gadget we add both RNDIS ethernet
+ * and DFU.
  */
 #define CONFIG_USB_MUSB_DSPS
 #define CONFIG_ARCH_MISC_INIT
 #define CONFIG_MUSB_GADGET
 #define CONFIG_MUSB_PIO_ONLY
 #define CONFIG_MUSB_DISABLE_BULK_COMBINE_SPLIT
+#define CONFIG_USB_GADGET
+#define CONFIG_USBDOWNLOAD_GADGET
 #define CONFIG_USB_GADGET_DUALSPEED
 #define CONFIG_USB_GADGET_VBUS_DRAW    2
 #define CONFIG_MUSB_HOST
 #define CONFIG_USB_ETHER
 #define CONFIG_USB_ETH_RNDIS
 #define CONFIG_USBNET_HOST_ADDR        "de:ad:be:af:00:00"
+
+/* USB TI's IDs */
+#define CONFIG_G_DNL_VENDOR_NUM 0x0403
+#define CONFIG_G_DNL_PRODUCT_NUM 0xBD00
+#define CONFIG_G_DNL_MANUFACTURER "Texas Instruments"
 #endif /* CONFIG_MUSB_GADGET */
 
 #if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_USBETH_SUPPORT)
 #undef CONFIG_SPL_ETH_SUPPORT
 #endif
 
+/* USB Device Firmware Update support */
+#define CONFIG_DFU_FUNCTION
+#define CONFIG_DFU_MMC
+#define CONFIG_CMD_DFU
+#define DFU_ALT_INFO_MMC \
+       "boot part 0 1;" \
+       "rootfs part 0 2;" \
+       "MLO fat 0 1;" \
+       "MLO.raw mmc 100 100;" \
+       "u-boot.img.raw mmc 300 400;" \
+       "spl-os-args.raw mmc 80 80;" \
+       "spl-os-image.raw mmc 900 2000;" \
+       "spl-os-args fat 0 1;" \
+       "spl-os-image fat 0 1;" \
+       "u-boot.img fat 0 1;" \
+       "uEnv.txt fat 0 1"
+#ifdef CONFIG_NAND
+#define CONFIG_DFU_NAND
+#define DFU_ALT_INFO_NAND \
+       "SPL part 0 1;" \
+       "SPL.backup1 part 0 2;" \
+       "SPL.backup2 part 0 3;" \
+       "SPL.backup3 part 0 4;" \
+       "u-boot part 0 5;" \
+       "u-boot-spl-os part 0 6;" \
+       "kernel part 0 8;" \
+       "rootfs part 0 9"
+#endif
+
 /*
  * Default to using SPI for environment, etc.
  * 0x000000 - 0x020000 : SPL (128KiB)
index 2aea55567da54d387b57510537c2eb7d36bbfe76..fc4ecec7ad47195ded6f4a462ecfb1700d50c5c4 100644 (file)
@@ -13,6 +13,8 @@
 
 #include <asm/hardware.h>
 
+#define CONFIG_SYS_TEXT_BASE           0x73f00000
+
 #define CONFIG_AT91_LEGACY
 #define CONFIG_ATMEL_LEGACY            /* required until (g)pio is fixed */
 
index be8a28c32714f7e89a262f09242a56b37900fa1d..28a79258df41a783be95d459f7f5fef5219e5dd6 100644 (file)
 #define CONFIG_PMECC_CAP               2
 #define CONFIG_PMECC_SECTOR_SIZE       512
 #define CONFIG_PMECC_INDEX_TABLE_OFFSET        0x8000
+
+#define CONFIG_CMD_NAND_TRIMFFS
+
 #endif
 
 #define CONFIG_MTD_PARTITIONS
index 2b1533c85ac70eda187c9040f5daa7f5deb06c6e..4a2ac9aabde12354b353c32ade3f31eea6086d5a 100644 (file)
@@ -11,6 +11,8 @@
 
 #include <asm/hardware.h>
 
+#define CONFIG_SYS_TEXT_BASE           0x26f00000
+
 /* ARM asynchronous clock */
 #define CONFIG_SYS_AT91_SLOW_CLOCK     32768
 #define CONFIG_SYS_AT91_MAIN_CLOCK     12000000        /* 12 MHz crystal */
 #define CONFIG_ATMEL_NAND_HW_PMECC     1
 #define CONFIG_PMECC_CAP               2
 #define CONFIG_PMECC_SECTOR_SIZE       512
-#define CONFIG_PMECC_INDEX_TABLE_OFFSET        0x8000
+
+#define CONFIG_CMD_NAND_TRIMFFS
 
 #define CONFIG_MTD_DEVICE
 #define CONFIG_CMD_MTDPARTS
index 145e7ac926db17df54b818f3d0db7fd2bccd1e96..bdf012b2b8e3ee51c2b04feb6603a370660ccfd3 100644 (file)
@@ -21,9 +21,6 @@
 
 #include "tegra114-common.h"
 
-/* Must be off for Dalmore to boot !?!? FIXME */
-#define CONFIG_SYS_DCACHE_OFF
-
 /* Enable fdt support for Dalmore. Flash the image in u-boot-dtb.bin */
 #define CONFIG_DEFAULT_DEVICE_TREE     tegra114-dalmore
 #define CONFIG_OF_CONTROL
index 58786ffa9126d6335cbb60700a14baaa6a11529f..4fbe768cbc71b2c48e2b824bff96b6dbb66bf874 100644 (file)
 #include <configs/omap5_common.h>
 
 /* CPSW Ethernet */
-#define CONFIG_CMD_NET
+#define CONFIG_CMD_NET                 /* 'bootp' and 'tftp' */
 #define CONFIG_CMD_DHCP
-#define CONFIG_CMD_PING
-#define CONFIG_CMD_MII
-#define CONFIG_DRIVER_TI_CPSW
-#define CONFIG_MII
-#define CONFIG_BOOTP_DEFAULT
-#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_DNS               /* Configurable parts of CMD_DHCP */
 #define CONFIG_BOOTP_DNS2
 #define CONFIG_BOOTP_SEND_HOSTNAME
 #define CONFIG_BOOTP_GATEWAY
 #define CONFIG_BOOTP_SUBNETMASK
-#define CONFIG_NET_RETRY_COUNT         10
-#define CONFIG_NET_MULTI
-#define CONFIG_PHY_GIGE
+#define CONFIG_NET_RETRY_COUNT         10
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_MII
+#define CONFIG_DRIVER_TI_CPSW          /* Driver for IP block */
+#define CONFIG_MII                     /* Required in net/eth.c */
+#define CONFIG_PHY_GIGE                        /* per-board part of CPSW */
 #define CONFIG_PHYLIB
 #define CONFIG_PHY_ADDR                        2
 
diff --git a/include/configs/dxr2.h b/include/configs/dxr2.h
new file mode 100644 (file)
index 0000000..cd553ec
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * (C) Copyright 2013 Siemens Schweiz AG
+ * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Based on:
+ * U-Boot file:/include/configs/am335x_evm.h
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __CONFIG_DXR2_H
+#define __CONFIG_DXR2_H
+
+#define CONFIG_SIEMENS_DXR2
+#define MACH_TYPE_DXR2                 4315
+#define CONFIG_SIEMENS_MACH_TYPE       MACH_TYPE_DXR2
+
+#include "siemens-am33x-common.h"
+
+#define CONFIG_SYS_MPUCLK      275
+#define DXR2_IOCTRL_VAL        0x18b
+#define DDR_PLL_FREQ   266
+#define CONFIG_SPL_AM33XX_DO_NOT_ENABLE_RTC32K
+
+#define BOARD_DFU_BUTTON_GPIO  27
+#define BOARD_DFU_BUTTON_LED   64
+
+#undef CONFIG_DOS_PARTITION
+#undef CONFIG_CMD_FAT
+
+
+ /* Physical Memory Map */
+#define CONFIG_MAX_RAM_BANK_SIZE       (1024 << 20)    /* 1GB */
+
+/* I2C Configuration */
+#define CONFIG_SYS_I2C_SPEED           100000
+
+#define CONFIG_SYS_I2C_EEPROM_ADDR              0x50
+#define EEPROM_ADDR_DDR3 0x90
+#define EEPROM_ADDR_CHIP 0x120
+
+#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS     0x300
+
+#undef CONFIG_SPL_NET_SUPPORT
+#undef CONFIG_SPL_NET_VCI_STRING
+#undef CONFIG_SPL_ETH_SUPPORT
+
+#undef CONFIG_MII
+#undef CONFIG_PHY_GIGE
+#define CONFIG_PHY_ADDR                        0
+#define CONFIG_PHY_SMSC
+
+#define CONFIG_FACTORYSET
+
+/* Watchdog */
+#define CONFIG_OMAP_WATCHDOG
+
+#ifndef CONFIG_SPL_BUILD
+
+/* Default env settings */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+       "hostname=dxr2\0" \
+       "nand_img_size=0x300000\0" \
+       "optargs=\0" \
+       CONFIG_COMMON_ENV_SETTINGS
+
+#ifndef CONFIG_RESTORE_FLASH
+/* set to negative value for no autoboot */
+#define CONFIG_BOOTDELAY               3
+
+#define CONFIG_BOOTCOMMAND \
+"if dfubutton; then " \
+       "run dfu_start; " \
+       "reset; " \
+"fi;" \
+"if ping ${serverip}; then " \
+       "run net_nfs; " \
+"fi;" \
+"run nand_boot;"
+
+#else
+#define CONFIG_BOOTDELAY               0
+
+#define CONFIG_BOOTCOMMAND                     \
+       "setenv autoload no; "                  \
+       "dhcp; "                                \
+       "if tftp 80000000 debrick.scr; then "   \
+               "source 80000000; "             \
+       "fi"
+#endif
+#endif /* CONFIG_SPL_BUILD */
+#endif /* ! __CONFIG_DXR2_H */
index 247e37b6dddaeec972465876ea6f2dcbde76a3b1..ccc7bd0a8aa70f88750499e83dbb1793c5c2bf19 100644 (file)
@@ -39,6 +39,7 @@
 #define CONFIG_SYS_TEXT_BASE           0x21f00000
 #endif
 #define CONFIG_SYS_LOAD_ADDR           0x21000000  /* default load address */
+#define CONFIG_STANDALONE_LOAD_ADDR    0x21000000
 
 #define CONFIG_SYS_BOOT_SIZE           0x00 /* 0 KBytes */
 #define CONFIG_SYS_U_BOOT_BASE         PHYS_FLASH_1
 #define CONFIG_CMD_DATE
 #define CONFIG_CMD_DHCP
 #define CONFIG_CMD_I2C
-#define CONFIG_CMD_JFFS2
 #define CONFIG_CMD_MII
 #define CONFIG_CMD_NAND
 #define CONFIG_CMD_PING
-#define CONFIG_I2C_CMD_NO_FLAT
 #define CONFIG_I2C_CMD_TREE
 #define CONFIG_CMD_USB
 #define CONFIG_CMD_FAT
-
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_CMD_UBIFS
 #define CONFIG_SYS_LONGHELP
 
 /*
- * Filesystems
+ * MTD defines
  */
 
-#define CONFIG_JFFS2_NAND              1
+#define CONFIG_FLASH_CFI_MTD
+#define CONFIG_MTD_DEVICE
+#define CONFIG_MTD_PARTITIONS
+#define CONFIG_RBTREE
+#define CONFIG_LZO
 
-#ifndef CONFIG_JFFS2_CMDLINE
-#define CONFIG_JFFS2_DEV               "nand0"
-#define CONFIG_JFFS2_PART_OFFSET       0
-#define CONFIG_JFFS2_PART_SIZE         0xFFFFFFFF
-#else
-#define MTDIDS_DEFAULT         "nor0=0,nand0=1"
+#define MTDIDS_DEFAULT         "nor0=physmap-flash.0,nand0=atmel_nand"
 #define MTDPARTS_DEFAULT       "mtdparts="                             \
-                                       "0:"                            \
-                                       "384k(U-Boot),"                 \
-                                       "128k(Env),"                    \
-                                       "128k(Splash),"                 \
-                                       "4M(Kernel),"                   \
-                                       "-(FS)"                         \
+                                       "physmap-flash.0:"              \
+                                               "512k(U-Boot),"         \
+                                               "128k(Env),"            \
+                                               "128k(Splash),"         \
+                                               "4M(Kernel),"           \
+                                               "384k(MiniFS),"         \
+                                               "-(FS)"                 \
                                        ";"                             \
-                                       "1:"                            \
-                                       "-(jffs2)"
-#endif /* CONFIG_JFFS2_CMDLINE */
-
+                                       "atmel_nand:"                   \
+                                               "1M(emergency),"        \
+                                               "-(data)"
 /*
  * Hardware drivers
  */
 #define CONFIG_BOOTDELAY               5
 
 #define CONFIG_ENV_IS_IN_FLASH         1
-#define CONFIG_ENV_ADDR                        (PHYS_FLASH_1 + 0x60000)
+#define CONFIG_ENV_ADDR                        (PHYS_FLASH_1 + 0x80000)
 #define CONFIG_ENV_SIZE                        0x20000 /* sectors are 128K here */
 
 #define CONFIG_BAUDRATE                115200
        "displayheight=512\0"                                           \
        "displaybsteps=1023\0"                                          \
        "ubootaddr=10000000\0"                                          \
-       "splashimage=10080000\0"                                        \
-       "kerneladdr=100A0000\0"                                         \
+       "splashimage=100A0000\0"                                        \
+       "kerneladdr=100C0000\0"                                         \
        "kernelsize=00400000\0"                                         \
-       "rootfsaddr=104A0000\0"                                         \
+       "rootfsaddr=10520000\0"                                         \
        "copy_addr=21200000\0"                                          \
-       "rootfssize=00B60000\0"                                         \
+       "rootfssize=00AE0000\0"                                         \
+       "mtdids=" MTDIDS_DEFAULT "\0"                                   \
+       "mtdparts=" MTDPARTS_DEFAULT "\0"                               \
        "bootargsdefaults=set bootargs "                                \
                "console=ttyS0,115200 "                                 \
                "video=vcxk_fb:xres:${displaywidth},"                   \
                "erase $(rootfsaddr) +$(rootfssize);"                   \
                "cp.b $(fileaddr) $(rootfsaddr) $(filesize);"           \
                "\0"                                                    \
-       "update_uboot=protect off 10000000 1005FFFF;"                   \
+       "update_uboot=protect off 10000000 1007FFFF;"                   \
                "dhcp $(copy_addr) u-boot_eb_cpux9k2;"                  \
-               "erase 10000000 1005FFFF;"                              \
+               "erase 10000000 1007FFFF;"                              \
                "cp.b $(fileaddr) $(ubootaddr) $(filesize);"            \
-               "protect on 10000000 1005FFFF;reset\0"                  \
+               "protect on 10000000 1007FFFF;reset\0"                  \
        "update_splash=protect off $(splashimage) +20000;"              \
                "dhcp $(copy_addr) splash_eb_cpux9k2.bmp;"              \
                "erase $(splashimage) +20000;"                          \
-               "cp.b $(fileaddr) 10080000 $(filesize);"                \
+               "cp.b $(fileaddr) $(splashimage) $(filesize);"          \
                "protect on $(splashimage) +20000;reset\0"              \
        "emergency=run bootargsdefaults;"                               \
                "set bootargs $(bootargs) root=initramfs boot=emergency " \
index 722c56652f1b22417642ec79e3d0d527a5096e89..9982cf6e900c4d434bf49224af6a01cca0653759 100644 (file)
@@ -45,6 +45,7 @@
 
 #define CONFIG_OF_LIBFDT
 #define CONFIG_CMD_BOOTZ
+#define CONFIG_SUPPORT_RAW_INITRD
 
 /*
  * NS16550 Configuration
index a684166502fc5d6de05a5cd8a6f602bce9085261..124dc1e6cbd41602333d3c0d1d705eb2200cdc3e 100644 (file)
 /* GPIO */
 #define CONFIG_MXS_GPIO
 
-/* DUART Serial Driver */
+/*
+ * DUART Serial Driver.
+ * Conflicts with AUART driver which can be set by board.
+ */
+#ifndef CONFIG_MXS_AUART
 #define CONFIG_PL011_SERIAL
 #define CONFIG_PL011_CLOCK             24000000
 #define CONFIG_PL01x_PORTS             { (void *)MXS_UARTDBG_BASE }
 #define CONFIG_CONS_INDEX              0
+#endif
 /* Default baudrate can be overriden by board! */
 #ifndef CONFIG_BAUDRATE
 #define CONFIG_BAUDRATE                        115200
index 3da78b65750f63c6f4d83e5cfdd3fa84e3b7130a..f40e0b718fc843d2a82a35e64e2829e35f1fbb22 100644 (file)
@@ -17,6 +17,7 @@
  * High Level Configuration Options
  */
 #define CONFIG_4430SDP         1       /* working with SDP */
+#define CONFIG_MACH_TYPE       MACH_TYPE_OMAP_4430SDP
 
 #include <configs/omap4_common.h>
 
index 8e82fed2347a7f63f0cd302c76337fdefd3de8bc..98ba559c86d134f2158c1d047ab3a018d12c911a 100644 (file)
 /* Use General purpose timer 1 */
 #define CONFIG_SYS_TIMERBASE           GPT2_BASE
 
+/*
+ * For the DDR timing information we can either dynamically determine
+ * the timings to use or use pre-determined timings (based on using the
+ * dynamic method.  Default to the static timing infomation.
+ */
 #define CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
-
-/* Defines for SDRAM init */
 #ifndef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
 #define CONFIG_SYS_AUTOMATIC_SDRAM_DETECTION
 #define CONFIG_SYS_DEFAULT_LPDDR2_TIMINGS
        "fi"
 
 
-/* Defines for SPL */
-#define CONFIG_SPL_TEXT_BASE           0x40300350
-#define CONFIG_SPL_MAX_SIZE            0x19000 /* 100K */
+/*
+ * SPL related defines.  The Public RAM memory map the ROM defines the
+ * area between 0x40300000 and 0x4031E000 as a download area for OMAP5
+ * (dra7xx is larger, but we do not need to be larger at this time).  We
+ * set CONFIG_SPL_DISPLAY_PRINT to have omap_rev_string() called and
+ * print some information.
+ */
+#define CONFIG_SPL_TEXT_BASE           0x40300000
+#define CONFIG_SPL_MAX_SIZE            (0x4031E000 - CONFIG_SPL_TEXT_BASE)
 #define CONFIG_SPL_DISPLAY_PRINT
 #define CONFIG_SPL_LDSCRIPT "$(CPUDIR)/omap-common/u-boot-spl.lds"
 
index 3c4249bddae6cba749ceb7e9394611713ad83213..0d1c43c2eb570dbdce1749c30000f65eaca8e7ac 100644 (file)
@@ -37,6 +37,7 @@
 #define CONFIG_PARTITION_UUIDS
 #define CONFIG_CMD_PART
 
+/* Required support for the TCA642X GPIO we have on the uEVM */
 #define CONFIG_TCA642X
 #define CONFIG_CMD_TCA642X
 #define CONFIG_SYS_I2C_TCA642X_BUS_NUM 4
@@ -64,6 +65,8 @@
 #define CONFIG_USB_ETHER_SMSC95XX
 
 #define CONSOLEDEV             "ttyO2"
+
+/* Max time to hold reset on this board, see doc/README.omap-reset-time */
 #define CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC       16296
 
 #endif /* __CONFIG_OMAP5_EVM_H */
diff --git a/include/configs/pxm2.h b/include/configs/pxm2.h
new file mode 100644 (file)
index 0000000..20b0f9a
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * siemens pxm2
+ * (C) Copyright 2013 Siemens Schweiz AG
+ * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Based on:
+ * U-Boot file:/include/configs/am335x_evm.h
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __CONFIG_PXM2_H
+#define __CONFIG_PXM2_H
+
+#define CONFIG_SIEMENS_PXM2
+#define MACH_TYPE_PXM2                 4309
+#define CONFIG_SIEMENS_MACH_TYPE       MACH_TYPE_PXM2
+
+#include "siemens-am33x-common.h"
+
+#define CONFIG_SYS_MPUCLK      720
+#define DXR2_IOCTRL_VAL                0x18b
+#define DDR_PLL_FREQ           266
+
+#define BOARD_DFU_BUTTON_GPIO  59
+#define BOARD_DFU_BUTTON_LED   117
+#define BOARD_LCD_POWER                111
+#define BOARD_BACK_LIGHT       112
+#define BOARD_TOUCH_POWER      57
+
+ /* Physical Memory Map */
+#define CONFIG_MAX_RAM_BANK_SIZE       (512 << 20)     /* 1GB */
+
+/* I2C Configuration */
+#define CONFIG_SYS_I2C_SPEED           400000
+#define CONFIG_SYS_I2C_EEPROM_ADDR     0x50
+
+
+#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS     0x300
+
+#undef CONFIG_SPL_NET_SUPPORT
+#undef CONFIG_SPL_NET_VCI_STRING
+#undef CONFIG_SPL_ETH_SUPPORT
+
+#define CONFIG_PHY_ADDR                        0
+#define CONFIG_PHY_ATHEROS
+
+#define CONFIG_FACTORYSET
+
+/* UBI Support */
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_MTD_PARTITIONS
+#define CONFIG_MTD_DEVICE
+#define CONFIG_RBTREE
+#define CONFIG_LZO
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS
+#endif
+
+/* Watchdog */
+#define CONFIG_OMAP_WATCHDOG
+
+#ifndef CONFIG_SPL_BUILD
+
+/* Default env settings */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+       "hostname=pxm2\0" \
+       "nand_img_size=0x500000\0" \
+       "optargs=\0" \
+       CONFIG_COMMON_ENV_SETTINGS \
+       "mmc_dev=0\0" \
+       "mmc_root=/dev/mmcblk0p2 rw\0" \
+       "mmc_root_fs_type=ext4 rootwait\0" \
+       "mmc_load_uimage=" \
+               "mmc rescan; " \
+               "setenv bootfile uImage;" \
+               "fatload mmc ${mmc_dev} ${kloadaddr} ${bootfile}\0" \
+       "loadbootenv=fatload mmc ${mmc_dev} ${loadaddr} ${bootenv}\0" \
+       "importbootenv=echo Importing environment from mmc ...; " \
+               "env import -t $loadaddr $filesize\0" \
+       "mmc_args=run bootargs_defaults;" \
+               "mtdparts default;" \
+               "setenv bootargs ${bootargs} " \
+               "root=${mmc_root} ${mtdparts}" \
+               "rootfstype=${mmc_root_fs_type} ip=${ip_method} " \
+               "eth=${ethaddr} " \
+               "\0" \
+       "mmc_boot=run mmc_args; " \
+               "run mmc_load_uimage; " \
+               "bootm ${kloadaddr}\0" \
+       ""
+
+#ifndef CONFIG_RESTORE_FLASH
+/* set to negative value for no autoboot */
+#define CONFIG_BOOTDELAY               3
+
+#define CONFIG_BOOTCOMMAND \
+       "if dfubutton; then " \
+               "run dfu_start; " \
+               "reset; " \
+       "fi; " \
+       "if mmc rescan; then " \
+               "echo SD/MMC found on device ${mmc_dev};" \
+               "if run loadbootenv; then " \
+                       "echo Loaded environment from ${bootenv};" \
+                       "run importbootenv;" \
+               "fi;" \
+               "if test -n $uenvcmd; then " \
+                       "echo Running uenvcmd ...;" \
+                       "run uenvcmd;" \
+               "fi;" \
+               "if run mmc_load_uimage; then " \
+                       "run mmc_args;" \
+                       "bootm ${kloadaddr};" \
+               "fi;" \
+       "fi;" \
+       "run nand_boot;" \
+       "if ping ${serverip}; then " \
+               "run net_nfs; " \
+       "fi; "
+
+#else
+#define CONFIG_BOOTDELAY               0
+
+#define CONFIG_BOOTCOMMAND                     \
+       "setenv autoload no; "                  \
+       "dhcp; "                                \
+       "if tftp 80000000 debrick.scr; then "   \
+               "source 80000000; "             \
+       "fi"
+#endif
+#endif /* CONFIG_SPL_BUILD */
+
+#define CONFIG_VIDEO
+#if defined(CONFIG_VIDEO)
+#define CONFIG_VIDEO_DA8XX
+#define CONFIG_CFB_CONSOLE
+#define CONFIG_VGA_AS_SINGLE_DEVICE
+#define CONFIG_SPLASH_SCREEN
+#define CONFIG_SPLASH_SCREEN_ALIGN
+#define CONFIG_VIDEO_LOGO
+#define CONFIG_VIDEO_BMP_RLE8
+#define CONFIG_VIDEO_BMP_LOGO
+#define CONFIG_CMD_BMP
+#define DA8XX_LCD_CNTL_BASE    LCD_CNTL_BASE
+#define PWM_TICKS      0x1388
+#define PWM_DUTY       0x200
+#endif
+
+#endif /* ! __CONFIG_PXM2_H */
diff --git a/include/configs/rut.h b/include/configs/rut.h
new file mode 100644 (file)
index 0000000..7c94644
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ * siemens rut
+ * (C) Copyright 2013 Siemens Schweiz AG
+ * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Based on:
+ * U-Boot file:/include/configs/am335x_evm.h
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __CONFIG_RUT_H
+#define __CONFIG_RUT_H
+
+#define CONFIG_SIEMENS_RUT
+#define MACH_TYPE_RUT                  4316
+#define CONFIG_SIEMENS_MACH_TYPE       MACH_TYPE_RUT
+
+#include "siemens-am33x-common.h"
+
+#define CONFIG_SYS_MPUCLK      600
+#define RUT_IOCTRL_VAL 0x18b
+#define DDR_PLL_FREQ   303
+
+ /* Physical Memory Map */
+#define CONFIG_MAX_RAM_BANK_SIZE       (256 << 20) /* 256 MiB */
+
+/* I2C Configuration */
+#define CONFIG_SYS_I2C_SPEED           100000
+
+#define CONFIG_SYS_I2C_EEPROM_ADDR              0x50
+#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN          2
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS       6       /* 64 byte pages */
+#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS   10      /* take up to 10 msec */
+
+#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS     0x200
+
+#undef CONFIG_SPL_NET_SUPPORT
+#undef CONFIG_SPL_NET_VCI_STRING
+#undef CONFIG_SPL_ETH_SUPPORT
+
+#define CONFIG_PHY_ADDR                        1
+#define CONFIG_PHY_NATSEMI
+
+#define CONFIG_FACTORYSET
+
+/* UBI Support */
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_MTD_PARTITIONS
+#define CONFIG_MTD_DEVICE
+#define CONFIG_RBTREE
+#define CONFIG_LZO
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS
+#endif
+
+/* Watchdog */
+#define WATCHDOG_TRIGGER_GPIO  14
+
+#ifndef CONFIG_SPL_BUILD
+
+/* Default env settings */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+       "hostname=rut\0" \
+       "splashpos=488,352\0" \
+       "optargs=fixrtc --no-log consoleblank=0 \0" \
+       CONFIG_COMMON_ENV_SETTINGS \
+       "mmc_dev=0\0" \
+       "mmc_root=/dev/mmcblk0p2 rw\0" \
+       "mmc_root_fs_type=ext4 rootwait\0" \
+       "mmc_load_uimage=" \
+               "mmc rescan; " \
+               "setenv bootfile uImage;" \
+               "fatload mmc ${mmc_dev} ${kloadaddr} ${bootfile}\0" \
+       "loadbootenv=fatload mmc ${mmc_dev} ${loadaddr} ${bootenv}\0" \
+       "importbootenv=echo Importing environment from mmc ...; " \
+               "env import -t $loadaddr $filesize\0" \
+       "mmc_args=run bootargs_defaults;" \
+               "mtdparts default;" \
+               "setenv bootargs ${bootargs} " \
+               "root=${mmc_root} ${mtdparts}" \
+               "rootfstype=${mmc_root_fs_type} ip=${ip_method} " \
+               "eth=${ethaddr} " \
+               "\0" \
+       "mmc_boot=run mmc_args; " \
+               "run mmc_load_uimage; " \
+               "bootm ${kloadaddr}\0" \
+       ""
+
+#ifndef CONFIG_RESTORE_FLASH
+/* set to negative value for no autoboot */
+#define CONFIG_BOOTDELAY               3
+
+#define CONFIG_BOOTCOMMAND \
+       "if mmc rescan; then " \
+               "echo SD/MMC found on device ${mmc_dev};" \
+               "if run loadbootenv; then " \
+                       "echo Loaded environment from ${bootenv};" \
+                       "run importbootenv;" \
+               "fi;" \
+               "if test -n $uenvcmd; then " \
+                       "echo Running uenvcmd ...;" \
+                       "run uenvcmd;" \
+               "fi;" \
+               "if run mmc_load_uimage; then " \
+                       "run mmc_args;" \
+                       "bootm ${kloadaddr};" \
+               "fi;" \
+       "fi;" \
+       "run nand_boot;" \
+       "if ping ${serverip}; then " \
+               "run net_nfs; " \
+       "fi; "
+
+#else
+#define CONFIG_BOOTDELAY               0
+
+#define CONFIG_BOOTCOMMAND                     \
+       "setenv autoload no; "                  \
+       "dhcp; "                                \
+       "if tftp 80000000 debrick.scr; then "   \
+               "source 80000000; "             \
+       "fi"
+#endif
+
+#endif /* CONFIG_SPL_BUILD */
+
+#ifdef CONFIG_SPL_BUILD
+#undef CONFIG_HW_WATCHDOG
+#endif
+
+#define CONFIG_VIDEO
+#if defined(CONFIG_VIDEO)
+#define CONFIG_VIDEO_DA8XX
+#define CONFIG_CFB_CONSOLE
+#define CONFIG_VGA_AS_SINGLE_DEVICE
+#define CONFIG_SPLASH_SCREEN
+#define CONFIG_SPLASH_SCREEN_ALIGN
+#define CONFIG_VIDEO_LOGO
+#define CONFIG_VIDEO_BMP_RLE8
+#define CONFIG_VIDEO_BMP_LOGO
+#define CONFIG_CMD_BMP
+#define DA8XX_LCD_CNTL_BASE    LCD_CNTL_BASE
+
+#define CONFIG_SPI
+#define CONFIG_OMAP3_SPI
+
+#define BOARD_LCD_RESET                115     /* Bank 3 pin 19 */
+#define CONFIG_ARCH_EARLY_INIT_R
+#define CONFIG_FORMIKE
+#endif
+
+#endif /* ! __CONFIG_RUT_H */
index 10697d627af6d573d9f93b84258ba27d8adf396b..76fa500eddb5b137fe407ae6ce71514015def7a7 100644 (file)
@@ -56,7 +56,6 @@
 #define LCD_BPP                                LCD_COLOR16
 #define LCD_OUTPUT_BPP                  24
 #define CONFIG_LCD_LOGO
-#undef LCD_TEST_PATTERN
 #define CONFIG_LCD_INFO
 #define CONFIG_LCD_INFO_BELOW_LOGO
 #define CONFIG_SYS_WHITE_ON_BLACK
 #define CONFIG_CMD_NAND
 
 #ifdef CONFIG_CMD_NAND
-#define CONFIG_NAND_MAX_CHIPS          1
 #define CONFIG_NAND_ATMEL
 #define CONFIG_SYS_MAX_NAND_DEVICE     1
 #define CONFIG_SYS_NAND_BASE           ATMEL_BASE_CS3
 #define CONFIG_ATMEL_NAND_HW_PMECC
 #define CONFIG_PMECC_CAP               4
 #define CONFIG_PMECC_SECTOR_SIZE       512
-#define CONFIG_PMECC_INDEX_TABLE_OFFSET        ATMEL_PMECC_INDEX_OFFSET_512
 #define CONFIG_CMD_NAND_TRIMFFS
 #endif
 
 /* Ethernet Hardware */
 #define CONFIG_MACB
 #define CONFIG_RMII
-#define CONFIG_NET_MULTI
 #define CONFIG_NET_RETRY_COUNT         20
 #define CONFIG_MACB_SEARCH_PHY
+#define CONFIG_RGMII
+#define CONFIG_CMD_MII
+#define CONFIG_PHYLIB
+#define CONFIG_PHY_MICREL
+#define CONFIG_PHY_MICREL_KSZ9021
 
 /* MMC */
 #define CONFIG_CMD_MMC
                                "bootm 0x22000000 - 0x21000000"
 #define CONFIG_SYS_MMC_ENV_DEV 0
 #else
-#define CONIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_IS_NOWHERE
 #endif
 
 #ifdef CONFIG_SYS_USE_MMC
diff --git a/include/configs/siemens-am33x-common.h b/include/configs/siemens-am33x-common.h
new file mode 100644 (file)
index 0000000..5426ee8
--- /dev/null
@@ -0,0 +1,461 @@
+/*
+ * siemens am33x common board options
+ * (C) Copyright 2013 Siemens Schweiz AG
+ * (C) Heiko Schocher, DENX Software Engineering, hs@denx.de.
+ *
+ * Based on:
+ * U-Boot file:/include/configs/am335x_evm.h
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __CONFIG_SIEMENS_AM33X_COMMON_H
+#define __CONFIG_SIEMENS_AM33X_COMMON_H
+
+#define CONFIG_AM33XX
+#define CONFIG_OMAP
+#define CONFIG_OMAP_COMMON
+
+#include <asm/arch/omap.h>
+
+#define CONFIG_DMA_COHERENT
+#define CONFIG_DMA_COHERENT_SIZE       (1 << 20)
+
+#define CONFIG_ENV_SIZE                        (0x2000)
+#define CONFIG_SYS_MALLOC_LEN          (16 * 1024 * 1024)
+#define CONFIG_SYS_LONGHELP            /* undef to save memory */
+#define CONFIG_SYS_HUSH_PARSER         /* use "hush" command parser */
+#define CONFIG_SYS_PROMPT              "U-Boot# "
+#define CONFIG_SYS_PROMPT_HUSH_PS2     "> "
+#define CONFIG_BOARD_LATE_INIT
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_MACH_TYPE               CONFIG_SIEMENS_MACH_TYPE
+
+#define CONFIG_CMDLINE_TAG             /* enable passing of ATAGs */
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+
+#define CONFIG_SYS_CACHELINE_SIZE       64
+
+/* commands to include */
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_ASKENV
+#define CONFIG_CMD_ECHO
+#define CONFIG_CMD_CACHE
+
+#define CONFIG_ENV_VARS_UBOOT_CONFIG
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_ROOTPATH                "/opt/eldk"
+#endif
+
+#define CONFIG_ENV_OVERWRITE           1
+#define CONFIG_ENV_IS_NOWHERE
+
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_SYS_AUTOLOAD    "yes"
+
+/* Clock Defines */
+#define V_OSCK                         24000000  /* Clock output from T2 */
+#define V_SCLK                         (V_OSCK)
+
+/* We set the max number of command args high to avoid HUSH bugs. */
+#define CONFIG_SYS_MAXARGS             32
+
+/* Console I/O Buffer Size */
+#define CONFIG_SYS_CBSIZE              512
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE              (CONFIG_SYS_CBSIZE \
+                                       + sizeof(CONFIG_SYS_PROMPT) + 16)
+
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE            CONFIG_SYS_CBSIZE
+
+/*
+ * memtest works on 8 MB in DRAM after skipping 32MB from
+ * start addr of ram disk
+ */
+#define CONFIG_SYS_MEMTEST_START       (PHYS_DRAM_1 + (64 * 1024 * 1024))
+#define CONFIG_SYS_MEMTEST_END         (CONFIG_SYS_MEMTEST_START \
+                                       + (8 * 1024 * 1024))
+
+#define CONFIG_SYS_LOAD_ADDR           0x81000000 /* Default load address */
+#define CONFIG_SYS_HZ                  1000 /* 1ms clock */
+
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_OMAP_HSMMC
+#define CONFIG_CMD_MMC
+#define CONFIG_DOS_PARTITION
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_EXT2
+
+#define CONFIG_SPI
+#define CONFIG_OMAP3_SPI
+#define CONFIG_MTD_DEVICE
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_WINBOND
+#define CONFIG_CMD_SF
+#define CONFIG_SF_DEFAULT_SPEED                (75000000)
+
+ /* Physical Memory Map */
+#define CONFIG_NR_DRAM_BANKS           1               /*  1 bank of DRAM */
+#define PHYS_DRAM_1                    0x80000000      /* DRAM Bank #1 */
+
+#define CONFIG_SYS_SDRAM_BASE          PHYS_DRAM_1
+#define CONFIG_SYS_INIT_SP_ADDR         (NON_SECURE_SRAM_END - \
+                                               GENERATED_GBL_DATA_SIZE)
+ /* Platform/Board specific defs */
+#define CONFIG_SYS_TIMERBASE           0x48040000      /* Use Timer2 */
+#define CONFIG_SYS_PTV                 2       /* Divisor: 2^(PTV+1) => 8 */
+#define CONFIG_SYS_HZ                  1000
+
+/* NS16550 Configuration */
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+#define CONFIG_SERIAL_MULTI
+#define CONFIG_SYS_NS16550_REG_SIZE    (-4)
+#define CONFIG_SYS_NS16550_CLK         (48000000)
+#define CONFIG_SYS_NS16550_COM1                0x44e09000
+#define CONFIG_SYS_NS16550_COM4                0x481a6000
+
+#define CONFIG_BAUDRATE                115200
+
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+#define CONFIG_SERIAL1                  1
+#define CONFIG_CONS_INDEX               1
+
+/* I2C Configuration */
+#define CONFIG_I2C
+#define CONFIG_CMD_I2C
+#define CONFIG_HARD_I2C
+#define CONFIG_SYS_I2C_SLAVE           1
+#define CONFIG_I2C_MULTI_BUS
+#define CONFIG_DRIVER_OMAP24XX_I2C
+
+
+/* Defines for SPL */
+#define CONFIG_SPL
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_TEXT_BASE           0x402F0400
+#define CONFIG_SPL_MAX_SIZE            (101 * 1024)
+#define CONFIG_SPL_STACK               CONFIG_SYS_INIT_SP_ADDR
+
+#define CONFIG_SPL_BSS_START_ADDR      0x80000000
+#define CONFIG_SPL_BSS_MAX_SIZE                0x80000         /* 512 KB */
+
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR        0x300 /* address 0x60000 */
+#define CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION   1
+#define CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME       "u-boot.img"
+#define CONFIG_SPL_MMC_SUPPORT
+#define CONFIG_SPL_FAT_SUPPORT
+#define CONFIG_FS_FAT
+#define CONFIG_SPL_I2C_SUPPORT
+
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBDISK_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_YMODEM_SUPPORT
+
+#define CONFIG_SPL_GPIO_SUPPORT
+#define CONFIG_SPL_WATCHDOG_SUPPORT
+
+#define CONFIG_SPL_SPI_SUPPORT
+#define CONFIG_SPL_SPI_FLASH_SUPPORT
+#define CONFIG_SPL_SPI_LOAD
+#define CONFIG_SPL_SPI_BUS             0
+#define CONFIG_SPL_SPI_CS              0
+#define CONFIG_SYS_SPI_U_BOOT_OFFS     0x20000
+
+#define CONFIG_SPL_LDSCRIPT            "$(CPUDIR)/am33xx/u-boot-spl.lds"
+
+#define CONFIG_SPL_BOARD_INIT
+#define CONFIG_SPL_NAND_AM33XX_BCH
+#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#define CONFIG_SYS_NAND_PAGE_COUNT     (CONFIG_SYS_NAND_BLOCK_SIZE / \
+                                        CONFIG_SYS_NAND_PAGE_SIZE)
+#define CONFIG_SYS_NAND_PAGE_SIZE      2048
+#define CONFIG_SYS_NAND_OOBSIZE                64
+#define CONFIG_SYS_NAND_BLOCK_SIZE     (128*1024)
+#define CONFIG_SYS_NAND_BAD_BLOCK_POS  NAND_LARGE_BADBLOCK_POS
+#define CONFIG_SYS_NAND_ECCPOS         { 2, 3, 4, 5, 6, 7, 8, 9, \
+                                        10, 11, 12, 13, 14, 15, 16, 17, \
+                                        18, 19, 20, 21, 22, 23, 24, 25, \
+                                        26, 27, 28, 29, 30, 31, 32, 33, \
+                                        34, 35, 36, 37, 38, 39, 40, 41, \
+                                        42, 43, 44, 45, 46, 47, 48, 49, \
+                                        50, 51, 52, 53, 54, 55, 56, 57, }
+
+#define CONFIG_SYS_NAND_ECCSIZE                512
+#define CONFIG_SYS_NAND_ECCBYTES       14
+
+#define CONFIG_SYS_NAND_ECCSTEPS       4
+#define        CONFIG_SYS_NAND_ECCTOTAL        (CONFIG_SYS_NAND_ECCBYTES * \
+                                               CONFIG_SYS_NAND_ECCSTEPS)
+
+#define        CONFIG_SYS_NAND_U_BOOT_START    CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SYS_NAND_U_BOOT_OFFS    0x80000
+
+/*
+ * 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM
+ * 64 bytes before this address should be set aside for u-boot.img's
+ * header. That is 0x800FFFC0--0x80100000 should not be used for any
+ * other needs.
+ */
+#define CONFIG_SYS_TEXT_BASE           0x80100000
+#define CONFIG_SYS_SPL_MALLOC_START    0x80208000
+#define CONFIG_SYS_SPL_MALLOC_SIZE     0x100000
+
+/*
+ * Since SPL did pll and ddr initialization for us,
+ * we don't need to do it twice.
+ */
+#ifndef CONFIG_SPL_BUILD
+#define CONFIG_SKIP_LOWLEVEL_INIT
+#endif
+
+#ifndef CONFIG_SPL_BUILD
+/*
+ * USB configuration
+ */
+#define CONFIG_USB_MUSB_DSPS
+#define CONFIG_ARCH_MISC_INIT
+#define CONFIG_MUSB_GADGET
+#define CONFIG_MUSB_PIO_ONLY
+#define CONFIG_MUSB_DISABLE_BULK_COMBINE_SPLIT
+#define CONFIG_USB_GADGET_DUALSPEED
+#define CONFIG_USB_GADGET_VBUS_DRAW    2
+#define CONFIG_MUSB_HOST
+
+#define CONFIG_AM335X_USB0
+#define CONFIG_AM335X_USB0_MODE        MUSB_PERIPHERAL
+#define CONFIG_AM335X_USB1
+#define CONFIG_AM335X_USB1_MODE MUSB_HOST
+#ifdef CONFIG_MUSB_HOST
+#define CONFIG_CMD_USB
+#define CONFIG_USB_STORAGE
+#endif
+
+#ifdef CONFIG_MUSB_GADGET
+#define CONFIG_USB_ETHER
+#define CONFIG_USB_ETH_RNDIS
+#define CONFIG_USBNET_HOST_ADDR        "de:ad:be:af:00:00"
+#endif /* CONFIG_MUSB_GADGET */
+
+#define CONFIG_USB_GADGET
+#define CONFIG_USBDOWNLOAD_GADGET
+
+/* USB TI's IDs */
+#define CONFIG_USBD_HS
+#define CONFIG_G_DNL_VENDOR_NUM 0x0525
+#define CONFIG_G_DNL_PRODUCT_NUM 0x4a47
+#define CONFIG_G_DNL_MANUFACTURER "Texas Instruments"
+
+/* USB Device Firmware Update support */
+#define CONFIG_DFU_FUNCTION
+#define CONFIG_DFU_NAND
+#define CONFIG_CMD_DFU
+#define CONFIG_SYS_DFU_DATA_BUF_SIZE   (1 << 20)
+
+#endif /* CONFIG_SPL_BUILD */
+
+/*
+ * Default to using SPI for environment, etc.  We have multiple copies
+ * of SPL as the ROM will check these locations.
+ * 0x0 - 0x20000 : First copy of SPL
+ * 0x20000 - 0x40000 : Second copy of SPL
+ * 0x40000 - 0x60000 : Third copy of SPL
+ * 0x60000 - 0x80000 : Fourth copy of SPL
+ * 0x80000 - 0xDF000 : U-Boot
+ * 0xDF000 - 0xE0000 : U-Boot Environment
+ * 0xE0000 - 0x442000 : Linux Kernel
+ * 0x442000 - 0x800000 : Userland
+ */
+#if defined(CONFIG_SPI_BOOT)
+# undef CONFIG_ENV_IS_NOWHERE
+# define CONFIG_ENV_IS_IN_SPI_FLASH
+# define CONFIG_ENV_SPI_MAX_HZ         CONFIG_SF_DEFAULT_SPEED
+# define CONFIG_ENV_OFFSET             (892 << 10) /* 892 KiB in */
+# define CONFIG_ENV_SECT_SIZE          (4 << 10) /* 4 KB sectors */
+#endif /* SPI support */
+
+/* Unsupported features */
+#undef CONFIG_USE_IRQ
+
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_PING
+#define CONFIG_DRIVER_TI_CPSW
+#define CONFIG_MII
+#define CONFIG_PHY_GIGE
+#define CONFIG_PHYLIB
+#define CONFIG_CMD_MII
+#define CONFIG_BOOTP_DEFAULT
+#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_DNS2
+#define CONFIG_BOOTP_SEND_HOSTNAME
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_SUBNETMASK
+#define CONFIG_NET_RETRY_COUNT         10
+#define CONFIG_NET_MULTI
+
+#define CONFIG_NAND
+/* NAND support */
+#ifdef CONFIG_NAND
+#define CONFIG_CMD_NAND
+#define CONFIG_CMD_MTDPARTS
+
+#define MTDIDS_NAME_STR                "omap2-nand.0"
+#define MTDIDS_DEFAULT         "nand0=" MTDIDS_NAME_STR
+#define MTDPARTS_DEFAULT       "mtdparts=" MTDIDS_NAME_STR ":" \
+                                       "128k(spl),"            \
+                                       "128k(spl.backup1),"    \
+                                       "128k(spl.backup2),"    \
+                                       "128k(spl.backup3),"    \
+                                       "1920k(u-boot),"        \
+                                       "128k(uboot.env),"      \
+                                       "5120k(kernel_a),"      \
+                                       "5120k(kernel_b),"      \
+                                       "8192k(mtdoops),"       \
+                                       "-(rootfs)"
+/*
+ * chip-size = 256MiB
+ *|         name |        size |           address area |
+ *-------------------------------------------------------
+ *|          spl | 128.000 KiB | 0x       0..0x   1ffff |
+ *|  spl.backup1 | 128.000 KiB | 0x   20000..0x   3ffff |
+ *|  spl.backup2 | 128.000 KiB | 0x   40000..0x   5ffff |
+ *|  spl.backup3 | 128.000 KiB | 0x   60000..0x   7ffff |
+ *|       u-boot |   1.875 MiB | 0x   80000..0x  25ffff |
+ *|    uboot.env | 128.000 KiB | 0x  260000..0x  27ffff |
+ *|     kernel_a |   5.000 MiB | 0x  280000..0x  77ffff |
+ *|     kernel_b |   5.000 MiB | 0x  780000..0x  c7ffff |
+ *|      mtdoops |   8.000 MiB | 0x  c80000..0x 147ffff |
+ *|       rootfs | 235.500 MiB | 0x 1480000..0x fffffff |
+ *-------------------------------------------------------
+ */
+
+#define DFU_ALT_INFO_NAND \
+       "spl part 0 1;" \
+       "spl.backup1 part 0 2;" \
+       "spl.backup2 part 0 3;" \
+       "spl.backup3 part 0 4;" \
+       "u-boot part 0 5;" \
+       "u-boot.env part 0 6;" \
+       "kernel_a part 0 7;" \
+       "kernel_b part 0 8;" \
+       "rootfs partubi 0 10"
+
+#define CONFIG_COMMON_ENV_SETTINGS \
+       "verify=no \0" \
+       "project_dir=systemone\0" \
+       "loadaddr=0x82000000\0" \
+       "kloadaddr=0x81000000\0" \
+       "script_addr=0x81900000\0" \
+       "console=console=ttyMTD,mtdoops console=ttyO0,115200n8\0" \
+       "active_set=a\0" \
+       "nand_active_ubi_vol=rootfs_a\0" \
+       "nand_root_fs_type=ubifs rootwait=1\0" \
+       "nand_src_addr=0x280000\0" \
+       "nand_src_addr_a=0x280000\0" \
+       "nand_src_addr_b=0x780000\0" \
+       "nfsopts=nolock rw mem=128M\0" \
+       "ip_method=none\0" \
+       "bootenv=uEnv.txt\0" \
+       "bootargs_defaults=setenv bootargs " \
+               "console=${console} " \
+               "${optargs}\0" \
+       "nand_args=run bootargs_defaults;" \
+               "mtdparts default;" \
+               "setenv nand_active_ubi_vol rootfs_${active_set};" \
+               "setenv ${active_set} true;" \
+               "if test -n ${a}; then " \
+                       "setenv nand_src_addr ${nand_src_addr_a};" \
+               "fi;" \
+               "if test -n ${b}; then " \
+                       "setenv nand_src_addr ${nand_src_addr_b};" \
+               "fi;" \
+               "setenv nand_root ubi0:${nand_active_ubi_vol} rw " \
+               "ubi.mtd=9,2048;" \
+               "setenv bootargs ${bootargs} " \
+               "root=${nand_root} noinitrd ${mtdparts} " \
+               "rootfstype=${nand_root_fs_type} ip=${ip_method} " \
+               "console=ttyMTD,mtdoops console=ttyO0,115200n8 mtdoops.mtddev" \
+               "=mtdoops\0" \
+       "dfu_args=run bootargs_defaults;" \
+               "setenv bootargs ${bootargs} ;" \
+               "mtdparts default; " \
+               "dfu nand 0; \0" \
+               "dfu_alt_info=" DFU_ALT_INFO_NAND "\0" \
+       "net_args=run bootargs_defaults;" \
+               "mtdparts default;" \
+               "setenv bootfile ${project_dir}/kernel/uImage;" \
+               "setenv rootpath /home/projects/${project_dir}/rootfs;" \
+               "setenv bootargs ${bootargs} " \
+               "root=/dev/nfs ${mtdparts} " \
+               "nfsroot=${serverip}:${rootpath},${nfsopts} " \
+               "addip=setenv bootargs ${bootargs} ip=${ipaddr}:${serverip}:" \
+               "${gatewayip}:${netmask}:${hostname}:eth0:off\0" \
+       "nand_boot=echo Booting from nand, active set ${active_set} ...; " \
+               "run nand_args; " \
+               "nand read.i ${kloadaddr} ${nand_src_addr} " \
+               "${nand_img_size}; bootm ${kloadaddr}\0" \
+       "net_nfs=echo Booting from network ...; " \
+               "run net_args; " \
+               "tftpboot ${kloadaddr} ${serverip}:${bootfile}; " \
+               "bootm ${kloadaddr}\0" \
+       "flash_self=run nand_boot\0" \
+       "flash_self_test=setenv bootargs_defaults ${bootargs_defaults} test; " \
+               "run nand_boot\0" \
+       "dfu_start=echo Preparing for dfu mode ...; " \
+               "run dfu_args; \0" \
+       "preboot=echo; "\
+               "echo Type 'run flash_self' to use kernel and root " \
+               "filesystem on memory; echo Type 'run flash_self_test' to " \
+               "use kernel and root filesystem on memory, boot in test " \
+               "mode; echo Not ready yet: 'run flash_nfs' to use kernel " \
+               "from memory and root filesystem over NFS; echo Type " \
+               "'run net_nfs' to get Kernel over TFTP and mount root " \
+               "filesystem over NFS; echo Set active_set variable to 'a' " \
+               "or 'b' to select kernel and rootfs partition; " \
+               "echo" \
+               "\0"
+
+#define CONFIG_NAND_OMAP_GPMC
+#define GPMC_NAND_ECC_LP_x16_LAYOUT    1
+#define CONFIG_SYS_NAND_BASE           (0x08000000)    /* physical address */
+                                                       /* to access nand at */
+                                                       /* CS0 */
+#define CONFIG_SYS_MAX_NAND_DEVICE     1               /* Max number of NAND
+                                                          devices */
+#if !defined(CONFIG_SPI_BOOT)
+#undef CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OFFSET              0x260000 /* environment starts here */
+#define CONFIG_SYS_ENV_SECT_SIZE       (128 << 10)     /* 128 KiB */
+#endif
+#endif
+
+#define CONFIG_OMAP_GPIO
+
+/* Watchdog */
+#define CONFIG_HW_WATCHDOG
+
+/* Stop autoboot with ESC ESC key detected */
+#define CONFIG_AUTOBOOT_KEYED
+#define CONFIG_AUTOBOOT_STOP_STR       "\x1b\x1b"
+#define CONFIG_AUTOBOOT_PROMPT "Autobooting in %d seconds, "           \
+                               "press \"<Esc><Esc>\" to stop\n", bootdelay
+
+#endif /* ! __CONFIG_SIEMENS_AM33X_COMMON_H */
index b5a7a9addcfaa8dbbdb831f5b2de3203b4361859..06aeba61dd2dd32da524df63c66f8b32cc3ec503 100644 (file)
@@ -11,6 +11,8 @@
 /*
  * High level configuration
  */
+/* Virtual target or real hardware */
+#define CONFIG_SOCFPGA_VIRTUAL_TARGET
 
 #define CONFIG_ARMV7
 #define CONFIG_L2_OFF
 #define CONFIG_SINGLE_BOOTLOADER
 #define CONFIG_SOCFPGA
 
+/* base address for .text section */
+#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET
 #define CONFIG_SYS_TEXT_BASE           0x08000040
-#define V_NS16550_CLK                  1000000
-#define CONFIG_BAUDRATE                        57600
-#define CONFIG_SYS_HZ                  1000
-#define CONFIG_TIMER_CLOCK_KHZ         2400
+#else
+#define CONFIG_SYS_TEXT_BASE           0x01000040
+#endif
 #define CONFIG_SYS_LOAD_ADDR           0x7fc0
 
 /* Console I/O Buffer Size */
 /* SDRAM Bank #1 */
 #define CONFIG_SYS_SDRAM_BASE          0x00000000
 /* SDRAM memory size */
-#define PHYS_SDRAM_1_SIZE              0x80000000
+#define PHYS_SDRAM_1_SIZE              0x40000000
 
 #define PHYS_SDRAM_1                   CONFIG_SYS_SDRAM_BASE
 #define CONFIG_SYS_MEMTEST_START       0x00000000
 #define CONFIG_SYS_NS16550_CLK          V_NS16550_CLK
 #define CONFIG_CONS_INDEX               1
 #define CONFIG_SYS_NS16550_COM1                UART0_BASE
-
 #define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600, 115200}
+#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET
+#define V_NS16550_CLK                  1000000
+#else
+#define V_NS16550_CLK                  100000000
+#endif
+#define CONFIG_BAUDRATE                        115200
 
 /*
  * FLASH
 /* This timer use eosc1 where the clock frequency is fixed
  * throughout any condition */
 #define CONFIG_SYS_TIMERBASE           SOCFPGA_OSC1TIMER0_ADDRESS
-
 /* reload value when timer count to zero */
 #define TIMER_LOAD_VAL                 0xFFFFFFFF
+/* Timer info */
+#define CONFIG_SYS_HZ                  1000
+#ifdef CONFIG_SOCFPGA_VIRTUAL_TARGET
+#define CONFIG_TIMER_CLOCK_KHZ         2400
+#else
+#define CONFIG_TIMER_CLOCK_KHZ         25000
+#endif
 
 #define CONFIG_ENV_IS_NOWHERE
 
index ccd68a19fd4cf2a23f656d3df46ae34e1fdc00d0..ba6c6bb9f5f80aadd8de9c71f9b3bf66a9354749 100644 (file)
@@ -17,8 +17,6 @@
 #define CONFIG_TEGRA                   /* which is a Tegra generic machine */
 #define CONFIG_SYS_L2CACHE_OFF         /* No L2 cache */
 
-#define CONFIG_SYS_CACHELINE_SIZE      32
-
 #include <asm/arch/tegra.h>            /* get chip and board defs */
 
 /*
 #define CONFIG_CMD_GPIO
 #define CONFIG_CMD_ENTERRCM
 #define CONFIG_CMD_BOOTZ
+#define CONFIG_SUPPORT_RAW_INITRD
 
 /* Defines for SPL */
 #define CONFIG_SPL
index 44e98e501952bb26284b531323aee68c9621e9c3..c3de9a999e952e3f893a6ae9efa2538e53b79e3e 100644 (file)
@@ -18,6 +18,9 @@
 #define _TEGRA114_COMMON_H_
 #include "tegra-common.h"
 
+/* Cortex-A15 uses a cache line size of 64 bytes */
+#define CONFIG_SYS_CACHELINE_SIZE      64
+
 /*
  * NS16550 Configuration
  */
index d5e9ee4062e4fd7b1343e761c08cdbdb47186f80..b009a316b14cd29e4389e64dfef8cbfec111bf3c 100644 (file)
@@ -9,6 +9,9 @@
 #define _TEGRA20_COMMON_H_
 #include "tegra-common.h"
 
+/* Cortex-A9 uses a cache line size of 32 bytes */
+#define CONFIG_SYS_CACHELINE_SIZE      32
+
 /*
  * Errata configuration
  */
index 5ac88165041595a9edd7d13f70e1b2fb61684c90..99acbfd28b29de65dad657cbd556cd523322e2c2 100644 (file)
@@ -9,6 +9,9 @@
 #define _TEGRA30_COMMON_H_
 #include "tegra-common.h"
 
+/* Cortex-A9 uses a cache line size of 32 bytes */
+#define CONFIG_SYS_CACHELINE_SIZE      32
+
 /*
  * Errata configuration
  */
index fd3ffab015bd26f2185590834bbac4de68eaf96b..d2e34aeed48142e0b086c834ce73ac70045afe4e 100644 (file)
 #define CONFIG_SYS_NS16550_CLK         48000000
 
 /* Network defines. */
-#define CONFIG_CMD_NET
+#define CONFIG_CMD_NET                 /* 'bootp' and 'tftp' */
 #define CONFIG_CMD_DHCP
-#define CONFIG_CMD_PING
-#define CONFIG_DRIVER_TI_CPSW
-#define CONFIG_MII
-#define CONFIG_BOOTP_DEFAULT
-#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_DNS               /* Configurable parts of CMD_DHCP */
 #define CONFIG_BOOTP_DNS2
 #define CONFIG_BOOTP_SEND_HOSTNAME
 #define CONFIG_BOOTP_GATEWAY
 #define CONFIG_BOOTP_SUBNETMASK
 #define CONFIG_NET_RETRY_COUNT         10
+#define CONFIG_CMD_PING
+#define CONFIG_DRIVER_TI_CPSW          /* Driver for IP block */
+#define CONFIG_MII                     /* Required in net/eth.c */
 
-/* SPL defines. */
+/*
+ * SPL related defines.  The Public RAM memory map the ROM defines the
+ * area between 0x402F0400 and 0x4030B800 as a download area and
+ * 0x4030B800 to 0x4030CE00 as a public stack area.  The ROM also
+ * supports X-MODEM loading via UART, and we leverage this and then use
+ * Y-MODEM to load u-boot.img, when booted over UART.
+ */
 #define CONFIG_SPL_TEXT_BASE           0x402F0400
-#define CONFIG_SPL_MAX_SIZE            (0x4030C000 - CONFIG_SPL_TEXT_BASE)
-#define CONFIG_SPL_YMODEM_SUPPORT
+#define CONFIG_SPL_MAX_SIZE            (0x4030B800 - CONFIG_SPL_TEXT_BASE)
 
 /*
  * Since SPL did pll and ddr initialization for us,
index e0ab6912baf29ca2c9253c4f42ecd23f93663404..e89e8744df4492a722eb142cdd22d91c14d60997 100644 (file)
 
 /* I2C IP block */
 #define CONFIG_I2C
-#define CONFIG_CMD_I2C
 #define CONFIG_HARD_I2C
 #define CONFIG_SYS_I2C_SPEED           100000
 #define CONFIG_SYS_I2C_SLAVE           1
 #define CONFIG_I2C_MULTI_BUS
 #define CONFIG_DRIVER_OMAP24XX_I2C
+#define CONFIG_CMD_I2C
 
 /* MMC/SD IP block */
 #define CONFIG_MMC
  * access CS0 at is 0x8000000.
  */
 #ifdef CONFIG_NAND
-#define CONFIG_CMD_NAND
 #define CONFIG_NAND_OMAP_GPMC
 #define CONFIG_SYS_NAND_BASE           0x8000000
 #define CONFIG_SYS_MAX_NAND_DEVICE     1
+#define CONFIG_CMD_NAND
 #endif
 
 /*
  * console baudrate of 115200 and use the default baud rate table.
  */
 #define CONFIG_SYS_MALLOC_LEN          (1024 << 10)
-#define CONFIG_SYS_LONGHELP
 #define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT              "U-Boot# "
+#define CONFIG_SYS_CONSOLE_INFO_QUIET
+#define CONFIG_BAUDRATE                        115200
+#define CONFIG_ENV_VARS_UBOOT_CONFIG   /* Strongly encouraged */
+#define CONFIG_ENV_OVERWRITE           /* Overwrite ethaddr / serial# */
+
+/* As stated above, the following choices are optional. */
+#define CONFIG_SYS_LONGHELP
 #define CONFIG_AUTO_COMPLETE
 #define CONFIG_CMDLINE_EDITING
-#define CONFIG_SYS_PROMPT              "U-Boot# "
 #define CONFIG_VERSION_VARIABLE
-#define CONFIG_ENV_VARS_UBOOT_CONFIG
-#define CONFIG_BAUDRATE                        115200
 
 /* We set the max number of command args high to avoid HUSH bugs. */
 #define CONFIG_SYS_MAXARGS             64
 /* Boot Argument Buffer Size */
 #define CONFIG_SYS_BARGSIZE            CONFIG_SYS_CBSIZE
 
-#define CONFIG_ENV_OVERWRITE
-#define CONFIG_SYS_CONSOLE_INFO_QUIET
-
 /*
  * When we have SPI, NOR or NAND flash we expect to be making use of
  * mtdparts, both for ease of use in U-Boot and for passing information
  * useful commands.  Note that we must have set CONFIG_SYS_NO_FLASH
  * prior to this include, in order to skip a few commands.  When we do
  * have flash, if we expect these commands they must be enabled in that
- * config.
+ * config.  If desired, a specific list of desired commands can be used
+ * instead.
  */
 #include <config_cmd_default.h>
 #define CONFIG_CMD_ASKENV
 #endif
 
 #ifdef CONFIG_MMC
+#define CONFIG_SPL_LIBDISK_SUPPORT
 #define CONFIG_SPL_MMC_SUPPORT
 #define CONFIG_SPL_FAT_SUPPORT
 #endif
 
-/* General parts of the framework. */
+/* General parts of the framework, required. */
 #define CONFIG_SPL_I2C_SUPPORT
 #define CONFIG_SPL_LIBCOMMON_SUPPORT
-#define CONFIG_SPL_LIBDISK_SUPPORT
 #define CONFIG_SPL_LIBGENERIC_SUPPORT
 #define CONFIG_SPL_SERIAL_SUPPORT
 #define CONFIG_SPL_GPIO_SUPPORT
index f93a39389a4d00b575cfdbfb9e528413ef0b99ce..ee6eb8d24645a7ba8112a7ba15303b10b823a51f 100644 (file)
@@ -212,6 +212,7 @@ struct lmb;
 #define IH_TYPE_AISIMAGE       13      /* TI Davinci AIS Image         */
 #define IH_TYPE_KERNEL_NOLOAD  14      /* OS Kernel Image, can run from any load address */
 #define IH_TYPE_PBLIMAGE       15      /* Freescale PBL Boot Image     */
+#define IH_TYPE_MXSIMAGE       16      /* Freescale MXSBoot Image      */
 
 /*
  * Compression Types
index e1338bf489f8a1934c1c1e669d3db5db48d712be..3fdfb399b50fde478c2bfd81483576697b468671 100644 (file)
@@ -3,6 +3,14 @@
 
 #define ndelay(x)      udelay(1)
 
+#define dev_dbg(dev, fmt, args...)             \
+       debug(fmt, ##args)
+#define dev_vdbg(dev, fmt, args...)            \
+       debug(fmt, ##args)
+#define dev_info(dev, fmt, args...)            \
+       printf(fmt, ##args)
+#define dev_err(dev, fmt, args...)             \
+       printf(fmt, ##args)
 #define printk printf
 
 #define KERN_EMERG
index f7e27f8477b0e5d3c4acae8175b080db88a78eca..0ff857bc9f5722bce1062e6744f16bbfdbbbe9b0 100644 (file)
@@ -63,4 +63,8 @@ void video_position_cursor(unsigned col, unsigned row);
 /* Clear the display */
 void video_clear(void);
 
+#if defined(CONFIG_FORMIKE)
+int kwh043st20_f01_spi_startup(unsigned int bus, unsigned int cs,
+       unsigned int max_hz, unsigned int spi_mode);
+#endif
 #endif
index 339e5e897115815162ba999790f168a3a58ea80f..174d0a7fc47fe60d16b2613a57cd97055dca0970 100644 (file)
@@ -98,6 +98,7 @@ LIBS-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/phy/libphy.o
 LIBS-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/net/phy/libphy.o
 LIBS-$(CONFIG_SPL_MUSB_NEW_SUPPORT) += drivers/usb/musb-new/libusb_musb-new.o
 LIBS-$(CONFIG_SPL_USBETH_SUPPORT) += drivers/usb/gadget/libusb_gadget.o
+LIBS-$(CONFIG_SPL_WATCHDOG_SUPPORT) += drivers/watchdog/libwatchdog.o
 
 ifneq ($(CONFIG_OMAP_COMMON),)
 LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
index 6d456564a11d73673662ea148a9c110d246414d3..0a29147847451be688fbaa041ecabc000c0eb37a 100644 (file)
@@ -70,31 +70,32 @@ EXT_OBJ_FILES-y += lib/md5.o
 EXT_OBJ_FILES-y += lib/sha1.o
 
 # Source files located in the tools directory
-OBJ_FILES-$(CONFIG_LCD_LOGO) += bmp_logo.o
-OBJ_FILES-$(CONFIG_VIDEO_LOGO) += bmp_logo.o
+NOPED_OBJ_FILES-y += aisimage.o
 NOPED_OBJ_FILES-y += default_image.o
-NOPED_OBJ_FILES-y += proftool.o
-OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc.o
 NOPED_OBJ_FILES-y += fit_image.o
-OBJ_FILES-$(CONFIG_CMD_NET) += gen_eth_addr.o
-OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o
-OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o
-NOPED_OBJ_FILES-y += aisimage.o
-NOPED_OBJ_FILES-y += kwbimage.o
-NOPED_OBJ_FILES-y += pblimage.o
-NOPED_OBJ_FILES-y += imximage.o
 NOPED_OBJ_FILES-y += image-host.o
-NOPED_OBJ_FILES-y += omapimage.o
+NOPED_OBJ_FILES-y += imximage.o
+NOPED_OBJ_FILES-y += kwbimage.o
 NOPED_OBJ_FILES-y += mkenvimage.o
 NOPED_OBJ_FILES-y += mkimage.o
-OBJ_FILES-$(CONFIG_SMDK5250) += mkexynosspl.o
+NOPED_OBJ_FILES-y += mxsimage.o
+NOPED_OBJ_FILES-y += omapimage.o
+NOPED_OBJ_FILES-y += os_support.o
+NOPED_OBJ_FILES-y += pblimage.o
+NOPED_OBJ_FILES-y += proftool.o
+NOPED_OBJ_FILES-y += ublimage.o
+OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc.o
+OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o
+OBJ_FILES-$(CONFIG_CMD_NET) += gen_eth_addr.o
+OBJ_FILES-$(CONFIG_KIRKWOOD) += kwboot.o
+OBJ_FILES-$(CONFIG_LCD_LOGO) += bmp_logo.o
 OBJ_FILES-$(CONFIG_MX23) += mxsboot.o
 OBJ_FILES-$(CONFIG_MX28) += mxsboot.o
 OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o
-NOPED_OBJ_FILES-y += os_support.o
 OBJ_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1.o
-NOPED_OBJ_FILES-y += ublimage.o
-OBJ_FILES-$(CONFIG_KIRKWOOD) += kwboot.o
+OBJ_FILES-$(CONFIG_SMDK5250) += mkexynosspl.o
+OBJ_FILES-$(CONFIG_VIDEO_LOGO) += bmp_logo.o
+OBJ_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes.o
 
 # Don't build by default
 #ifeq ($(ARCH),ppc)
@@ -203,20 +204,21 @@ $(obj)mkenvimage$(SFX):   $(obj)crc32.o $(obj)mkenvimage.o \
        $(HOSTSTRIP) $@
 
 $(obj)mkimage$(SFX):   $(obj)aisimage.o \
+                       $(FIT_SIG_OBJS) \
                        $(obj)crc32.o \
                        $(obj)default_image.o \
                        $(obj)fit_image.o \
                        $(obj)image-fit.o \
-                       $(obj)image.o \
                        $(obj)image-host.o \
-                       $(FIT_SIG_OBJS) \
+                       $(obj)image.o \
                        $(obj)imximage.o \
                        $(obj)kwbimage.o \
-                       $(obj)pblimage.o \
                        $(obj)md5.o \
                        $(obj)mkimage.o \
-                       $(obj)os_support.o \
+                       $(obj)mxsimage.o \
                        $(obj)omapimage.o \
+                       $(obj)os_support.o \
+                       $(obj)pblimage.o \
                        $(obj)sha1.o \
                        $(obj)ublimage.o \
                        $(LIBFDT_OBJS) \
index cab208b5ac889f5e5235e1ca79dc5c9c2c82f205..c87669b985d4c4b95d531b5899b013fa44bf4997 100644 (file)
@@ -13,6 +13,8 @@
 #include <image.h>
 #include "imximage.h"
 
+#define UNDEFINED 0xFFFFFFFF
+
 /*
  * Supported commands for configuration file
  */
@@ -20,6 +22,7 @@ static table_entry_t imximage_cmds[] = {
        {CMD_BOOT_FROM,         "BOOT_FROM",            "boot command",   },
        {CMD_BOOT_OFFSET,       "BOOT_OFFSET",          "Boot offset",    },
        {CMD_DATA,              "DATA",                 "Reg Write Data", },
+       {CMD_CSF,               "CSF",           "Command Sequence File", },
        {CMD_IMAGE_VERSION,     "IMAGE_VERSION",        "image version",  },
        {-1,                    "",                     "",               },
 };
@@ -28,7 +31,7 @@ static table_entry_t imximage_cmds[] = {
  * Supported Boot options for configuration file
  * this is needed to set the correct flash offset
  */
-static table_entry_t imximage_bootops[] = {
+static table_entry_t imximage_boot_offset[] = {
        {FLASH_OFFSET_ONENAND,  "onenand",      "OneNAND Flash",},
        {FLASH_OFFSET_NAND,     "nand",         "NAND Flash",   },
        {FLASH_OFFSET_NOR,      "nor",          "NOR Flash",    },
@@ -38,6 +41,20 @@ static table_entry_t imximage_bootops[] = {
        {-1,                    "",             "Invalid",      },
 };
 
+/*
+ * Supported Boot options for configuration file
+ * this is needed to determine the initial load size
+ */
+static table_entry_t imximage_boot_loadsize[] = {
+       {FLASH_LOADSIZE_ONENAND,        "onenand",      "OneNAND Flash",},
+       {FLASH_LOADSIZE_NAND,           "nand",         "NAND Flash",   },
+       {FLASH_LOADSIZE_NOR,            "nor",          "NOR Flash",    },
+       {FLASH_LOADSIZE_SATA,           "sata",         "SATA Disk",    },
+       {FLASH_LOADSIZE_SD,             "sd",           "SD Card",      },
+       {FLASH_LOADSIZE_SPI,            "spi",          "SPI Flash",    },
+       {-1,                            "",             "Invalid",      },
+};
+
 /*
  * IMXIMAGE version definition for i.MX chips
  */
@@ -49,12 +66,22 @@ static table_entry_t imximage_versions[] = {
 
 static struct imx_header imximage_header;
 static uint32_t imximage_version;
+/*
+ * Image Vector Table Offset
+ * Initialized to a wrong not 4-bytes aligned address to
+ * check if it is was set by the cfg file.
+ */
+static uint32_t imximage_ivt_offset = UNDEFINED;
+static uint32_t imximage_csf_size = UNDEFINED;
+/* Initial Load Region Size */
+static uint32_t imximage_init_loadsize;
 
 static set_dcd_val_t set_dcd_val;
 static set_dcd_rst_t set_dcd_rst;
 static set_imx_hdr_t set_imx_hdr;
 static uint32_t max_dcd_entries;
 static uint32_t *header_size_ptr;
+static uint32_t *csf_ptr;
 
 static uint32_t get_cfg_value(char *token, char *name,  int linenr)
 {
@@ -190,7 +217,8 @@ static void set_imx_hdr_v1(struct imx_header *imxhdr, uint32_t dcd_len,
        /* Set magic number */
        fhdr_v1->app_code_barker = APP_CODE_BARKER;
 
-       hdr_base = entry_point - sizeof(struct imx_header);
+       /* TODO: check i.MX image V1 handling, for now use 'old' style */
+       hdr_base = entry_point - 4096;
        fhdr_v1->app_dest_ptr = hdr_base - flash_offset;
        fhdr_v1->app_code_jump_vector = entry_point;
 
@@ -217,16 +245,18 @@ static void set_imx_hdr_v2(struct imx_header *imxhdr, uint32_t dcd_len,
 
        fhdr_v2->entry = entry_point;
        fhdr_v2->reserved1 = fhdr_v2->reserved2 = 0;
-       fhdr_v2->self = hdr_base = entry_point - sizeof(struct imx_header);
-
+       hdr_base = entry_point - imximage_init_loadsize +
+               flash_offset;
+       fhdr_v2->self = hdr_base;
        fhdr_v2->dcd_ptr = hdr_base + offsetof(imx_header_v2_t, dcd_table);
        fhdr_v2->boot_data_ptr = hdr_base
                        + offsetof(imx_header_v2_t, boot_data);
-       hdr_v2->boot_data.start = hdr_base - flash_offset;
+       hdr_v2->boot_data.start = entry_point - imximage_init_loadsize;
 
-       /* Security feature are not supported */
        fhdr_v2->csf = 0;
+
        header_size_ptr = &hdr_v2->boot_data.size;
+       csf_ptr = &fhdr_v2->csf;
 }
 
 static void set_hdr_func(struct imx_header *imxhdr)
@@ -303,6 +333,13 @@ static void print_hdr_v2(struct imx_header *imx_hdr)
        genimg_print_size(hdr_v2->boot_data.size);
        printf("Load Address: %08x\n", (uint32_t)fhdr_v2->boot_data_ptr);
        printf("Entry Point:  %08x\n", (uint32_t)fhdr_v2->entry);
+       if (fhdr_v2->csf && (imximage_ivt_offset != UNDEFINED) &&
+           (imximage_csf_size != UNDEFINED)) {
+               printf("HAB Blocks:   %08x %08x %08x\n",
+                      (uint32_t)fhdr_v2->self, 0,
+                      hdr_v2->boot_data.size - imximage_ivt_offset -
+                      imximage_csf_size);
+       }
 }
 
 static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
@@ -324,18 +361,36 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
                set_hdr_func(imxhdr);
                break;
        case CMD_BOOT_FROM:
-               imxhdr->flash_offset = get_table_entry_id(imximage_bootops,
+               imximage_ivt_offset = get_table_entry_id(imximage_boot_offset,
                                        "imximage boot option", token);
-               if (imxhdr->flash_offset == -1) {
+               if (imximage_ivt_offset == -1) {
                        fprintf(stderr, "Error: %s[%d] -Invalid boot device"
                                "(%s)\n", name, lineno, token);
                        exit(EXIT_FAILURE);
                }
+
+               imximage_init_loadsize =
+                       get_table_entry_id(imximage_boot_loadsize,
+                                          "imximage boot option", token);
+
+               if (imximage_init_loadsize == -1) {
+                       fprintf(stderr,
+                               "Error: %s[%d] -Invalid boot device(%s)\n",
+                               name, lineno, token);
+                       exit(EXIT_FAILURE);
+               }
+
+               /*
+                * The SOC loads from the storage starting at address 0
+                * then ensures that the load size contains the offset
+                */
+               if (imximage_init_loadsize < imximage_ivt_offset)
+                       imximage_init_loadsize = imximage_ivt_offset;
                if (unlikely(cmd_ver_first != 1))
                        cmd_ver_first = 0;
                break;
        case CMD_BOOT_OFFSET:
-               imxhdr->flash_offset = get_cfg_value(token, name, lineno);
+               imximage_ivt_offset = get_cfg_value(token, name, lineno);
                if (unlikely(cmd_ver_first != 1))
                        cmd_ver_first = 0;
                break;
@@ -345,6 +400,17 @@ static void parse_cfg_cmd(struct imx_header *imxhdr, int32_t cmd, char *token,
                if (unlikely(cmd_ver_first != 1))
                        cmd_ver_first = 0;
                break;
+       case CMD_CSF:
+               if (imximage_version != 2) {
+                       fprintf(stderr,
+                               "Error: %s[%d] - CSF only supported for VERSION 2(%s)\n",
+                               name, lineno, token);
+                       exit(EXIT_FAILURE);
+               }
+               imximage_csf_size = get_cfg_value(token, name, lineno);
+               if (unlikely(cmd_ver_first != 1))
+                       cmd_ver_first = 0;
+               break;
        }
 }
 
@@ -405,7 +471,8 @@ static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name)
                exit(EXIT_FAILURE);
        }
 
-       /* Very simple parsing, line starting with # are comments
+       /*
+        * Very simple parsing, line starting with # are comments
         * and are dropped
         */
        while ((getline(&line, &len, fd)) > 0) {
@@ -436,7 +503,7 @@ static uint32_t parse_cfg_file(struct imx_header *imxhdr, char *name)
        fclose(fd);
 
        /* Exit if there is no BOOT_FROM field specifying the flash_offset */
-       if (imxhdr->flash_offset == FLASH_OFFSET_UNDEFINED) {
+       if (imximage_ivt_offset == FLASH_OFFSET_UNDEFINED) {
                fprintf(stderr, "Error: No BOOT_FROM tag in %s\n", name);
                exit(EXIT_FAILURE);
        }
@@ -494,14 +561,15 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
         */
        imximage_version = IMXIMAGE_V1;
        /* Be able to detect if the cfg file has no BOOT_FROM tag */
-       imxhdr->flash_offset = FLASH_OFFSET_UNDEFINED;
+       imximage_ivt_offset = FLASH_OFFSET_UNDEFINED;
+       imximage_csf_size = 0;
        set_hdr_func(imxhdr);
 
        /* Parse dcd configuration file */
        dcd_len = parse_cfg_file(imxhdr, params->imagename);
 
        /* Set the imx header */
-       (*set_imx_hdr)(imxhdr, dcd_len, params->ep, imxhdr->flash_offset);
+       (*set_imx_hdr)(imxhdr, dcd_len, params->ep, imximage_ivt_offset);
 
        /*
         * ROM bug alert
@@ -512,7 +580,13 @@ static void imximage_set_header(void *ptr, struct stat *sbuf, int ifd,
         *
         * The remaining fraction of a block bytes would not be loaded!
         */
-       *header_size_ptr = ROUND(sbuf->st_size + imxhdr->flash_offset, 4096);
+       *header_size_ptr = ROUND(sbuf->st_size, 4096);
+
+       if (csf_ptr && imximage_csf_size) {
+               *csf_ptr = params->ep - imximage_init_loadsize +
+                       *header_size_ptr;
+               *header_size_ptr += imximage_csf_size;
+       }
 }
 
 int imximage_check_params(struct mkimage_params *params)
@@ -537,18 +611,92 @@ int imximage_check_params(struct mkimage_params *params)
                (params->xflag) || !(strlen(params->imagename));
 }
 
+static int imximage_generate(struct mkimage_params *params,
+       struct image_type_params *tparams)
+{
+       struct imx_header *imxhdr;
+       size_t alloc_len;
+       struct stat sbuf;
+       char *datafile = params->datafile;
+       uint32_t pad_len;
+
+       memset(&imximage_header, 0, sizeof(imximage_header));
+
+       /*
+        * In order to not change the old imx cfg file
+        * by adding VERSION command into it, here need
+        * set up function ptr group to V1 by default.
+        */
+       imximage_version = IMXIMAGE_V1;
+       /* Be able to detect if the cfg file has no BOOT_FROM tag */
+       imximage_ivt_offset = FLASH_OFFSET_UNDEFINED;
+       imximage_csf_size = 0;
+       set_hdr_func(imxhdr);
+
+       /* Parse dcd configuration file */
+       parse_cfg_file(&imximage_header, params->imagename);
+
+       /* TODO: check i.MX image V1 handling, for now use 'old' style */
+       if (imximage_version == IMXIMAGE_V1) {
+               alloc_len = 4096;
+       } else {
+               if (imximage_init_loadsize < imximage_ivt_offset +
+                       sizeof(imx_header_v2_t))
+                               imximage_init_loadsize = imximage_ivt_offset +
+                                       sizeof(imx_header_v2_t);
+               alloc_len = imximage_init_loadsize - imximage_ivt_offset;
+       }
+
+       if (alloc_len < sizeof(struct imx_header)) {
+               fprintf(stderr, "%s: header error\n",
+                       params->cmdname);
+               exit(EXIT_FAILURE);
+       }
+
+       imxhdr = malloc(alloc_len);
+
+       if (!imxhdr) {
+               fprintf(stderr, "%s: malloc return failure: %s\n",
+                       params->cmdname, strerror(errno));
+               exit(EXIT_FAILURE);
+       }
+
+       memset(imxhdr, 0, alloc_len);
+
+       tparams->header_size = alloc_len;
+       tparams->hdr         = imxhdr;
+
+       /* determine data image file length */
+
+       if (stat(datafile, &sbuf) < 0) {
+               fprintf(stderr, "%s: Can't stat %s: %s\n",
+                       params->cmdname, datafile, strerror(errno));
+               exit(EXIT_FAILURE);
+       }
+
+       pad_len = ROUND(sbuf.st_size, 4096) - sbuf.st_size;
+
+       /* TODO: check i.MX image V1 handling, for now use 'old' style */
+       if (imximage_version == IMXIMAGE_V1)
+               return 0;
+       else
+               return pad_len;
+}
+
+
 /*
  * imximage parameters
  */
 static struct image_type_params imximage_params = {
        .name           = "Freescale i.MX Boot Image support",
-       .header_size    = sizeof(struct imx_header),
-       .hdr            = (void *)&imximage_header,
+       .header_size    = 0,
+       .hdr            = NULL,
        .check_image_type = imximage_check_image_types,
        .verify_header  = imximage_verify_header,
        .print_header   = imximage_print_header,
        .set_header     = imximage_set_header,
        .check_params   = imximage_check_params,
+       .vrec_header    = imximage_generate,
 };
 
 void init_imx_image_type(void)
index 214187bb8c5aa308760116524be4b126ceaf89ed..efe6a88d9ea4ebea22e909f96420a3be176ca872 100644 (file)
 #define APP_CODE_BARKER        0xB1
 #define DCD_BARKER     0xB17219E9
 
-#define HEADER_OFFSET  0x400
-
 /*
  * NOTE: This file must be kept in sync with arch/arm/include/asm/\
  *       imx-common/imximage.cfg because tools/imximage.c can not
  *       cross-include headers from arch/arm/ and vice-versa.
  */
 #define CMD_DATA_STR   "DATA"
+
+/* Initial Vector Table Offset */
 #define FLASH_OFFSET_UNDEFINED 0xFFFFFFFF
 #define FLASH_OFFSET_STANDARD  0x400
 #define FLASH_OFFSET_NAND      FLASH_OFFSET_STANDARD
 #define FLASH_OFFSET_NOR       0x1000
 #define FLASH_OFFSET_SATA      FLASH_OFFSET_STANDARD
 
+/* Initial Load Region Size */
+#define FLASH_LOADSIZE_UNDEFINED       0xFFFFFFFF
+#define FLASH_LOADSIZE_STANDARD                0x1000
+#define FLASH_LOADSIZE_NAND            FLASH_LOADSIZE_STANDARD
+#define FLASH_LOADSIZE_SD              FLASH_LOADSIZE_STANDARD
+#define FLASH_LOADSIZE_SPI             FLASH_LOADSIZE_STANDARD
+#define FLASH_LOADSIZE_ONENAND         0x400
+#define FLASH_LOADSIZE_NOR             0x0 /* entire image */
+#define FLASH_LOADSIZE_SATA            FLASH_LOADSIZE_STANDARD
+
 #define IVT_HEADER_TAG 0xD1
 #define IVT_VERSION 0x40
 #define DCD_HEADER_TAG 0xD2
@@ -42,7 +52,8 @@ enum imximage_cmd {
        CMD_IMAGE_VERSION,
        CMD_BOOT_FROM,
        CMD_BOOT_OFFSET,
-       CMD_DATA
+       CMD_DATA,
+       CMD_CSF,
 };
 
 enum imximage_fld_types {
@@ -147,8 +158,7 @@ struct imx_header {
                imx_header_v1_t hdr_v1;
                imx_header_v2_t hdr_v2;
        } header;
-       uint32_t flash_offset;
-} __attribute__((aligned(4096)));
+};
 
 typedef void (*set_dcd_val_t)(struct imx_header *imxhdr,
                                        char *name, int lineno,
diff --git a/tools/logos/siemens.bmp b/tools/logos/siemens.bmp
new file mode 100644 (file)
index 0000000..bff2b19
Binary files /dev/null and b/tools/logos/siemens.bmp differ
index b700b9e8c0eb424b9022a2f21f54201d0cef3dee..7f221013e38cf20fe9bad4a42d1a7aca387e9924 100644 (file)
@@ -137,6 +137,7 @@ main (int argc, char **argv)
        char *ptr;
        int retval = 0;
        struct image_type_params *tparams = NULL;
+       int pad_len = 0;
 
        /* Init Freescale PBL Boot image generation/list support */
        init_pbl_image_type();
@@ -144,6 +145,8 @@ main (int argc, char **argv)
        init_kwb_image_type ();
        /* Init Freescale imx Boot image generation/list support */
        init_imx_image_type ();
+       /* Init Freescale mxs Boot image generation/list support */
+       init_mxs_image_type();
        /* Init FIT image generation/list support */
        init_fit_image_type ();
        /* Init TI OMAP Boot image generation/list support */
@@ -391,7 +394,7 @@ NXTARG:             ;
         * allocate memory for the header itself.
         */
        if (tparams->vrec_header)
-               tparams->vrec_header(&params, tparams);
+               pad_len = tparams->vrec_header(&params, tparams);
        else
                memset(tparams->hdr, 0, tparams->header_size);
 
@@ -463,7 +466,7 @@ NXTARG:             ;
                        /* PBL has special Image format, implements its' own */
                        pbl_load_uboot(ifd, &params);
                } else {
-                       copy_file (ifd, params.datafile, 0);
+                       copy_file(ifd, params.datafile, pad_len);
                }
        }
 
@@ -537,10 +540,19 @@ copy_file (int ifd, const char *datafile, int pad)
        unsigned char *ptr;
        int tail;
        int zero = 0;
+       uint8_t zeros[4096];
        int offset = 0;
        int size;
        struct image_type_params *tparams = mkimage_get_type (params.type);
 
+       if (pad >= sizeof(zeros)) {
+               fprintf(stderr, "%s: Can't pad to %d\n",
+                       params.cmdname, pad);
+               exit(EXIT_FAILURE);
+       }
+
+       memset(zeros, 0, sizeof(zeros));
+
        if (params.vflag) {
                fprintf (stderr, "Adding Image %s\n", datafile);
        }
@@ -598,7 +610,8 @@ copy_file (int ifd, const char *datafile, int pad)
                exit (EXIT_FAILURE);
        }
 
-       if (pad && ((tail = size % 4) != 0)) {
+       tail = size % 4;
+       if ((pad == 1) && (tail != 0)) {
 
                if (write(ifd, (char *)&zero, 4-tail) != 4-tail) {
                        fprintf (stderr, "%s: Write error on %s: %s\n",
@@ -606,6 +619,13 @@ copy_file (int ifd, const char *datafile, int pad)
                                strerror(errno));
                        exit (EXIT_FAILURE);
                }
+       } else if (pad > 1) {
+               if (write(ifd, (char *)&zeros, pad) != pad) {
+                       fprintf(stderr, "%s: Write error on %s: %s\n",
+                               params.cmdname, params.imagefile,
+                               strerror(errno));
+                       exit(EXIT_FAILURE);
+               }
        }
 
        (void) munmap((void *)ptr, sbuf.st_size);
index 950e19067f0a34b25328b5d691bd51d0b56a63fd..af491544e42b5557a1e06c0afd0aef50d6fa010d 100644 (file)
@@ -132,7 +132,10 @@ struct image_type_params {
        /*
         * This callback function will be executed for variable size record
         * It is expected to build this header in memory and return its length
-        * and a pointer to it
+        * and a pointer to it by using image_type_params.header_size and
+        * image_type_params.hdr. The return value shall indicate if an
+        * additional padding should be used when copying the data image
+        * by returning the padding length.
         */
        int (*vrec_header) (struct mkimage_params *,
                struct image_type_params *);
@@ -158,6 +161,7 @@ void init_pbl_image_type(void);
 void init_ais_image_type(void);
 void init_kwb_image_type (void);
 void init_imx_image_type (void);
+void init_mxs_image_type(void);
 void init_default_image_type (void);
 void init_fit_image_type (void);
 void init_ubl_image_type(void);
index 3d9cc10f0fa8761277509954376e3b7dc3fc9234..1060cbf605f82a382a2db32ac46f550dad8f7ccc 100644 (file)
  *
  * TWEAK this if you have different kind of NAND chip.
  */
-uint32_t nand_writesize = 2048;
-uint32_t nand_oobsize = 64;
-uint32_t nand_erasesize = 128 * 1024;
+static uint32_t nand_writesize = 2048;
+static uint32_t nand_oobsize = 64;
+static uint32_t nand_erasesize = 128 * 1024;
 
 /*
  * Sector on which the SigmaTel boot partition (0x53) starts.
  */
-uint32_t sd_sector = 2048;
+static uint32_t sd_sector = 2048;
 
 /*
  * Each of the U-Boot bootstreams is at maximum 1MB big.
@@ -434,7 +434,7 @@ static int mx28_nand_write_firmware(struct mx28_nand_fcb *fcb, int infd,
        return 0;
 }
 
-void usage(void)
+static void usage(void)
 {
        printf(
                "Usage: mxsboot [ops] <type> <infile> <outfile>\n"
@@ -575,7 +575,7 @@ err0:
        return ret;
 }
 
-int parse_ops(int argc, char **argv)
+static int parse_ops(int argc, char **argv)
 {
        int i;
        int tmp;
diff --git a/tools/mxsimage.c b/tools/mxsimage.c
new file mode 100644 (file)
index 0000000..5db19b2
--- /dev/null
@@ -0,0 +1,2347 @@
+/*
+ * Freescale i.MX23/i.MX28 SB image generator
+ *
+ * Copyright (C) 2012-2013 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifdef CONFIG_MXS
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+
+#include <openssl/evp.h>
+
+#include "mkimage.h"
+#include "mxsimage.h"
+#include <image.h>
+
+
+/*
+ * DCD block
+ * |-Write to address command block
+ * |  0xf00 == 0xf33d
+ * |  0xba2 == 0xb33f
+ * |-ORR address with mask command block
+ * |  0xf00 |= 0x1337
+ * |-Write to address command block
+ * |  0xba2 == 0xd00d
+ * :
+ */
+#define SB_HAB_DCD_WRITE       0xccUL
+#define SB_HAB_DCD_CHECK       0xcfUL
+#define SB_HAB_DCD_NOOP                0xc0UL
+#define SB_HAB_DCD_MASK_BIT    (1 << 3)
+#define SB_HAB_DCD_SET_BIT     (1 << 4)
+
+/* Addr.n = Value.n */
+#define        SB_DCD_WRITE    \
+       (SB_HAB_DCD_WRITE << 24)
+/* Addr.n &= ~Value.n */
+#define        SB_DCD_ANDC     \
+       ((SB_HAB_DCD_WRITE << 24) | SB_HAB_DCD_SET_BIT)
+/* Addr.n |= Value.n */
+#define        SB_DCD_ORR      \
+       ((SB_HAB_DCD_WRITE << 24) | SB_HAB_DCD_SET_BIT | SB_HAB_DCD_MASK_BIT)
+/* (Addr.n & Value.n) == 0 */
+#define        SB_DCD_CHK_EQZ  \
+       (SB_HAB_DCD_CHECK << 24)
+/* (Addr.n & Value.n) == Value.n */
+#define        SB_DCD_CHK_EQ   \
+       ((SB_HAB_DCD_CHECK << 24) | SB_HAB_DCD_SET_BIT)
+/* (Addr.n & Value.n) != Value.n */
+#define        SB_DCD_CHK_NEQ  \
+       ((SB_HAB_DCD_CHECK << 24) | SB_HAB_DCD_MASK_BIT)
+/* (Addr.n & Value.n) != 0 */
+#define        SB_DCD_CHK_NEZ  \
+       ((SB_HAB_DCD_CHECK << 24) | SB_HAB_DCD_SET_BIT | SB_HAB_DCD_MASK_BIT)
+/* NOP */
+#define        SB_DCD_NOOP     \
+       (SB_HAB_DCD_NOOP << 24)
+
+struct sb_dcd_ctx {
+       struct sb_dcd_ctx               *dcd;
+
+       uint32_t                        id;
+
+       /* The DCD block. */
+       uint32_t                        *payload;
+       /* Size of the whole DCD block. */
+       uint32_t                        size;
+
+       /* Pointer to previous DCD command block. */
+       uint32_t                        *prev_dcd_head;
+};
+
+/*
+ * IMAGE
+ *   |-SECTION
+ *   |    |-CMD
+ *   |    |-CMD
+ *   |    `-CMD
+ *   |-SECTION
+ *   |    |-CMD
+ *   :    :
+ */
+struct sb_cmd_list {
+       char                            *cmd;
+       size_t                          len;
+       unsigned int                    lineno;
+};
+
+struct sb_cmd_ctx {
+       uint32_t                        size;
+
+       struct sb_cmd_ctx               *cmd;
+
+       uint8_t                         *data;
+       uint32_t                        length;
+
+       struct sb_command               payload;
+       struct sb_command               c_payload;
+};
+
+struct sb_section_ctx {
+       uint32_t                        size;
+
+       /* Section flags */
+       unsigned int                    boot:1;
+
+       struct sb_section_ctx           *sect;
+
+       struct sb_cmd_ctx               *cmd_head;
+       struct sb_cmd_ctx               *cmd_tail;
+
+       struct sb_sections_header       payload;
+};
+
+struct sb_image_ctx {
+       unsigned int                    in_section:1;
+       unsigned int                    in_dcd:1;
+       /* Image configuration */
+       unsigned int                    verbose_boot:1;
+       unsigned int                    silent_dump:1;
+       char                            *input_filename;
+       char                            *output_filename;
+       char                            *cfg_filename;
+       uint8_t                         image_key[16];
+
+       /* Number of section in the image */
+       unsigned int                    sect_count;
+       /* Bootable section */
+       unsigned int                    sect_boot;
+       unsigned int                    sect_boot_found:1;
+
+       struct sb_section_ctx           *sect_head;
+       struct sb_section_ctx           *sect_tail;
+
+       struct sb_dcd_ctx               *dcd_head;
+       struct sb_dcd_ctx               *dcd_tail;
+
+       EVP_CIPHER_CTX                  cipher_ctx;
+       EVP_MD_CTX                      md_ctx;
+       uint8_t                         digest[32];
+       struct sb_key_dictionary_key    sb_dict_key;
+
+       struct sb_boot_image_header     payload;
+};
+
+/*
+ * Instruction semantics:
+ * NOOP
+ * TAG [LAST]
+ * LOAD       address file
+ * LOAD  IVT  address IVT_entry_point
+ * FILL address pattern length
+ * JUMP [HAB] address [r0_arg]
+ * CALL [HAB] address [r0_arg]
+ * MODE mode
+ *      For i.MX23, mode = USB/I2C/SPI1_FLASH/SPI2_FLASH/NAND_BCH
+ *                         JTAG/SPI3_EEPROM/SD_SSP0/SD_SSP1
+ *      For i.MX28, mode = USB/I2C/SPI2_FLASH/SPI3_FLASH/NAND_BCH
+ *                         JTAG/SPI2_EEPROM/SD_SSP0/SD_SSP1
+ */
+
+/*
+ * AES libcrypto
+ */
+static int sb_aes_init(struct sb_image_ctx *ictx, uint8_t *iv, int enc)
+{
+       EVP_CIPHER_CTX *ctx = &ictx->cipher_ctx;
+       int ret;
+
+       /* If there is no init vector, init vector is all zeroes. */
+       if (!iv)
+               iv = ictx->image_key;
+
+       EVP_CIPHER_CTX_init(ctx);
+       ret = EVP_CipherInit(ctx, EVP_aes_128_cbc(), ictx->image_key, iv, enc);
+       if (ret == 1)
+               EVP_CIPHER_CTX_set_padding(ctx, 0);
+       return ret;
+}
+
+static int sb_aes_crypt(struct sb_image_ctx *ictx, uint8_t *in_data,
+                       uint8_t *out_data, int in_len)
+{
+       EVP_CIPHER_CTX *ctx = &ictx->cipher_ctx;
+       int ret, outlen;
+       uint8_t *outbuf;
+
+       outbuf = malloc(in_len);
+       if (!outbuf)
+               return -ENOMEM;
+       memset(outbuf, 0, sizeof(in_len));
+
+       ret = EVP_CipherUpdate(ctx, outbuf, &outlen, in_data, in_len);
+       if (!ret) {
+               ret = -EINVAL;
+               goto err;
+       }
+
+       if (out_data)
+               memcpy(out_data, outbuf, outlen);
+
+err:
+       free(outbuf);
+       return ret;
+}
+
+static int sb_aes_deinit(EVP_CIPHER_CTX *ctx)
+{
+       return EVP_CIPHER_CTX_cleanup(ctx);
+}
+
+static int sb_aes_reinit(struct sb_image_ctx *ictx, int enc)
+{
+       int ret;
+       EVP_CIPHER_CTX *ctx = &ictx->cipher_ctx;
+       struct sb_boot_image_header *sb_header = &ictx->payload;
+       uint8_t *iv = sb_header->iv;
+
+       ret = sb_aes_deinit(ctx);
+       if (!ret)
+               return ret;
+       return sb_aes_init(ictx, iv, enc);
+}
+
+/*
+ * CRC32
+ */
+static uint32_t crc32(uint8_t *data, uint32_t len)
+{
+       const uint32_t poly = 0x04c11db7;
+       uint32_t crc32 = 0xffffffff;
+       unsigned int byte, bit;
+
+       for (byte = 0; byte < len; byte++) {
+               crc32 ^= data[byte] << 24;
+
+               for (bit = 8; bit > 0; bit--) {
+                       if (crc32 & (1UL << 31))
+                               crc32 = (crc32 << 1) ^ poly;
+                       else
+                               crc32 = (crc32 << 1);
+               }
+       }
+
+       return crc32;
+}
+
+/*
+ * Debug
+ */
+static void soprintf(struct sb_image_ctx *ictx, const char *fmt, ...)
+{
+       va_list ap;
+
+       if (ictx->silent_dump)
+               return;
+
+       va_start(ap, fmt);
+       vfprintf(stdout, fmt, ap);
+       va_end(ap);
+}
+
+/*
+ * Code
+ */
+static time_t sb_get_timestamp(void)
+{
+       struct tm time_2000 = {
+               .tm_yday        = 1,    /* Jan. 1st */
+               .tm_year        = 100,  /* 2000 */
+       };
+       time_t seconds_to_2000 = mktime(&time_2000);
+       time_t seconds_to_now = time(NULL);
+
+       return seconds_to_now - seconds_to_2000;
+}
+
+static int sb_get_time(time_t time, struct tm *tm)
+{
+       struct tm time_2000 = {
+               .tm_yday        = 1,    /* Jan. 1st */
+               .tm_year        = 0,    /* 1900 */
+       };
+       const time_t seconds_to_2000 = mktime(&time_2000);
+       const time_t seconds_to_now = seconds_to_2000 + time;
+       struct tm *ret;
+       ret = gmtime_r(&seconds_to_now, tm);
+       return ret ? 0 : -EINVAL;
+}
+
+static void sb_encrypt_sb_header(struct sb_image_ctx *ictx)
+{
+       EVP_MD_CTX *md_ctx = &ictx->md_ctx;
+       struct sb_boot_image_header *sb_header = &ictx->payload;
+       uint8_t *sb_header_ptr = (uint8_t *)sb_header;
+
+       /* Encrypt the header, compute the digest. */
+       sb_aes_crypt(ictx, sb_header_ptr, NULL, sizeof(*sb_header));
+       EVP_DigestUpdate(md_ctx, sb_header_ptr, sizeof(*sb_header));
+}
+
+static void sb_encrypt_sb_sections_header(struct sb_image_ctx *ictx)
+{
+       EVP_MD_CTX *md_ctx = &ictx->md_ctx;
+       struct sb_section_ctx *sctx = ictx->sect_head;
+       struct sb_sections_header *shdr;
+       uint8_t *sb_sections_header_ptr;
+       const int size = sizeof(*shdr);
+
+       while (sctx) {
+               shdr = &sctx->payload;
+               sb_sections_header_ptr = (uint8_t *)shdr;
+
+               sb_aes_crypt(ictx, sb_sections_header_ptr,
+                            ictx->sb_dict_key.cbc_mac, size);
+               EVP_DigestUpdate(md_ctx, sb_sections_header_ptr, size);
+
+               sctx = sctx->sect;
+       };
+}
+
+static void sb_encrypt_key_dictionary_key(struct sb_image_ctx *ictx)
+{
+       EVP_MD_CTX *md_ctx = &ictx->md_ctx;
+
+       sb_aes_crypt(ictx, ictx->image_key, ictx->sb_dict_key.key,
+                    sizeof(ictx->sb_dict_key.key));
+       EVP_DigestUpdate(md_ctx, &ictx->sb_dict_key, sizeof(ictx->sb_dict_key));
+}
+
+static void sb_decrypt_key_dictionary_key(struct sb_image_ctx *ictx)
+{
+       EVP_MD_CTX *md_ctx = &ictx->md_ctx;
+
+       EVP_DigestUpdate(md_ctx, &ictx->sb_dict_key, sizeof(ictx->sb_dict_key));
+       sb_aes_crypt(ictx, ictx->sb_dict_key.key, ictx->image_key,
+                    sizeof(ictx->sb_dict_key.key));
+}
+
+static void sb_encrypt_tag(struct sb_image_ctx *ictx,
+               struct sb_cmd_ctx *cctx)
+{
+       EVP_MD_CTX *md_ctx = &ictx->md_ctx;
+       struct sb_command *cmd = &cctx->payload;
+
+       sb_aes_crypt(ictx, (uint8_t *)cmd,
+                    (uint8_t *)&cctx->c_payload, sizeof(*cmd));
+       EVP_DigestUpdate(md_ctx, &cctx->c_payload, sizeof(*cmd));
+}
+
+static int sb_encrypt_image(struct sb_image_ctx *ictx)
+{
+       /* Start image-wide crypto. */
+       EVP_MD_CTX_init(&ictx->md_ctx);
+       EVP_DigestInit(&ictx->md_ctx, EVP_sha1());
+
+       /*
+        * SB image header.
+        */
+       sb_aes_init(ictx, NULL, 1);
+       sb_encrypt_sb_header(ictx);
+
+       /*
+        * SB sections header.
+        */
+       sb_encrypt_sb_sections_header(ictx);
+
+       /*
+        * Key dictionary.
+        */
+       sb_aes_reinit(ictx, 1);
+       sb_encrypt_key_dictionary_key(ictx);
+
+       /*
+        * Section tags.
+        */
+       struct sb_cmd_ctx *cctx;
+       struct sb_command *ccmd;
+       struct sb_section_ctx *sctx = ictx->sect_head;
+
+       while (sctx) {
+               cctx = sctx->cmd_head;
+
+               sb_aes_reinit(ictx, 1);
+
+               while (cctx) {
+                       ccmd = &cctx->payload;
+
+                       sb_encrypt_tag(ictx, cctx);
+
+                       if (ccmd->header.tag == ROM_TAG_CMD) {
+                               sb_aes_reinit(ictx, 1);
+                       } else if (ccmd->header.tag == ROM_LOAD_CMD) {
+                               sb_aes_crypt(ictx, cctx->data, cctx->data,
+                                            cctx->length);
+                               EVP_DigestUpdate(&ictx->md_ctx, cctx->data,
+                                                cctx->length);
+                       }
+
+                       cctx = cctx->cmd;
+               }
+
+               sctx = sctx->sect;
+       };
+
+       /*
+        * Dump the SHA1 of the whole image.
+        */
+       sb_aes_reinit(ictx, 1);
+
+       EVP_DigestFinal(&ictx->md_ctx, ictx->digest, NULL);
+       sb_aes_crypt(ictx, ictx->digest, ictx->digest, sizeof(ictx->digest));
+
+       /* Stop the encryption session. */
+       sb_aes_deinit(&ictx->cipher_ctx);
+
+       return 0;
+}
+
+static int sb_load_file(struct sb_cmd_ctx *cctx, char *filename)
+{
+       long real_size, roundup_size;
+       uint8_t *data;
+       long ret;
+       unsigned long size;
+       FILE *fp;
+
+       if (!filename) {
+               fprintf(stderr, "ERR: Missing filename!\n");
+               return -EINVAL;
+       }
+
+       fp = fopen(filename, "r");
+       if (!fp)
+               goto err_open;
+
+       ret = fseek(fp, 0, SEEK_END);
+       if (ret < 0)
+               goto err_file;
+
+       real_size = ftell(fp);
+       if (real_size < 0)
+               goto err_file;
+
+       ret = fseek(fp, 0, SEEK_SET);
+       if (ret < 0)
+               goto err_file;
+
+       roundup_size = roundup(real_size, SB_BLOCK_SIZE);
+       data = calloc(1, roundup_size);
+       if (!data)
+               goto err_file;
+
+       size = fread(data, 1, real_size, fp);
+       if (size != (unsigned long)real_size)
+               goto err_alloc;
+
+       cctx->data = data;
+       cctx->length = roundup_size;
+
+       fclose(fp);
+       return 0;
+
+err_alloc:
+       free(data);
+err_file:
+       fclose(fp);
+err_open:
+       fprintf(stderr, "ERR: Failed to load file \"%s\"\n", filename);
+       return -EINVAL;
+}
+
+static uint8_t sb_command_checksum(struct sb_command *inst)
+{
+       uint8_t *inst_ptr = (uint8_t *)inst;
+       uint8_t csum = 0;
+       unsigned int i;
+
+       for (i = 0; i < sizeof(struct sb_command); i++)
+               csum += inst_ptr[i];
+
+       return csum;
+}
+
+static int sb_token_to_long(char *tok, uint32_t *rid)
+{
+       char *endptr;
+       unsigned long id;
+
+       if (tok[0] != '0' || tok[1] != 'x') {
+               fprintf(stderr, "ERR: Invalid hexadecimal number!\n");
+               return -EINVAL;
+       }
+
+       tok += 2;
+
+       id = strtoul(tok, &endptr, 16);
+       if ((errno == ERANGE && id == ULONG_MAX) || (errno != 0 && id == 0)) {
+               fprintf(stderr, "ERR: Value can't be decoded!\n");
+               return -EINVAL;
+       }
+
+       /* Check for 32-bit overflow. */
+       if (id > 0xffffffff) {
+               fprintf(stderr, "ERR: Value too big!\n");
+               return -EINVAL;
+       }
+
+       if (endptr == tok) {
+               fprintf(stderr, "ERR: Deformed value!\n");
+               return -EINVAL;
+       }
+
+       *rid = (uint32_t)id;
+       return 0;
+}
+
+static int sb_grow_dcd(struct sb_dcd_ctx *dctx, unsigned int inc_size)
+{
+       uint32_t *tmp;
+
+       if (!inc_size)
+               return 0;
+
+       dctx->size += inc_size;
+       tmp = realloc(dctx->payload, dctx->size);
+       if (!tmp)
+               return -ENOMEM;
+
+       dctx->payload = tmp;
+
+       /* Assemble and update the HAB DCD header. */
+       dctx->payload[0] = htonl((SB_HAB_DCD_TAG << 24) |
+                                (dctx->size << 8) |
+                                SB_HAB_VERSION);
+
+       return 0;
+}
+
+static int sb_build_dcd(struct sb_image_ctx *ictx, struct sb_cmd_list *cmd)
+{
+       struct sb_dcd_ctx *dctx;
+
+       char *tok;
+       uint32_t id;
+       int ret;
+
+       dctx = calloc(1, sizeof(*dctx));
+       if (!dctx)
+               return -ENOMEM;
+
+       ret = sb_grow_dcd(dctx, 4);
+       if (ret)
+               goto err_dcd;
+
+       /* Read DCD block number. */
+       tok = strtok(cmd->cmd, " ");
+       if (!tok) {
+               fprintf(stderr, "#%i ERR: DCD block without number!\n",
+                       cmd->lineno);
+               ret = -EINVAL;
+               goto err_dcd;
+       }
+
+       /* Parse the DCD block number. */
+       ret = sb_token_to_long(tok, &id);
+       if (ret) {
+               fprintf(stderr, "#%i ERR: Malformed DCD block number!\n",
+                       cmd->lineno);
+               goto err_dcd;
+       }
+
+       dctx->id = id;
+
+       /*
+        * The DCD block is now constructed. Append it to the list.
+        * WARNING: The DCD size is still not computed and will be
+        * updated while parsing it's commands.
+        */
+       if (!ictx->dcd_head) {
+               ictx->dcd_head = dctx;
+               ictx->dcd_tail = dctx;
+       } else {
+               ictx->dcd_tail->dcd = dctx;
+               ictx->dcd_tail = dctx;
+       }
+
+       return 0;
+
+err_dcd:
+       free(dctx->payload);
+       free(dctx);
+       return ret;
+}
+
+static int sb_build_dcd_block(struct sb_image_ctx *ictx,
+                             struct sb_cmd_list *cmd,
+                             uint32_t type)
+{
+       char *tok;
+       uint32_t address, value, length;
+       int ret;
+
+       struct sb_dcd_ctx *dctx = ictx->dcd_tail;
+       uint32_t *dcd;
+
+       if (dctx->prev_dcd_head && (type != SB_DCD_NOOP) &&
+           ((dctx->prev_dcd_head[0] & 0xff0000ff) == type)) {
+               /* Same instruction as before, just append it. */
+               ret = sb_grow_dcd(dctx, 8);
+               if (ret)
+                       return ret;
+       } else if (type == SB_DCD_NOOP) {
+               ret = sb_grow_dcd(dctx, 4);
+               if (ret)
+                       return ret;
+
+               /* Update DCD command block pointer. */
+               dctx->prev_dcd_head = dctx->payload +
+                               dctx->size / sizeof(*dctx->payload) - 1;
+
+               /* NOOP has only 4 bytes and no payload. */
+               goto noop;
+       } else {
+               /*
+                * Either a different instruction block started now
+                * or this is the first instruction block.
+                */
+               ret = sb_grow_dcd(dctx, 12);
+               if (ret)
+                       return ret;
+
+               /* Update DCD command block pointer. */
+               dctx->prev_dcd_head = dctx->payload +
+                               dctx->size / sizeof(*dctx->payload) - 3;
+       }
+
+       dcd = dctx->payload + dctx->size / sizeof(*dctx->payload) - 2;
+
+       /*
+        * Prepare the command.
+        */
+       tok = strtok(cmd->cmd, " ");
+       if (!tok) {
+               fprintf(stderr, "#%i ERR: Missing DCD address!\n",
+                       cmd->lineno);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       /* Read DCD destination address. */
+       ret = sb_token_to_long(tok, &address);
+       if (ret) {
+               fprintf(stderr, "#%i ERR: Incorrect DCD address!\n",
+                       cmd->lineno);
+               goto err;
+       }
+
+       tok = strtok(NULL, " ");
+       if (!tok) {
+               fprintf(stderr, "#%i ERR: Missing DCD value!\n",
+                       cmd->lineno);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       /* Read DCD operation value. */
+       ret = sb_token_to_long(tok, &value);
+       if (ret) {
+               fprintf(stderr, "#%i ERR: Incorrect DCD value!\n",
+                       cmd->lineno);
+               goto err;
+       }
+
+       /* Fill in the new DCD entry. */
+       dcd[0] = htonl(address);
+       dcd[1] = htonl(value);
+
+noop:
+       /* Update the DCD command block. */
+       length = dctx->size -
+                ((dctx->prev_dcd_head - dctx->payload) *
+                sizeof(*dctx->payload));
+       dctx->prev_dcd_head[0] = htonl(type | (length << 8));
+
+err:
+       return ret;
+}
+
+static int sb_build_section(struct sb_image_ctx *ictx, struct sb_cmd_list *cmd)
+{
+       struct sb_section_ctx *sctx;
+       struct sb_sections_header *shdr;
+       char *tok;
+       uint32_t bootable = 0;
+       uint32_t id;
+       int ret;
+
+       sctx = calloc(1, sizeof(*sctx));
+       if (!sctx)
+               return -ENOMEM;
+
+       /* Read section number. */
+       tok = strtok(cmd->cmd, " ");
+       if (!tok) {
+               fprintf(stderr, "#%i ERR: Section without number!\n",
+                       cmd->lineno);
+               ret = -EINVAL;
+               goto err_sect;
+       }
+
+       /* Parse the section number. */
+       ret = sb_token_to_long(tok, &id);
+       if (ret) {
+               fprintf(stderr, "#%i ERR: Malformed section number!\n",
+                       cmd->lineno);
+               goto err_sect;
+       }
+
+       /* Read section's BOOTABLE flag. */
+       tok = strtok(NULL, " ");
+       if (tok && (strlen(tok) == 8) && !strncmp(tok, "BOOTABLE", 8))
+               bootable = SB_SECTION_FLAG_BOOTABLE;
+
+       sctx->boot = bootable;
+
+       shdr = &sctx->payload;
+       shdr->section_number = id;
+       shdr->section_flags = bootable;
+
+       /*
+        * The section is now constructed. Append it to the list.
+        * WARNING: The section size is still not computed and will
+        * be updated while parsing it's commands.
+        */
+       ictx->sect_count++;
+
+       /* Mark that this section is bootable one. */
+       if (bootable) {
+               if (ictx->sect_boot_found) {
+                       fprintf(stderr,
+                               "#%i WARN: Multiple bootable section!\n",
+                               cmd->lineno);
+               } else {
+                       ictx->sect_boot = id;
+                       ictx->sect_boot_found = 1;
+               }
+       }
+
+       if (!ictx->sect_head) {
+               ictx->sect_head = sctx;
+               ictx->sect_tail = sctx;
+       } else {
+               ictx->sect_tail->sect = sctx;
+               ictx->sect_tail = sctx;
+       }
+
+       return 0;
+
+err_sect:
+       free(sctx);
+       return ret;
+}
+
+static int sb_build_command_nop(struct sb_image_ctx *ictx)
+{
+       struct sb_section_ctx *sctx = ictx->sect_tail;
+       struct sb_cmd_ctx *cctx;
+       struct sb_command *ccmd;
+
+       cctx = calloc(1, sizeof(*cctx));
+       if (!cctx)
+               return -ENOMEM;
+
+       ccmd = &cctx->payload;
+
+       /*
+        * Construct the command.
+        */
+       ccmd->header.checksum   = 0x5a;
+       ccmd->header.tag        = ROM_NOP_CMD;
+
+       cctx->size = sizeof(*ccmd);
+
+       /*
+        * Append the command to the last section.
+        */
+       if (!sctx->cmd_head) {
+               sctx->cmd_head = cctx;
+               sctx->cmd_tail = cctx;
+       } else {
+               sctx->cmd_tail->cmd = cctx;
+               sctx->cmd_tail = cctx;
+       }
+
+       return 0;
+}
+
+static int sb_build_command_tag(struct sb_image_ctx *ictx,
+                               struct sb_cmd_list *cmd)
+{
+       struct sb_section_ctx *sctx = ictx->sect_tail;
+       struct sb_cmd_ctx *cctx;
+       struct sb_command *ccmd;
+       char *tok;
+
+       cctx = calloc(1, sizeof(*cctx));
+       if (!cctx)
+               return -ENOMEM;
+
+       ccmd = &cctx->payload;
+
+       /*
+        * Prepare the command.
+        */
+       /* Check for the LAST keyword. */
+       tok = strtok(cmd->cmd, " ");
+       if (tok && !strcmp(tok, "LAST"))
+               ccmd->header.flags = ROM_TAG_CMD_FLAG_ROM_LAST_TAG;
+
+       /*
+        * Construct the command.
+        */
+       ccmd->header.checksum   = 0x5a;
+       ccmd->header.tag        = ROM_TAG_CMD;
+
+       cctx->size = sizeof(*ccmd);
+
+       /*
+        * Append the command to the last section.
+        */
+       if (!sctx->cmd_head) {
+               sctx->cmd_head = cctx;
+               sctx->cmd_tail = cctx;
+       } else {
+               sctx->cmd_tail->cmd = cctx;
+               sctx->cmd_tail = cctx;
+       }
+
+       return 0;
+}
+
+static int sb_build_command_load(struct sb_image_ctx *ictx,
+                                struct sb_cmd_list *cmd)
+{
+       struct sb_section_ctx *sctx = ictx->sect_tail;
+       struct sb_cmd_ctx *cctx;
+       struct sb_command *ccmd;
+       char *tok;
+       int ret, is_ivt = 0, is_dcd = 0;
+       uint32_t dest, dcd = 0;
+
+       cctx = calloc(1, sizeof(*cctx));
+       if (!cctx)
+               return -ENOMEM;
+
+       ccmd = &cctx->payload;
+
+       /*
+        * Prepare the command.
+        */
+       tok = strtok(cmd->cmd, " ");
+       if (!tok) {
+               fprintf(stderr, "#%i ERR: Missing LOAD address or 'IVT'!\n",
+                       cmd->lineno);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       /* Check for "IVT" flag. */
+       if (!strcmp(tok, "IVT"))
+               is_ivt = 1;
+       if (!strcmp(tok, "DCD"))
+               is_dcd = 1;
+       if (is_ivt || is_dcd) {
+               tok = strtok(NULL, " ");
+               if (!tok) {
+                       fprintf(stderr, "#%i ERR: Missing LOAD address!\n",
+                               cmd->lineno);
+                       ret = -EINVAL;
+                       goto err;
+               }
+       }
+
+       /* Read load destination address. */
+       ret = sb_token_to_long(tok, &dest);
+       if (ret) {
+               fprintf(stderr, "#%i ERR: Incorrect LOAD address!\n",
+                       cmd->lineno);
+               goto err;
+       }
+
+       /* Read filename or IVT entrypoint or DCD block ID. */
+       tok = strtok(NULL, " ");
+       if (!tok) {
+               fprintf(stderr,
+                       "#%i ERR: Missing LOAD filename or IVT ep or DCD block ID!\n",
+                       cmd->lineno);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       if (is_ivt) {
+               /* Handle IVT. */
+               struct sb_ivt_header *ivt;
+               uint32_t ivtep;
+               ret = sb_token_to_long(tok, &ivtep);
+
+               if (ret) {
+                       fprintf(stderr,
+                               "#%i ERR: Incorrect IVT entry point!\n",
+                               cmd->lineno);
+                       goto err;
+               }
+
+               ivt = calloc(1, sizeof(*ivt));
+               if (!ivt) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
+
+               ivt->header = sb_hab_ivt_header();
+               ivt->entry = ivtep;
+               ivt->self = dest;
+
+               cctx->data = (uint8_t *)ivt;
+               cctx->length = sizeof(*ivt);
+       } else if (is_dcd) {
+               struct sb_dcd_ctx *dctx = ictx->dcd_head;
+               uint32_t dcdid;
+               uint8_t *payload;
+               uint32_t asize;
+               ret = sb_token_to_long(tok, &dcdid);
+
+               if (ret) {
+                       fprintf(stderr,
+                               "#%i ERR: Incorrect DCD block ID!\n",
+                               cmd->lineno);
+                       goto err;
+               }
+
+               while (dctx) {
+                       if (dctx->id == dcdid)
+                               break;
+                       dctx = dctx->dcd;
+               }
+
+               if (!dctx) {
+                       fprintf(stderr, "#%i ERR: DCD block %08x not found!\n",
+                               cmd->lineno, dcdid);
+                       goto err;
+               }
+
+               asize = roundup(dctx->size, SB_BLOCK_SIZE);
+               payload = calloc(1, asize);
+               if (!payload) {
+                       ret = -ENOMEM;
+                       goto err;
+               }
+
+               memcpy(payload, dctx->payload, dctx->size);
+
+               cctx->data = payload;
+               cctx->length = asize;
+
+               /* Set the Load DCD flag. */
+               dcd = ROM_LOAD_CMD_FLAG_DCD_LOAD;
+       } else {
+               /* Regular LOAD of a file. */
+               ret = sb_load_file(cctx, tok);
+               if (ret) {
+                       fprintf(stderr, "#%i ERR: Cannot load '%s'!\n",
+                               cmd->lineno, tok);
+                       goto err;
+               }
+       }
+
+       if (cctx->length & (SB_BLOCK_SIZE - 1)) {
+               fprintf(stderr, "#%i ERR: Unaligned payload!\n",
+                       cmd->lineno);
+       }
+
+       /*
+        * Construct the command.
+        */
+       ccmd->header.checksum   = 0x5a;
+       ccmd->header.tag        = ROM_LOAD_CMD;
+       ccmd->header.flags      = dcd;
+
+       ccmd->load.address      = dest;
+       ccmd->load.count        = cctx->length;
+       ccmd->load.crc32        = crc32(cctx->data, cctx->length);
+
+       cctx->size = sizeof(*ccmd) + cctx->length;
+
+       /*
+        * Append the command to the last section.
+        */
+       if (!sctx->cmd_head) {
+               sctx->cmd_head = cctx;
+               sctx->cmd_tail = cctx;
+       } else {
+               sctx->cmd_tail->cmd = cctx;
+               sctx->cmd_tail = cctx;
+       }
+
+       return 0;
+
+err:
+       free(cctx);
+       return ret;
+}
+
+static int sb_build_command_fill(struct sb_image_ctx *ictx,
+                                struct sb_cmd_list *cmd)
+{
+       struct sb_section_ctx *sctx = ictx->sect_tail;
+       struct sb_cmd_ctx *cctx;
+       struct sb_command *ccmd;
+       char *tok;
+       uint32_t address, pattern, length;
+       int ret;
+
+       cctx = calloc(1, sizeof(*cctx));
+       if (!cctx)
+               return -ENOMEM;
+
+       ccmd = &cctx->payload;
+
+       /*
+        * Prepare the command.
+        */
+       tok = strtok(cmd->cmd, " ");
+       if (!tok) {
+               fprintf(stderr, "#%i ERR: Missing FILL address!\n",
+                       cmd->lineno);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       /* Read fill destination address. */
+       ret = sb_token_to_long(tok, &address);
+       if (ret) {
+               fprintf(stderr, "#%i ERR: Incorrect FILL address!\n",
+                       cmd->lineno);
+               goto err;
+       }
+
+       tok = strtok(NULL, " ");
+       if (!tok) {
+               fprintf(stderr, "#%i ERR: Missing FILL pattern!\n",
+                       cmd->lineno);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       /* Read fill pattern address. */
+       ret = sb_token_to_long(tok, &pattern);
+       if (ret) {
+               fprintf(stderr, "#%i ERR: Incorrect FILL pattern!\n",
+                       cmd->lineno);
+               goto err;
+       }
+
+       tok = strtok(NULL, " ");
+       if (!tok) {
+               fprintf(stderr, "#%i ERR: Missing FILL length!\n",
+                       cmd->lineno);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       /* Read fill pattern address. */
+       ret = sb_token_to_long(tok, &length);
+       if (ret) {
+               fprintf(stderr, "#%i ERR: Incorrect FILL length!\n",
+                       cmd->lineno);
+               goto err;
+       }
+
+       /*
+        * Construct the command.
+        */
+       ccmd->header.checksum   = 0x5a;
+       ccmd->header.tag        = ROM_FILL_CMD;
+
+       ccmd->fill.address      = address;
+       ccmd->fill.count        = length;
+       ccmd->fill.pattern      = pattern;
+
+       cctx->size = sizeof(*ccmd);
+
+       /*
+        * Append the command to the last section.
+        */
+       if (!sctx->cmd_head) {
+               sctx->cmd_head = cctx;
+               sctx->cmd_tail = cctx;
+       } else {
+               sctx->cmd_tail->cmd = cctx;
+               sctx->cmd_tail = cctx;
+       }
+
+       return 0;
+
+err:
+       free(cctx);
+       return ret;
+}
+
+static int sb_build_command_jump_call(struct sb_image_ctx *ictx,
+                                     struct sb_cmd_list *cmd,
+                                     unsigned int is_call)
+{
+       struct sb_section_ctx *sctx = ictx->sect_tail;
+       struct sb_cmd_ctx *cctx;
+       struct sb_command *ccmd;
+       char *tok;
+       uint32_t dest, arg = 0x0;
+       uint32_t hab = 0;
+       int ret;
+       const char *cmdname = is_call ? "CALL" : "JUMP";
+
+       cctx = calloc(1, sizeof(*cctx));
+       if (!cctx)
+               return -ENOMEM;
+
+       ccmd = &cctx->payload;
+
+       /*
+        * Prepare the command.
+        */
+       tok = strtok(cmd->cmd, " ");
+       if (!tok) {
+               fprintf(stderr,
+                       "#%i ERR: Missing %s address or 'HAB'!\n",
+                       cmd->lineno, cmdname);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       /* Check for "HAB" flag. */
+       if (!strcmp(tok, "HAB")) {
+               hab = is_call ? ROM_CALL_CMD_FLAG_HAB : ROM_JUMP_CMD_FLAG_HAB;
+               tok = strtok(NULL, " ");
+               if (!tok) {
+                       fprintf(stderr, "#%i ERR: Missing %s address!\n",
+                               cmd->lineno, cmdname);
+                       ret = -EINVAL;
+                       goto err;
+               }
+       }
+       /* Read load destination address. */
+       ret = sb_token_to_long(tok, &dest);
+       if (ret) {
+               fprintf(stderr, "#%i ERR: Incorrect %s address!\n",
+                       cmd->lineno, cmdname);
+               goto err;
+       }
+
+       tok = strtok(NULL, " ");
+       if (tok) {
+               ret = sb_token_to_long(tok, &arg);
+               if (ret) {
+                       fprintf(stderr,
+                               "#%i ERR: Incorrect %s argument!\n",
+                               cmd->lineno, cmdname);
+                       goto err;
+               }
+       }
+
+       /*
+        * Construct the command.
+        */
+       ccmd->header.checksum   = 0x5a;
+       ccmd->header.tag        = is_call ? ROM_CALL_CMD : ROM_JUMP_CMD;
+       ccmd->header.flags      = hab;
+
+       ccmd->call.address      = dest;
+       ccmd->call.argument     = arg;
+
+       cctx->size = sizeof(*ccmd);
+
+       /*
+        * Append the command to the last section.
+        */
+       if (!sctx->cmd_head) {
+               sctx->cmd_head = cctx;
+               sctx->cmd_tail = cctx;
+       } else {
+               sctx->cmd_tail->cmd = cctx;
+               sctx->cmd_tail = cctx;
+       }
+
+       return 0;
+
+err:
+       free(cctx);
+       return ret;
+}
+
+static int sb_build_command_jump(struct sb_image_ctx *ictx,
+                                struct sb_cmd_list *cmd)
+{
+       return sb_build_command_jump_call(ictx, cmd, 0);
+}
+
+static int sb_build_command_call(struct sb_image_ctx *ictx,
+                                struct sb_cmd_list *cmd)
+{
+       return sb_build_command_jump_call(ictx, cmd, 1);
+}
+
+static int sb_build_command_mode(struct sb_image_ctx *ictx,
+                                struct sb_cmd_list *cmd)
+{
+       struct sb_section_ctx *sctx = ictx->sect_tail;
+       struct sb_cmd_ctx *cctx;
+       struct sb_command *ccmd;
+       char *tok;
+       int ret;
+       unsigned int i;
+       uint32_t mode = 0xffffffff;
+
+       cctx = calloc(1, sizeof(*cctx));
+       if (!cctx)
+               return -ENOMEM;
+
+       ccmd = &cctx->payload;
+
+       /*
+        * Prepare the command.
+        */
+       tok = strtok(cmd->cmd, " ");
+       if (!tok) {
+               fprintf(stderr, "#%i ERR: Missing MODE boot mode argument!\n",
+                       cmd->lineno);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(modetable); i++) {
+               if (!strcmp(tok, modetable[i].name)) {
+                       mode = modetable[i].mode;
+                       break;
+               }
+
+               if (!modetable[i].altname)
+                       continue;
+
+               if (!strcmp(tok, modetable[i].altname)) {
+                       mode = modetable[i].mode;
+                       break;
+               }
+       }
+
+       if (mode == 0xffffffff) {
+               fprintf(stderr, "#%i ERR: Invalid MODE boot mode argument!\n",
+                       cmd->lineno);
+               ret = -EINVAL;
+               goto err;
+       }
+
+       /*
+        * Construct the command.
+        */
+       ccmd->header.checksum   = 0x5a;
+       ccmd->header.tag        = ROM_MODE_CMD;
+
+       ccmd->mode.mode         = mode;
+
+       cctx->size = sizeof(*ccmd);
+
+       /*
+        * Append the command to the last section.
+        */
+       if (!sctx->cmd_head) {
+               sctx->cmd_head = cctx;
+               sctx->cmd_tail = cctx;
+       } else {
+               sctx->cmd_tail->cmd = cctx;
+               sctx->cmd_tail = cctx;
+       }
+
+       return 0;
+
+err:
+       free(cctx);
+       return ret;
+}
+
+static int sb_prefill_image_header(struct sb_image_ctx *ictx)
+{
+       struct sb_boot_image_header *hdr = &ictx->payload;
+
+       /* Fill signatures */
+       memcpy(hdr->signature1, "STMP", 4);
+       memcpy(hdr->signature2, "sgtl", 4);
+
+       /* SB Image version 1.1 */
+       hdr->major_version = SB_VERSION_MAJOR;
+       hdr->minor_version = SB_VERSION_MINOR;
+
+       /* Boot image major version */
+       hdr->product_version.major = htons(0x999);
+       hdr->product_version.minor = htons(0x999);
+       hdr->product_version.revision = htons(0x999);
+       /* Boot image major version */
+       hdr->component_version.major = htons(0x999);
+       hdr->component_version.minor = htons(0x999);
+       hdr->component_version.revision = htons(0x999);
+
+       /* Drive tag must be 0x0 for i.MX23 */
+       hdr->drive_tag = 0;
+
+       hdr->header_blocks =
+               sizeof(struct sb_boot_image_header) / SB_BLOCK_SIZE;
+       hdr->section_header_size =
+               sizeof(struct sb_sections_header) / SB_BLOCK_SIZE;
+       hdr->timestamp_us = sb_get_timestamp() * 1000000;
+
+       /* FIXME -- add proper config option */
+       hdr->flags = ictx->verbose_boot ? SB_IMAGE_FLAG_VERBOSE : 0,
+
+       /* FIXME -- We support only default key */
+       hdr->key_count = 1;
+
+       return 0;
+}
+
+static int sb_postfill_image_header(struct sb_image_ctx *ictx)
+{
+       struct sb_boot_image_header *hdr = &ictx->payload;
+       struct sb_section_ctx *sctx = ictx->sect_head;
+       uint32_t kd_size, sections_blocks;
+       EVP_MD_CTX md_ctx;
+
+       /* The main SB header size in blocks. */
+       hdr->image_blocks = hdr->header_blocks;
+
+       /* Size of the key dictionary, which has single zero entry. */
+       kd_size = hdr->key_count * sizeof(struct sb_key_dictionary_key);
+       hdr->image_blocks += kd_size / SB_BLOCK_SIZE;
+
+       /* Now count the payloads. */
+       hdr->section_count = ictx->sect_count;
+       while (sctx) {
+               hdr->image_blocks += sctx->size / SB_BLOCK_SIZE;
+               sctx = sctx->sect;
+       }
+
+       if (!ictx->sect_boot_found) {
+               fprintf(stderr, "ERR: No bootable section selected!\n");
+               return -EINVAL;
+       }
+       hdr->first_boot_section_id = ictx->sect_boot;
+
+       /* The n * SB section size in blocks. */
+       sections_blocks = hdr->section_count * hdr->section_header_size;
+       hdr->image_blocks += sections_blocks;
+
+       /* Key dictionary offset. */
+       hdr->key_dictionary_block = hdr->header_blocks + sections_blocks;
+
+       /* Digest of the whole image. */
+       hdr->image_blocks += 2;
+
+       /* Pointer past the dictionary. */
+       hdr->first_boot_tag_block =
+               hdr->key_dictionary_block + kd_size / SB_BLOCK_SIZE;
+
+       /* Compute header digest. */
+       EVP_MD_CTX_init(&md_ctx);
+
+       EVP_DigestInit(&md_ctx, EVP_sha1());
+       EVP_DigestUpdate(&md_ctx, hdr->signature1,
+                        sizeof(struct sb_boot_image_header) -
+                        sizeof(hdr->digest));
+       EVP_DigestFinal(&md_ctx, hdr->digest, NULL);
+
+       return 0;
+}
+
+static int sb_fixup_sections_and_tags(struct sb_image_ctx *ictx)
+{
+       /* Fixup the placement of sections. */
+       struct sb_boot_image_header *ihdr = &ictx->payload;
+       struct sb_section_ctx *sctx = ictx->sect_head;
+       struct sb_sections_header *shdr;
+       struct sb_cmd_ctx *cctx;
+       struct sb_command *ccmd;
+       uint32_t offset = ihdr->first_boot_tag_block;
+
+       while (sctx) {
+               shdr = &sctx->payload;
+
+               /* Fill in the section TAG offset. */
+               shdr->section_offset = offset + 1;
+               offset += shdr->section_size;
+
+               /* Section length is measured from the TAG block. */
+               shdr->section_size--;
+
+               /* Fixup the TAG command. */
+               cctx = sctx->cmd_head;
+               while (cctx) {
+                       ccmd = &cctx->payload;
+                       if (ccmd->header.tag == ROM_TAG_CMD) {
+                               ccmd->tag.section_number = shdr->section_number;
+                               ccmd->tag.section_length = shdr->section_size;
+                               ccmd->tag.section_flags = shdr->section_flags;
+                       }
+
+                       /* Update the command checksum. */
+                       ccmd->header.checksum = sb_command_checksum(ccmd);
+
+                       cctx = cctx->cmd;
+               }
+
+               sctx = sctx->sect;
+       }
+
+       return 0;
+}
+
+static int sb_parse_line(struct sb_image_ctx *ictx, struct sb_cmd_list *cmd)
+{
+       char *tok;
+       char *line = cmd->cmd;
+       char *rptr;
+       int ret;
+
+       /* Analyze the identifier on this line first. */
+       tok = strtok_r(line, " ", &rptr);
+       if (!tok || (strlen(tok) == 0)) {
+               fprintf(stderr, "#%i ERR: Invalid line!\n", cmd->lineno);
+               return -EINVAL;
+       }
+
+       cmd->cmd = rptr;
+
+       /* DCD */
+       if (!strcmp(tok, "DCD")) {
+               ictx->in_section = 0;
+               ictx->in_dcd = 1;
+               sb_build_dcd(ictx, cmd);
+               return 0;
+       }
+
+       /* Section */
+       if (!strcmp(tok, "SECTION")) {
+               ictx->in_section = 1;
+               ictx->in_dcd = 0;
+               sb_build_section(ictx, cmd);
+               return 0;
+       }
+
+       if (!ictx->in_section && !ictx->in_dcd) {
+               fprintf(stderr, "#%i ERR: Data outside of a section!\n",
+                       cmd->lineno);
+               return -EINVAL;
+       }
+
+       if (ictx->in_section) {
+               /* Section commands */
+               if (!strcmp(tok, "NOP")) {
+                       ret = sb_build_command_nop(ictx);
+               } else if (!strcmp(tok, "TAG")) {
+                       ret = sb_build_command_tag(ictx, cmd);
+               } else if (!strcmp(tok, "LOAD")) {
+                       ret = sb_build_command_load(ictx, cmd);
+               } else if (!strcmp(tok, "FILL")) {
+                       ret = sb_build_command_fill(ictx, cmd);
+               } else if (!strcmp(tok, "JUMP")) {
+                       ret = sb_build_command_jump(ictx, cmd);
+               } else if (!strcmp(tok, "CALL")) {
+                       ret = sb_build_command_call(ictx, cmd);
+               } else if (!strcmp(tok, "MODE")) {
+                       ret = sb_build_command_mode(ictx, cmd);
+               } else {
+                       fprintf(stderr,
+                               "#%i ERR: Unsupported instruction '%s'!\n",
+                               cmd->lineno, tok);
+                       return -ENOTSUP;
+               }
+       } else if (ictx->in_dcd) {
+               char *lptr;
+               uint32_t ilen = '1';
+
+               tok = strtok_r(tok, ".", &lptr);
+               if (!tok || (strlen(tok) == 0) || (lptr && strlen(lptr) != 1)) {
+                       fprintf(stderr, "#%i ERR: Invalid line!\n",
+                               cmd->lineno);
+                       return -EINVAL;
+               }
+
+               if (lptr &&
+                   (lptr[0] != '1' && lptr[0] != '2' && lptr[0] != '4')) {
+                       fprintf(stderr, "#%i ERR: Invalid instruction width!\n",
+                               cmd->lineno);
+                       return -EINVAL;
+               }
+
+               if (lptr)
+                       ilen = lptr[0] - '1';
+
+               /* DCD commands */
+               if (!strcmp(tok, "WRITE")) {
+                       ret = sb_build_dcd_block(ictx, cmd,
+                                                SB_DCD_WRITE | ilen);
+               } else if (!strcmp(tok, "ANDC")) {
+                       ret = sb_build_dcd_block(ictx, cmd,
+                                                SB_DCD_ANDC | ilen);
+               } else if (!strcmp(tok, "ORR")) {
+                       ret = sb_build_dcd_block(ictx, cmd,
+                                                SB_DCD_ORR | ilen);
+               } else if (!strcmp(tok, "EQZ")) {
+                       ret = sb_build_dcd_block(ictx, cmd,
+                                                SB_DCD_CHK_EQZ | ilen);
+               } else if (!strcmp(tok, "EQ")) {
+                       ret = sb_build_dcd_block(ictx, cmd,
+                                                SB_DCD_CHK_EQ | ilen);
+               } else if (!strcmp(tok, "NEQ")) {
+                       ret = sb_build_dcd_block(ictx, cmd,
+                                                SB_DCD_CHK_NEQ | ilen);
+               } else if (!strcmp(tok, "NEZ")) {
+                       ret = sb_build_dcd_block(ictx, cmd,
+                                                SB_DCD_CHK_NEZ | ilen);
+               } else if (!strcmp(tok, "NOOP")) {
+                       ret = sb_build_dcd_block(ictx, cmd, SB_DCD_NOOP);
+               } else {
+                       fprintf(stderr,
+                               "#%i ERR: Unsupported instruction '%s'!\n",
+                               cmd->lineno, tok);
+                       return -ENOTSUP;
+               }
+       } else {
+               fprintf(stderr, "#%i ERR: Unsupported instruction '%s'!\n",
+                       cmd->lineno, tok);
+               return -ENOTSUP;
+       }
+
+       /*
+        * Here we have at least one section with one command, otherwise we
+        * would have failed already higher above.
+        *
+        * FIXME -- should the updating happen here ?
+        */
+       if (ictx->in_section && !ret) {
+               ictx->sect_tail->size += ictx->sect_tail->cmd_tail->size;
+               ictx->sect_tail->payload.section_size =
+                       ictx->sect_tail->size / SB_BLOCK_SIZE;
+       }
+
+       return ret;
+}
+
+static int sb_load_cmdfile(struct sb_image_ctx *ictx)
+{
+       struct sb_cmd_list cmd;
+       int lineno = 1;
+       FILE *fp;
+       char *line = NULL;
+       ssize_t rlen;
+       size_t len;
+
+       fp = fopen(ictx->cfg_filename, "r");
+       if (!fp)
+               goto err_file;
+
+       while ((rlen = getline(&line, &len, fp)) > 0) {
+               memset(&cmd, 0, sizeof(cmd));
+
+               /* Strip the trailing newline. */
+               line[rlen - 1] = '\0';
+
+               cmd.cmd = line;
+               cmd.len = rlen;
+               cmd.lineno = lineno++;
+
+               sb_parse_line(ictx, &cmd);
+       }
+
+       free(line);
+
+       fclose(fp);
+
+       return 0;
+
+err_file:
+       fclose(fp);
+       fprintf(stderr, "ERR: Failed to load file \"%s\"\n",
+               ictx->cfg_filename);
+       return -EINVAL;
+}
+
+static int sb_build_tree_from_cfg(struct sb_image_ctx *ictx)
+{
+       int ret;
+
+       ret = sb_load_cmdfile(ictx);
+       if (ret)
+               return ret;
+
+       ret = sb_prefill_image_header(ictx);
+       if (ret)
+               return ret;
+
+       ret = sb_postfill_image_header(ictx);
+       if (ret)
+               return ret;
+
+       ret = sb_fixup_sections_and_tags(ictx);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static int sb_verify_image_header(struct sb_image_ctx *ictx,
+                                 FILE *fp, long fsize)
+{
+       /* Verify static fields in the image header. */
+       struct sb_boot_image_header *hdr = &ictx->payload;
+       const char *stat[2] = { "[PASS]", "[FAIL]" };
+       struct tm tm;
+       int sz, ret = 0;
+       unsigned char digest[20];
+       EVP_MD_CTX md_ctx;
+       unsigned long size;
+
+       /* Start image-wide crypto. */
+       EVP_MD_CTX_init(&ictx->md_ctx);
+       EVP_DigestInit(&ictx->md_ctx, EVP_sha1());
+
+       soprintf(ictx, "---------- Verifying SB Image Header ----------\n");
+
+       size = fread(&ictx->payload, 1, sizeof(ictx->payload), fp);
+       if (size != sizeof(ictx->payload)) {
+               fprintf(stderr, "ERR: SB image header too short!\n");
+               return -EINVAL;
+       }
+
+       /* Compute header digest. */
+       EVP_MD_CTX_init(&md_ctx);
+       EVP_DigestInit(&md_ctx, EVP_sha1());
+       EVP_DigestUpdate(&md_ctx, hdr->signature1,
+                        sizeof(struct sb_boot_image_header) -
+                        sizeof(hdr->digest));
+       EVP_DigestFinal(&md_ctx, digest, NULL);
+
+       sb_aes_init(ictx, NULL, 1);
+       sb_encrypt_sb_header(ictx);
+
+       if (memcmp(digest, hdr->digest, 20))
+               ret = -EINVAL;
+       soprintf(ictx, "%s Image header checksum:        %s\n", stat[!!ret],
+                ret ? "BAD" : "OK");
+       if (ret)
+               return ret;
+
+       if (memcmp(hdr->signature1, "STMP", 4) ||
+           memcmp(hdr->signature2, "sgtl", 4))
+               ret = -EINVAL;
+       soprintf(ictx, "%s Signatures:                   '%.4s' '%.4s'\n",
+                stat[!!ret], hdr->signature1, hdr->signature2);
+       if (ret)
+               return ret;
+
+       if ((hdr->major_version != SB_VERSION_MAJOR) ||
+           ((hdr->minor_version != 1) && (hdr->minor_version != 2)))
+               ret = -EINVAL;
+       soprintf(ictx, "%s Image version:                v%i.%i\n", stat[!!ret],
+                hdr->major_version, hdr->minor_version);
+       if (ret)
+               return ret;
+
+       ret = sb_get_time(hdr->timestamp_us / 1000000, &tm);
+       soprintf(ictx,
+                "%s Creation time:                %02i:%02i:%02i %02i/%02i/%04i\n",
+                stat[!!ret], tm.tm_hour, tm.tm_min, tm.tm_sec,
+                tm.tm_mday, tm.tm_mon, tm.tm_year + 2000);
+       if (ret)
+               return ret;
+
+       soprintf(ictx, "%s Product version:              %x.%x.%x\n", stat[0],
+                ntohs(hdr->product_version.major),
+                ntohs(hdr->product_version.minor),
+                ntohs(hdr->product_version.revision));
+       soprintf(ictx, "%s Component version:            %x.%x.%x\n", stat[0],
+                ntohs(hdr->component_version.major),
+                ntohs(hdr->component_version.minor),
+                ntohs(hdr->component_version.revision));
+
+       if (hdr->flags & ~SB_IMAGE_FLAG_VERBOSE)
+               ret = -EINVAL;
+       soprintf(ictx, "%s Image flags:                  %s\n", stat[!!ret],
+                hdr->flags & SB_IMAGE_FLAG_VERBOSE ? "Verbose_boot" : "");
+       if (ret)
+               return ret;
+
+       if (hdr->drive_tag != 0)
+               ret = -EINVAL;
+       soprintf(ictx, "%s Drive tag:                    %i\n", stat[!!ret],
+                hdr->drive_tag);
+       if (ret)
+               return ret;
+
+       sz = sizeof(struct sb_boot_image_header) / SB_BLOCK_SIZE;
+       if (hdr->header_blocks != sz)
+               ret = -EINVAL;
+       soprintf(ictx, "%s Image header size (blocks):   %i\n", stat[!!ret],
+                hdr->header_blocks);
+       if (ret)
+               return ret;
+
+       sz = sizeof(struct sb_sections_header) / SB_BLOCK_SIZE;
+       if (hdr->section_header_size != sz)
+               ret = -EINVAL;
+       soprintf(ictx, "%s Section header size (blocks): %i\n", stat[!!ret],
+                hdr->section_header_size);
+       if (ret)
+               return ret;
+
+       soprintf(ictx, "%s Sections count:               %i\n", stat[!!ret],
+                hdr->section_count);
+       soprintf(ictx, "%s First bootable section        %i\n", stat[!!ret],
+                hdr->first_boot_section_id);
+
+       if (hdr->image_blocks != fsize / SB_BLOCK_SIZE)
+               ret = -EINVAL;
+       soprintf(ictx, "%s Image size (blocks):          %i\n", stat[!!ret],
+                hdr->image_blocks);
+       if (ret)
+               return ret;
+
+       sz = hdr->header_blocks + hdr->section_header_size * hdr->section_count;
+       if (hdr->key_dictionary_block != sz)
+               ret = -EINVAL;
+       soprintf(ictx, "%s Key dict offset (blocks):     %i\n", stat[!!ret],
+                hdr->key_dictionary_block);
+       if (ret)
+               return ret;
+
+       if (hdr->key_count != 1)
+               ret = -EINVAL;
+       soprintf(ictx, "%s Number of encryption keys:    %i\n", stat[!!ret],
+                hdr->key_count);
+       if (ret)
+               return ret;
+
+       sz = hdr->header_blocks + hdr->section_header_size * hdr->section_count;
+       sz += hdr->key_count *
+               sizeof(struct sb_key_dictionary_key) / SB_BLOCK_SIZE;
+       if (hdr->first_boot_tag_block != (unsigned)sz)
+               ret = -EINVAL;
+       soprintf(ictx, "%s First TAG block (blocks):     %i\n", stat[!!ret],
+                hdr->first_boot_tag_block);
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
+static void sb_decrypt_tag(struct sb_image_ctx *ictx,
+               struct sb_cmd_ctx *cctx)
+{
+       EVP_MD_CTX *md_ctx = &ictx->md_ctx;
+       struct sb_command *cmd = &cctx->payload;
+
+       sb_aes_crypt(ictx, (uint8_t *)&cctx->c_payload,
+                    (uint8_t *)&cctx->payload, sizeof(*cmd));
+       EVP_DigestUpdate(md_ctx, &cctx->c_payload, sizeof(*cmd));
+}
+
+static int sb_verify_command(struct sb_image_ctx *ictx,
+                            struct sb_cmd_ctx *cctx, FILE *fp,
+                            unsigned long *tsize)
+{
+       struct sb_command *ccmd = &cctx->payload;
+       unsigned long size, asize;
+       char *csum, *flag = "";
+       int ret;
+       unsigned int i;
+       uint8_t csn, csc = ccmd->header.checksum;
+       ccmd->header.checksum = 0x5a;
+       csn = sb_command_checksum(ccmd);
+       ccmd->header.checksum = csc;
+
+       if (csc == csn)
+               ret = 0;
+       else
+               ret = -EINVAL;
+       csum = ret ? "checksum BAD" : "checksum OK";
+
+       switch (ccmd->header.tag) {
+       case ROM_NOP_CMD:
+               soprintf(ictx, " NOOP # %s\n", csum);
+               return ret;
+       case ROM_TAG_CMD:
+               if (ccmd->header.flags & ROM_TAG_CMD_FLAG_ROM_LAST_TAG)
+                       flag = "LAST";
+               soprintf(ictx, " TAG %s # %s\n", flag, csum);
+               sb_aes_reinit(ictx, 0);
+               return ret;
+       case ROM_LOAD_CMD:
+               soprintf(ictx, " LOAD addr=0x%08x length=0x%08x # %s\n",
+                        ccmd->load.address, ccmd->load.count, csum);
+
+               cctx->length = ccmd->load.count;
+               asize = roundup(cctx->length, SB_BLOCK_SIZE);
+               cctx->data = malloc(asize);
+               if (!cctx->data)
+                       return -ENOMEM;
+
+               size = fread(cctx->data, 1, asize, fp);
+               if (size != asize) {
+                       fprintf(stderr,
+                               "ERR: SB LOAD command payload too short!\n");
+                       return -EINVAL;
+               }
+
+               *tsize += size;
+
+               EVP_DigestUpdate(&ictx->md_ctx, cctx->data, asize);
+               sb_aes_crypt(ictx, cctx->data, cctx->data, asize);
+
+               if (ccmd->load.crc32 != crc32(cctx->data, asize)) {
+                       fprintf(stderr,
+                               "ERR: SB LOAD command payload CRC32 invalid!\n");
+                       return -EINVAL;
+               }
+               return 0;
+       case ROM_FILL_CMD:
+               soprintf(ictx,
+                        " FILL addr=0x%08x length=0x%08x pattern=0x%08x # %s\n",
+                        ccmd->fill.address, ccmd->fill.count,
+                        ccmd->fill.pattern, csum);
+               return 0;
+       case ROM_JUMP_CMD:
+               if (ccmd->header.flags & ROM_JUMP_CMD_FLAG_HAB)
+                       flag = " HAB";
+               soprintf(ictx,
+                        " JUMP%s addr=0x%08x r0_arg=0x%08x # %s\n",
+                        flag, ccmd->fill.address, ccmd->jump.argument, csum);
+               return 0;
+       case ROM_CALL_CMD:
+               if (ccmd->header.flags & ROM_CALL_CMD_FLAG_HAB)
+                       flag = " HAB";
+               soprintf(ictx,
+                        " CALL%s addr=0x%08x r0_arg=0x%08x # %s\n",
+                        flag, ccmd->fill.address, ccmd->jump.argument, csum);
+               return 0;
+       case ROM_MODE_CMD:
+               for (i = 0; i < ARRAY_SIZE(modetable); i++) {
+                       if (ccmd->mode.mode == modetable[i].mode) {
+                               soprintf(ictx, " MODE %s # %s\n",
+                                        modetable[i].name, csum);
+                               break;
+                       }
+               }
+               fprintf(stderr, " MODE !INVALID! # %s\n", csum);
+               return 0;
+       }
+
+       return ret;
+}
+
+static int sb_verify_commands(struct sb_image_ctx *ictx,
+                             struct sb_section_ctx *sctx, FILE *fp)
+{
+       unsigned long size, tsize = 0;
+       struct sb_cmd_ctx *cctx;
+       int ret;
+
+       sb_aes_reinit(ictx, 0);
+
+       while (tsize < sctx->size) {
+               cctx = calloc(1, sizeof(*cctx));
+               if (!cctx)
+                       return -ENOMEM;
+               if (!sctx->cmd_head) {
+                       sctx->cmd_head = cctx;
+                       sctx->cmd_tail = cctx;
+               } else {
+                       sctx->cmd_tail->cmd = cctx;
+                       sctx->cmd_tail = cctx;
+               }
+
+               size = fread(&cctx->c_payload, 1, sizeof(cctx->c_payload), fp);
+               if (size != sizeof(cctx->c_payload)) {
+                       fprintf(stderr, "ERR: SB command header too short!\n");
+                       return -EINVAL;
+               }
+
+               tsize += size;
+
+               sb_decrypt_tag(ictx, cctx);
+
+               ret = sb_verify_command(ictx, cctx, fp, &tsize);
+               if (ret)
+                       return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int sb_verify_sections_cmds(struct sb_image_ctx *ictx, FILE *fp)
+{
+       struct sb_boot_image_header *hdr = &ictx->payload;
+       struct sb_sections_header *shdr;
+       unsigned int i;
+       int ret;
+       struct sb_section_ctx *sctx;
+       unsigned long size;
+       char *bootable = "";
+
+       soprintf(ictx, "----- Verifying  SB Sections and Commands -----\n");
+
+       for (i = 0; i < hdr->section_count; i++) {
+               sctx = calloc(1, sizeof(*sctx));
+               if (!sctx)
+                       return -ENOMEM;
+               if (!ictx->sect_head) {
+                       ictx->sect_head = sctx;
+                       ictx->sect_tail = sctx;
+               } else {
+                       ictx->sect_tail->sect = sctx;
+                       ictx->sect_tail = sctx;
+               }
+
+               size = fread(&sctx->payload, 1, sizeof(sctx->payload), fp);
+               if (size != sizeof(sctx->payload)) {
+                       fprintf(stderr, "ERR: SB section header too short!\n");
+                       return -EINVAL;
+               }
+       }
+
+       size = fread(&ictx->sb_dict_key, 1, sizeof(ictx->sb_dict_key), fp);
+       if (size != sizeof(ictx->sb_dict_key)) {
+               fprintf(stderr, "ERR: SB key dictionary too short!\n");
+               return -EINVAL;
+       }
+
+       sb_encrypt_sb_sections_header(ictx);
+       sb_aes_reinit(ictx, 0);
+       sb_decrypt_key_dictionary_key(ictx);
+
+       sb_aes_reinit(ictx, 0);
+
+       sctx = ictx->sect_head;
+       while (sctx) {
+               shdr = &sctx->payload;
+
+               if (shdr->section_flags & SB_SECTION_FLAG_BOOTABLE) {
+                       sctx->boot = 1;
+                       bootable = " BOOTABLE";
+               }
+
+               sctx->size = (shdr->section_size * SB_BLOCK_SIZE) +
+                            sizeof(struct sb_command);
+               soprintf(ictx, "SECTION 0x%x%s # size = %i bytes\n",
+                        shdr->section_number, bootable, sctx->size);
+
+               if (shdr->section_flags & ~SB_SECTION_FLAG_BOOTABLE)
+                       fprintf(stderr, " WARN: Unknown section flag(s) %08x\n",
+                               shdr->section_flags);
+
+               if ((shdr->section_flags & SB_SECTION_FLAG_BOOTABLE) &&
+                   (hdr->first_boot_section_id != shdr->section_number)) {
+                       fprintf(stderr,
+                               " WARN: Bootable section does ID not match image header ID!\n");
+               }
+
+               ret = sb_verify_commands(ictx, sctx, fp);
+               if (ret)
+                       return ret;
+
+               sctx = sctx->sect;
+       }
+
+       /*
+        * FIXME IDEA:
+        * check if the first TAG command is at sctx->section_offset
+        */
+       return 0;
+}
+
+static int sb_verify_image_end(struct sb_image_ctx *ictx,
+                              FILE *fp, off_t filesz)
+{
+       uint8_t digest[32];
+       unsigned long size;
+       off_t pos;
+       int ret;
+
+       soprintf(ictx, "------------- Verifying image end -------------\n");
+
+       size = fread(digest, 1, sizeof(digest), fp);
+       if (size != sizeof(digest)) {
+               fprintf(stderr, "ERR: SB key dictionary too short!\n");
+               return -EINVAL;
+       }
+
+       pos = ftell(fp);
+       if (pos != filesz) {
+               fprintf(stderr, "ERR: Trailing data past the image!\n");
+               return -EINVAL;
+       }
+
+       /* Check the image digest. */
+       EVP_DigestFinal(&ictx->md_ctx, ictx->digest, NULL);
+
+       /* Decrypt the image digest from the input image. */
+       sb_aes_reinit(ictx, 0);
+       sb_aes_crypt(ictx, digest, digest, sizeof(digest));
+
+       /* Check all of 20 bytes of the SHA1 hash. */
+       ret = memcmp(digest, ictx->digest, 20) ? -EINVAL : 0;
+
+       if (ret)
+               soprintf(ictx, "[FAIL] Full-image checksum:          BAD\n");
+       else
+               soprintf(ictx, "[PASS] Full-image checksum:          OK\n");
+
+       return ret;
+}
+
+
+static int sb_build_tree_from_img(struct sb_image_ctx *ictx)
+{
+       long filesize;
+       int ret;
+       FILE *fp;
+
+       if (!ictx->input_filename) {
+               fprintf(stderr, "ERR: Missing filename!\n");
+               return -EINVAL;
+       }
+
+       fp = fopen(ictx->input_filename, "r");
+       if (!fp)
+               goto err_open;
+
+       ret = fseek(fp, 0, SEEK_END);
+       if (ret < 0)
+               goto err_file;
+
+       filesize = ftell(fp);
+       if (filesize < 0)
+               goto err_file;
+
+       ret = fseek(fp, 0, SEEK_SET);
+       if (ret < 0)
+               goto err_file;
+
+       if (filesize < (signed)sizeof(ictx->payload)) {
+               fprintf(stderr, "ERR: File too short!\n");
+               goto err_file;
+       }
+
+       if (filesize & (SB_BLOCK_SIZE - 1)) {
+               fprintf(stderr, "ERR: The file is not aligned!\n");
+               goto err_file;
+       }
+
+       /* Load and verify image header */
+       ret = sb_verify_image_header(ictx, fp, filesize);
+       if (ret)
+               goto err_verify;
+
+       /* Load and verify sections and commands */
+       ret = sb_verify_sections_cmds(ictx, fp);
+       if (ret)
+               goto err_verify;
+
+       ret = sb_verify_image_end(ictx, fp, filesize);
+       if (ret)
+               goto err_verify;
+
+       ret = 0;
+
+err_verify:
+       soprintf(ictx, "-------------------- Result -------------------\n");
+       soprintf(ictx, "Verification %s\n", ret ? "FAILED" : "PASSED");
+
+       /* Stop the encryption session. */
+       sb_aes_deinit(&ictx->cipher_ctx);
+
+       fclose(fp);
+       return ret;
+
+err_file:
+       fclose(fp);
+err_open:
+       fprintf(stderr, "ERR: Failed to load file \"%s\"\n",
+               ictx->input_filename);
+       return -EINVAL;
+}
+
+static void sb_free_image(struct sb_image_ctx *ictx)
+{
+       struct sb_section_ctx *sctx = ictx->sect_head, *s_head;
+       struct sb_dcd_ctx *dctx = ictx->dcd_head, *d_head;
+       struct sb_cmd_ctx *cctx, *c_head;
+
+       while (sctx) {
+               s_head = sctx;
+               c_head = sctx->cmd_head;
+
+               while (c_head) {
+                       cctx = c_head;
+                       c_head = c_head->cmd;
+                       if (cctx->data)
+                               free(cctx->data);
+                       free(cctx);
+               }
+
+               sctx = sctx->sect;
+               free(s_head);
+       }
+
+       while (dctx) {
+               d_head = dctx;
+               dctx = dctx->dcd;
+               free(d_head->payload);
+               free(d_head);
+       }
+}
+
+/*
+ * MXSSB-MKIMAGE glue code.
+ */
+static int mxsimage_check_image_types(uint8_t type)
+{
+       if (type == IH_TYPE_MXSIMAGE)
+               return EXIT_SUCCESS;
+       else
+               return EXIT_FAILURE;
+}
+
+static void mxsimage_set_header(void *ptr, struct stat *sbuf, int ifd,
+                               struct mkimage_params *params)
+{
+}
+
+int mxsimage_check_params(struct mkimage_params *params)
+{
+       if (!params)
+               return -1;
+       if (!strlen(params->imagename)) {
+               fprintf(stderr,
+                       "Error: %s - Configuration file not specified, it is needed for mxsimage generation\n",
+                       params->cmdname);
+               return -1;
+       }
+
+       /*
+        * Check parameters:
+        * XIP is not allowed and verify that incompatible
+        * parameters are not sent at the same time
+        * For example, if list is required a data image must not be provided
+        */
+       return  (params->dflag && (params->fflag || params->lflag)) ||
+               (params->fflag && (params->dflag || params->lflag)) ||
+               (params->lflag && (params->dflag || params->fflag)) ||
+               (params->xflag) || !(strlen(params->imagename));
+}
+
+static int mxsimage_verify_print_header(char *file, int silent)
+{
+       int ret;
+       struct sb_image_ctx ctx;
+
+       memset(&ctx, 0, sizeof(ctx));
+
+       ctx.input_filename = file;
+       ctx.silent_dump = silent;
+
+       ret = sb_build_tree_from_img(&ctx);
+       sb_free_image(&ctx);
+
+       return ret;
+}
+
+char *imagefile;
+static int mxsimage_verify_header(unsigned char *ptr, int image_size,
+                       struct mkimage_params *params)
+{
+       struct sb_boot_image_header *hdr;
+
+       if (!ptr)
+               return -EINVAL;
+
+       hdr = (struct sb_boot_image_header *)ptr;
+
+       /*
+        * Check if the header contains the MXS image signatures,
+        * if so, do a full-image verification.
+        */
+       if (memcmp(hdr->signature1, "STMP", 4) ||
+           memcmp(hdr->signature2, "sgtl", 4))
+               return -EINVAL;
+
+       imagefile = params->imagefile;
+
+       return mxsimage_verify_print_header(params->imagefile, 1);
+}
+
+static void mxsimage_print_header(const void *hdr)
+{
+       if (imagefile)
+               mxsimage_verify_print_header(imagefile, 0);
+}
+
+static int sb_build_image(struct sb_image_ctx *ictx,
+                         struct image_type_params *tparams)
+{
+       struct sb_boot_image_header *sb_header = &ictx->payload;
+       struct sb_section_ctx *sctx;
+       struct sb_cmd_ctx *cctx;
+       struct sb_command *ccmd;
+       struct sb_key_dictionary_key *sb_dict_key = &ictx->sb_dict_key;
+
+       uint8_t *image, *iptr;
+
+       /* Calculate image size. */
+       uint32_t size = sizeof(*sb_header) +
+               ictx->sect_count * sizeof(struct sb_sections_header) +
+               sizeof(*sb_dict_key) + sizeof(ictx->digest);
+
+       sctx = ictx->sect_head;
+       while (sctx) {
+               size += sctx->size;
+               sctx = sctx->sect;
+       };
+
+       image = malloc(size);
+       if (!image)
+               return -ENOMEM;
+       iptr = image;
+
+       memcpy(iptr, sb_header, sizeof(*sb_header));
+       iptr += sizeof(*sb_header);
+
+       sctx = ictx->sect_head;
+       while (sctx) {
+               memcpy(iptr, &sctx->payload, sizeof(struct sb_sections_header));
+               iptr += sizeof(struct sb_sections_header);
+               sctx = sctx->sect;
+       };
+
+       memcpy(iptr, sb_dict_key, sizeof(*sb_dict_key));
+       iptr += sizeof(*sb_dict_key);
+
+       sctx = ictx->sect_head;
+       while (sctx) {
+               cctx = sctx->cmd_head;
+               while (cctx) {
+                       ccmd = &cctx->payload;
+
+                       memcpy(iptr, &cctx->c_payload, sizeof(cctx->payload));
+                       iptr += sizeof(cctx->payload);
+
+                       if (ccmd->header.tag == ROM_LOAD_CMD) {
+                               memcpy(iptr, cctx->data, cctx->length);
+                               iptr += cctx->length;
+                       }
+
+                       cctx = cctx->cmd;
+               }
+
+               sctx = sctx->sect;
+       };
+
+       memcpy(iptr, ictx->digest, sizeof(ictx->digest));
+       iptr += sizeof(ictx->digest);
+
+       /* Configure the mkimage */
+       tparams->hdr = image;
+       tparams->header_size = size;
+
+       return 0;
+}
+
+static int mxsimage_generate(struct mkimage_params *params,
+       struct image_type_params *tparams)
+{
+       int ret;
+       struct sb_image_ctx ctx;
+
+       /* Do not copy the U-Boot image! */
+       params->skipcpy = 1;
+
+       memset(&ctx, 0, sizeof(ctx));
+
+       ctx.cfg_filename = params->imagename;
+       ctx.output_filename = params->imagefile;
+       ctx.verbose_boot = 1;
+
+       ret = sb_build_tree_from_cfg(&ctx);
+       if (ret)
+               goto fail;
+
+       ret = sb_encrypt_image(&ctx);
+       if (!ret)
+               ret = sb_build_image(&ctx, tparams);
+
+fail:
+       sb_free_image(&ctx);
+
+       return ret;
+}
+
+/*
+ * mxsimage parameters
+ */
+static struct image_type_params mxsimage_params = {
+       .name           = "Freescale MXS Boot Image support",
+       .header_size    = 0,
+       .hdr            = NULL,
+       .check_image_type = mxsimage_check_image_types,
+       .verify_header  = mxsimage_verify_header,
+       .print_header   = mxsimage_print_header,
+       .set_header     = mxsimage_set_header,
+       .check_params   = mxsimage_check_params,
+       .vrec_header    = mxsimage_generate,
+};
+
+void init_mxs_image_type(void)
+{
+       mkimage_register(&mxsimage_params);
+}
+
+#else
+void init_mxs_image_type(void)
+{
+}
+#endif
diff --git a/tools/mxsimage.h b/tools/mxsimage.h
new file mode 100644 (file)
index 0000000..6cd59d2
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ * Freescale i.MX28 SB image generator
+ *
+ * Copyright (C) 2012 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#ifndef __MXSSB_H__
+#define __MXSSB_H__
+
+#include <stdint.h>
+#include <arpa/inet.h>
+
+#define SB_BLOCK_SIZE          16
+
+#define roundup(x, y)          ((((x) + ((y) - 1)) / (y)) * (y))
+#define ARRAY_SIZE(x)          (sizeof(x) / sizeof((x)[0]))
+
+struct sb_boot_image_version {
+       uint16_t        major;
+       uint16_t        pad0;
+       uint16_t        minor;
+       uint16_t        pad1;
+       uint16_t        revision;
+       uint16_t        pad2;
+};
+
+struct sb_boot_image_header {
+       union {
+               /* SHA1 of the header. */
+               uint8_t digest[20];
+               struct {
+                       /* CBC-MAC initialization vector. */
+                       uint8_t iv[16];
+                       uint8_t extra[4];
+               };
+       };
+       /* 'STMP' */
+       uint8_t         signature1[4];
+       /* Major version of the image format. */
+       uint8_t         major_version;
+       /* Minor version of the image format. */
+       uint8_t         minor_version;
+       /* Flags associated with the image. */
+       uint16_t        flags;
+       /* Size of the image in 16b blocks. */
+       uint32_t        image_blocks;
+       /* Offset of the first tag in 16b blocks. */
+       uint32_t        first_boot_tag_block;
+       /* ID of the section to boot from. */
+       uint32_t        first_boot_section_id;
+       /* Amount of crypto keys. */
+       uint16_t        key_count;
+       /* Offset to the key dictionary in 16b blocks. */
+       uint16_t        key_dictionary_block;
+       /* Size of this header in 16b blocks. */
+       uint16_t        header_blocks;
+       /* Amount of section headers. */
+       uint16_t        section_count;
+       /* Section header size in 16b blocks. */
+       uint16_t        section_header_size;
+       /* Padding to align timestamp to uint64_t. */
+       uint8_t         padding0[2];
+       /* 'sgtl' (since v1.1) */
+       uint8_t         signature2[4];
+       /* Image generation date, in microseconds since 1.1.2000 . */
+       uint64_t        timestamp_us;
+       /* Product version. */
+       struct sb_boot_image_version
+                       product_version;
+       /* Component version. */
+       struct sb_boot_image_version
+                       component_version;
+       /* Drive tag for the system drive. (since v1.1) */
+       uint16_t        drive_tag;
+       /* Padding. */
+       uint8_t         padding1[6];
+};
+
+#define        SB_VERSION_MAJOR        1
+#define        SB_VERSION_MINOR        1
+
+/* Enable to HTLLC verbose boot report. */
+#define SB_IMAGE_FLAG_VERBOSE  (1 << 0)
+
+struct sb_key_dictionary_key {
+       /* The CBC-MAC of image and sections header. */
+       uint8_t         cbc_mac[SB_BLOCK_SIZE];
+       /* The AES key encrypted by image key (zero). */
+       uint8_t         key[SB_BLOCK_SIZE];
+};
+
+struct sb_ivt_header {
+       uint32_t        header;
+       uint32_t        entry;
+       uint32_t        reserved1;
+       uint32_t        dcd;
+       uint32_t        boot_data;
+       uint32_t        self;
+       uint32_t        csf;
+       uint32_t        reserved2;
+};
+
+#define        SB_HAB_IVT_TAG                  0xd1UL
+#define        SB_HAB_DCD_TAG                  0xd2UL
+
+#define        SB_HAB_VERSION                  0x40UL
+
+/*
+ * The "size" field in the IVT header is not naturally aligned,
+ * use this macro to fill first 4 bytes of the IVT header without
+ * causing issues on some systems (esp. M68k, PPC, MIPS-BE, ARM-BE).
+ */
+static inline uint32_t sb_hab_ivt_header(void)
+{
+       uint32_t ret = 0;
+       ret |= SB_HAB_IVT_TAG << 24;
+       ret |= sizeof(struct sb_ivt_header) << 16;
+       ret |= SB_HAB_VERSION;
+       return htonl(ret);
+}
+
+struct sb_sections_header {
+       /* Section number. */
+       uint32_t        section_number;
+       /* Offset of this sections first instruction after "TAG". */
+       uint32_t        section_offset;
+       /* Size of the section in 16b blocks. */
+       uint32_t        section_size;
+       /* Section flags. */
+       uint32_t        section_flags;
+};
+
+#define        SB_SECTION_FLAG_BOOTABLE        (1 << 0)
+
+struct sb_command {
+       struct {
+               uint8_t         checksum;
+               uint8_t         tag;
+               uint16_t        flags;
+#define ROM_TAG_CMD_FLAG_ROM_LAST_TAG  0x1
+#define ROM_LOAD_CMD_FLAG_DCD_LOAD     0x1     /* MX28 only */
+#define ROM_JUMP_CMD_FLAG_HAB          0x1     /* MX28 only */
+#define ROM_CALL_CMD_FLAG_HAB          0x1     /* MX28 only */
+       } header;
+
+       union {
+       struct {
+               uint32_t        reserved[3];
+       } nop;
+       struct {
+               uint32_t        section_number;
+               uint32_t        section_length;
+               uint32_t        section_flags;
+       } tag;
+       struct {
+               uint32_t        address;
+               uint32_t        count;
+               uint32_t        crc32;
+       } load;
+       struct {
+               uint32_t        address;
+               uint32_t        count;
+               uint32_t        pattern;
+       } fill;
+       struct {
+               uint32_t        address;
+               uint32_t        reserved;
+               /* Passed in register r0 before JUMP */
+               uint32_t        argument;
+       } jump;
+       struct {
+               uint32_t        address;
+               uint32_t        reserved;
+               /* Passed in register r0 before CALL */
+               uint32_t        argument;
+       } call;
+       struct {
+               uint32_t        reserved1;
+               uint32_t        reserved2;
+               uint32_t        mode;
+       } mode;
+
+       };
+};
+
+/*
+ * Most of the mode names are same or at least similar
+ * on i.MX23 and i.MX28, but some of the mode names
+ * differ. The "name" field represents the mode name
+ * on i.MX28 as seen in Table 12-2 of the datasheet.
+ * The "altname" field represents the differently named
+ * fields on i.MX23 as seen in Table 35-3 of the
+ * datasheet.
+ */
+static const struct {
+       const char      *name;
+       const char      *altname;
+       const uint8_t   mode;
+} modetable[] = {
+       { "USB",                NULL,           0x00 },
+       { "I2C",                NULL,           0x01 },
+       { "SPI2_FLASH",         "SPI1_FLASH",   0x02 },
+       { "SPI3_FLASH",         "SPI2_FLASH",   0x03 },
+       { "NAND_BCH",           NULL,           0x04 },
+       { "JTAG",               NULL,           0x06 },
+       { "SPI3_EEPROM",        "SPI2_EEPROM",  0x08 },
+       { "SD_SSP0",            NULL,           0x09 },
+       { "SD_SSP1",            NULL,           0x0A }
+};
+
+enum sb_tag {
+       ROM_NOP_CMD     = 0x00,
+       ROM_TAG_CMD     = 0x01,
+       ROM_LOAD_CMD    = 0x02,
+       ROM_FILL_CMD    = 0x03,
+       ROM_JUMP_CMD    = 0x04,
+       ROM_CALL_CMD    = 0x05,
+       ROM_MODE_CMD    = 0x06
+};
+
+struct sb_source_entry {
+       uint8_t         tag;
+       uint32_t        address;
+       uint32_t        flags;
+       char            *filename;
+};
+
+#endif /* __MXSSB_H__ */