summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--arch/arm/config.mk4
-rw-r--r--arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg8
-rw-r--r--arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg8
-rw-r--r--arch/arm/cpu/arm926ejs/mxs/spl_boot.c35
-rw-r--r--arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds2
-rw-r--r--arch/arm/dts/Makefile1
-rw-r--r--arch/arm/dts/imx6q-sabreauto.dts13
-rw-r--r--arch/arm/imx-common/Makefile8
-rw-r--r--board/denx/m53evk/m53evk.c31
-rw-r--r--board/freescale/mx53loco/mx53loco.c31
-rw-r--r--board/freescale/mx6sabresd/mx6sabresd.c11
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/mxs_ocotp.c311
-rw-r--r--drivers/pci/pcie_imx.c13
-rw-r--r--include/configs/m53evk.h8
-rw-r--r--include/configs/mx53loco.h10
-rw-r--r--include/configs/mx6qsabreauto.h3
-rw-r--r--include/configs/mx6sabresd.h10
-rw-r--r--include/configs/mxs.h15
-rw-r--r--include/configs/nitrogen6x.h1
-rw-r--r--include/configs/woodburn_sd.h2
22 files changed, 492 insertions, 40 deletions
diff --git a/Makefile b/Makefile
index 538c3bf..7865cb9 100644
--- a/Makefile
+++ b/Makefile
@@ -749,6 +749,9 @@ dtbs dts/dt.dtb: checkdtc u-boot
u-boot-dtb.bin: u-boot.bin dts/dt.dtb FORCE
$(call if_changed,cat)
+%.imx: %.bin
+ $(Q)$(MAKE) $(build)=arch/arm/imx-common $@
+
quiet_cmd_copy = COPY $@
cmd_copy = cp $< $@
@@ -802,9 +805,6 @@ MKIMAGEFLAGS_u-boot.pbl = -n $(srctree)/$(CONFIG_SYS_FSL_PBL_RCW:"%"=%) \
u-boot.img u-boot.kwb u-boot.pbl: u-boot.bin FORCE
$(call if_changed,mkimage)
-u-boot.imx: u-boot.bin
- $(Q)$(MAKE) $(build)=arch/arm/imx-common $@
-
u-boot.sha1: u-boot.bin
tools/ubsha1 u-boot.bin
diff --git a/arch/arm/config.mk b/arch/arm/config.mk
index f4c2d81..4502fd9 100644
--- a/arch/arm/config.mk
+++ b/arch/arm/config.mk
@@ -126,6 +126,10 @@ ifndef CONFIG_SPL_BUILD
ALL-y += SPL
endif
else
+ifeq ($(CONFIG_OF_SEPARATE),y)
+ALL-y += u-boot-dtb.imx
+else
ALL-y += u-boot.imx
endif
endif
+endif
diff --git a/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg b/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg
index 8118767..55510e9 100644
--- a/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg
+++ b/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg
@@ -1,6 +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
+ LOAD 0x1000 spl/u-boot-spl.bin
+ CALL 0x1000 0x0
+ LOAD 0x40002000 u-boot.bin
+ CALL 0x40002000 0x0
diff --git a/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg b/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg
index ea772f0..bb78cb0 100644
--- a/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg
+++ b/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg
@@ -1,8 +1,8 @@
SECTION 0x0 BOOTABLE
TAG LAST
- LOAD 0x0 spl/u-boot-spl.bin
- LOAD IVT 0x8000 0x14
+ LOAD 0x1000 spl/u-boot-spl.bin
+ LOAD IVT 0x8000 0x1000
CALL HAB 0x8000 0x0
- LOAD 0x40000100 u-boot.bin
- LOAD IVT 0x8000 0x40000100
+ LOAD 0x40002000 u-boot.bin
+ LOAD IVT 0x8000 0x40002000
CALL HAB 0x8000 0x0
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
index 68c30af..d3e1369 100644
--- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
+++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c
@@ -13,9 +13,16 @@
#include <asm/arch/imx-regs.h>
#include <asm/arch/sys_proto.h>
#include <asm/gpio.h>
+#include <linux/compiler.h>
#include "mxs_init.h"
+DECLARE_GLOBAL_DATA_PTR;
+static gd_t gdata __section(".data");
+#ifdef CONFIG_SPL_SERIAL_SUPPORT
+static bd_t bdata __section(".data");
+#endif
+
/*
* This delay function is intended to be used only in early stage of boot, where
* clock are not set up yet. The timer used here is reset on every boot and
@@ -102,6 +109,28 @@ static uint8_t mxs_get_bootmode_index(void)
return i;
}
+static void mxs_spl_fixup_vectors(void)
+{
+ /*
+ * Copy our vector table to 0x0, since due to HAB, we cannot
+ * be loaded to 0x0. We want to have working vectoring though,
+ * thus this fixup. Our vectoring table is PIC, so copying is
+ * fine.
+ */
+ extern uint32_t _start;
+ memcpy(0x0, &_start, 0x60);
+}
+
+static void mxs_spl_console_init(void)
+{
+#ifdef CONFIG_SPL_SERIAL_SUPPORT
+ gd->bd = &bdata;
+ gd->baudrate = CONFIG_BAUDRATE;
+ serial_init();
+ gd->have_console = 1;
+#endif
+}
+
void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr,
const iomux_cfg_t *iomux_setup,
const unsigned int iomux_size)
@@ -109,8 +138,14 @@ void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr,
struct mxs_spl_data *data = (struct mxs_spl_data *)
((CONFIG_SYS_TEXT_BASE - sizeof(struct mxs_spl_data)) & ~0xf);
uint8_t bootmode = mxs_get_bootmode_index();
+ gd = &gdata;
+
+ mxs_spl_fixup_vectors();
mxs_iomux_setup_multiple_pads(iomux_setup, iomux_size);
+
+ mxs_spl_console_init();
+
mxs_power_init();
mxs_mem_init();
diff --git a/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds b/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds
index d0b482d..f4bf8ac 100644
--- a/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds
+++ b/arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds
@@ -16,7 +16,7 @@ OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
- . = 0x00000000;
+ . = CONFIG_SPL_TEXT_BASE;
. = ALIGN(4);
.text :
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 631a9be..2c3c773 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -7,6 +7,7 @@ dtb-$(CONFIG_EXYNOS5) += exynos5250-arndale.dtb \
exynos5250-snow.dtb \
exynos5250-smdk5250.dtb \
exynos5420-smdk5420.dtb
+dtb-$(CONFIG_MX6) += imx6q-sabreauto.dtb
dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
tegra20-medcom-wide.dtb \
tegra20-paz00.dtb \
diff --git a/arch/arm/dts/imx6q-sabreauto.dts b/arch/arm/dts/imx6q-sabreauto.dts
new file mode 100644
index 0000000..a3c9c91
--- /dev/null
+++ b/arch/arm/dts/imx6q-sabreauto.dts
@@ -0,0 +1,13 @@
+/*
+ + * Copyright 2012 Freescale Semiconductor, Inc.
+ + * Copyright 2011 Linaro Ltd.
+ + *
+ + * SPDX-License-Identifier: GPL-2.0+
+ + */
+
+/dts-v1/;
+
+/ {
+ model = "Freescale i.MX6 Quad SABRE Automotive Board";
+ compatible = "fsl,imx6q-sabreauto", "fsl,imx6q";
+};
diff --git a/arch/arm/imx-common/Makefile b/arch/arm/imx-common/Makefile
index 16809fe..025cfed 100644
--- a/arch/arm/imx-common/Makefile
+++ b/arch/arm/imx-common/Makefile
@@ -42,6 +42,14 @@ MKIMAGEFLAGS_u-boot.imx = -n $(filter-out $< $(PHONY),$^) -T imximage \
u-boot.imx: u-boot.bin $(IMX_CONFIG) FORCE
$(call if_changed,mkimage)
+ifeq ($(CONFIG_OF_SEPARATE),y)
+MKIMAGEFLAGS_u-boot-dtb.imx = -n $(filter-out $< $(PHONY),$^) -T imximage \
+ -e $(CONFIG_SYS_TEXT_BASE)
+
+u-boot-dtb.imx: u-boot-dtb.bin $(IMX_CONFIG) FORCE
+ $(call if_changed,mkimage)
+endif
+
MKIMAGEFLAGS_SPL = -n $(filter-out $< $(PHONY),$^) -T imximage \
-e $(CONFIG_SPL_TEXT_BASE)
diff --git a/board/denx/m53evk/m53evk.c b/board/denx/m53evk/m53evk.c
index 0f71a16..74f9501 100644
--- a/board/denx/m53evk/m53evk.c
+++ b/board/denx/m53evk/m53evk.c
@@ -31,24 +31,41 @@
DECLARE_GLOBAL_DATA_PTR;
-int dram_init(void)
+static uint32_t mx53_dram_size[2];
+
+phys_size_t get_effective_memsize(void)
{
- u32 size1, size2;
+ /*
+ * WARNING: We must override get_effective_memsize() function here
+ * to report only the size of the first DRAM bank. This is to make
+ * U-Boot relocator place U-Boot into valid memory, that is, at the
+ * end of the first DRAM bank. If we did not override this function
+ * like so, U-Boot would be placed at the address of the first DRAM
+ * bank + total DRAM size - sizeof(uboot), which in the setup where
+ * each DRAM bank contains 512MiB of DRAM would result in placing
+ * U-Boot into invalid memory area close to the end of the first
+ * DRAM bank.
+ */
+ return mx53_dram_size[0];
+}
- size1 = get_ram_size((void *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
- size2 = get_ram_size((void *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE);
+int dram_init(void)
+{
+ mx53_dram_size[0] = get_ram_size((void *)PHYS_SDRAM_1, 1 << 30);
+ mx53_dram_size[1] = get_ram_size((void *)PHYS_SDRAM_2, 1 << 30);
- gd->ram_size = size1 + size2;
+ gd->ram_size = mx53_dram_size[0] + mx53_dram_size[1];
return 0;
}
+
void dram_init_banksize(void)
{
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
- gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+ gd->bd->bi_dram[0].size = mx53_dram_size[0];
gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
- gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+ gd->bd->bi_dram[1].size = mx53_dram_size[1];
}
static void setup_iomux_uart(void)
diff --git a/board/freescale/mx53loco/mx53loco.c b/board/freescale/mx53loco/mx53loco.c
index 08dd66f..b32a97f 100644
--- a/board/freescale/mx53loco/mx53loco.c
+++ b/board/freescale/mx53loco/mx53loco.c
@@ -30,24 +30,41 @@
DECLARE_GLOBAL_DATA_PTR;
-int dram_init(void)
+static uint32_t mx53_dram_size[2];
+
+phys_size_t get_effective_memsize(void)
{
- u32 size1, size2;
+ /*
+ * WARNING: We must override get_effective_memsize() function here
+ * to report only the size of the first DRAM bank. This is to make
+ * U-Boot relocator place U-Boot into valid memory, that is, at the
+ * end of the first DRAM bank. If we did not override this function
+ * like so, U-Boot would be placed at the address of the first DRAM
+ * bank + total DRAM size - sizeof(uboot), which in the setup where
+ * each DRAM bank contains 512MiB of DRAM would result in placing
+ * U-Boot into invalid memory area close to the end of the first
+ * DRAM bank.
+ */
+ return mx53_dram_size[0];
+}
- size1 = get_ram_size((void *)PHYS_SDRAM_1, PHYS_SDRAM_1_SIZE);
- size2 = get_ram_size((void *)PHYS_SDRAM_2, PHYS_SDRAM_2_SIZE);
+int dram_init(void)
+{
+ mx53_dram_size[0] = get_ram_size((void *)PHYS_SDRAM_1, 1 << 30);
+ mx53_dram_size[1] = get_ram_size((void *)PHYS_SDRAM_2, 1 << 30);
- gd->ram_size = size1 + size2;
+ gd->ram_size = mx53_dram_size[0] + mx53_dram_size[1];
return 0;
}
+
void dram_init_banksize(void)
{
gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
- gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+ gd->bd->bi_dram[0].size = mx53_dram_size[0];
gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
- gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE;
+ gd->bd->bi_dram[1].size = mx53_dram_size[1];
}
u32 get_board_rev(void)
diff --git a/board/freescale/mx6sabresd/mx6sabresd.c b/board/freescale/mx6sabresd/mx6sabresd.c
index 12d8c56..d7d932e 100644
--- a/board/freescale/mx6sabresd/mx6sabresd.c
+++ b/board/freescale/mx6sabresd/mx6sabresd.c
@@ -135,6 +135,16 @@ static void setup_spi(void)
imx_iomux_v3_setup_multiple_pads(ecspi1_pads, ARRAY_SIZE(ecspi1_pads));
}
+iomux_v3_cfg_t const pcie_pads[] = {
+ MX6_PAD_EIM_D19__GPIO3_IO19 | MUX_PAD_CTRL(NO_PAD_CTRL), /* POWER */
+ MX6_PAD_GPIO_17__GPIO7_IO12 | MUX_PAD_CTRL(NO_PAD_CTRL), /* RESET */
+};
+
+static void setup_pcie(void)
+{
+ imx_iomux_v3_setup_multiple_pads(pcie_pads, ARRAY_SIZE(pcie_pads));
+}
+
iomux_v3_cfg_t const di0_pads[] = {
MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK, /* DISP0_CLK */
MX6_PAD_DI0_PIN2__IPU1_DI0_PIN02, /* DISP0_HSYNC */
@@ -454,6 +464,7 @@ int overwrite_console(void)
int board_eth_init(bd_t *bis)
{
setup_iomux_enet();
+ setup_pcie();
return cpu_eth_init(bis);
}
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index c25e92d..2f2e48f 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_FSL_IIM) += fsl_iim.o
obj-$(CONFIG_GPIO_LED) += gpio_led.o
obj-$(CONFIG_FSL_MC9SDZ60) += mc9sdz60.o
obj-$(CONFIG_MXC_OCOTP) += mxc_ocotp.o
+obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o
obj-$(CONFIG_NS87308) += ns87308.o
obj-$(CONFIG_PDSP188x) += pdsp188x.o
obj-$(CONFIG_STATUS_LED) += status_led.o
diff --git a/drivers/misc/mxs_ocotp.c b/drivers/misc/mxs_ocotp.c
new file mode 100644
index 0000000..545d3eb
--- /dev/null
+++ b/drivers/misc/mxs_ocotp.c
@@ -0,0 +1,311 @@
+/*
+ * Freescale i.MX28 OCOTP Driver
+ *
+ * Copyright (C) 2014 Marek Vasut <marex@denx.de>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ *
+ * Note: The i.MX23/i.MX28 OCOTP block is a predecessor to the OCOTP block
+ * used in i.MX6 . While these blocks are very similar at the first
+ * glance, by digging deeper, one will notice differences (like the
+ * tight dependence on MXS power block, some completely new registers
+ * etc.) which would make common driver an ifdef nightmare :-(
+ */
+
+#include <common.h>
+#include <fuse.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/sys_proto.h>
+
+#define MXS_OCOTP_TIMEOUT 100000
+
+static struct mxs_ocotp_regs *ocotp_regs =
+ (struct mxs_ocotp_regs *)MXS_OCOTP_BASE;
+static struct mxs_power_regs *power_regs =
+ (struct mxs_power_regs *)MXS_POWER_BASE;
+static struct mxs_clkctrl_regs *clkctrl_regs =
+ (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE;
+
+static int mxs_ocotp_wait_busy_clear(void)
+{
+ uint32_t reg;
+ int timeout = MXS_OCOTP_TIMEOUT;
+
+ while (--timeout) {
+ reg = readl(&ocotp_regs->hw_ocotp_ctrl);
+ if (!(reg & OCOTP_CTRL_BUSY))
+ break;
+ udelay(10);
+ }
+
+ if (!timeout)
+ return -EINVAL;
+
+ /* Wait a little as per FSL datasheet's 'write postamble' section. */
+ udelay(10);
+
+ return 0;
+}
+
+static void mxs_ocotp_clear_error(void)
+{
+ writel(OCOTP_CTRL_ERROR, &ocotp_regs->hw_ocotp_ctrl_clr);
+}
+
+static int mxs_ocotp_read_bank_open(bool open)
+{
+ int ret = 0;
+
+ if (open) {
+ writel(OCOTP_CTRL_RD_BANK_OPEN,
+ &ocotp_regs->hw_ocotp_ctrl_set);
+
+ /*
+ * Wait before polling the BUSY bit, since the BUSY bit might
+ * be asserted only after a few HCLK cycles and if we were to
+ * poll immediatelly, we could miss the busy bit.
+ */
+ udelay(10);
+ ret = mxs_ocotp_wait_busy_clear();
+ } else {
+ writel(OCOTP_CTRL_RD_BANK_OPEN,
+ &ocotp_regs->hw_ocotp_ctrl_clr);
+ }
+
+ return ret;
+}
+
+static void mxs_ocotp_scale_vddio(bool enter, uint32_t *val)
+{
+ uint32_t scale_val;
+
+ if (enter) {
+ /*
+ * Enter the fuse programming VDDIO voltage setup. We start
+ * scaling the voltage from it's current value down to 2.8V
+ * which is the one and only correct voltage for programming
+ * the OCOTP fuses (according to datasheet).
+ */
+ scale_val = readl(&power_regs->hw_power_vddioctrl);
+ scale_val &= POWER_VDDIOCTRL_TRG_MASK;
+
+ /* Return the original voltage. */
+ *val = scale_val;
+
+ /*
+ * Start scaling VDDIO down to 0x2, which is 2.8V . Actually,
+ * the value 0x0 should be 2.8V, but that's not the case on
+ * most designs due to load etc., so we play safe. Undervolt
+ * can actually cause incorrect programming of the fuses and
+ * or reboots of the board.
+ */
+ while (scale_val > 2) {
+ clrsetbits_le32(&power_regs->hw_power_vddioctrl,
+ POWER_VDDIOCTRL_TRG_MASK, --scale_val);
+ udelay(500);
+ }
+ } else {
+ /* Start scaling VDDIO up to original value . */
+ for (scale_val = 2; scale_val <= *val; scale_val++) {
+ clrsetbits_le32(&power_regs->hw_power_vddioctrl,
+ POWER_VDDIOCTRL_TRG_MASK, scale_val);
+ udelay(500);
+ }
+ }
+
+ mdelay(10);
+}
+
+static int mxs_ocotp_wait_hclk_ready(void)
+{
+ uint32_t reg, timeout = MXS_OCOTP_TIMEOUT;
+
+ while (--timeout) {
+ reg = readl(&clkctrl_regs->hw_clkctrl_hbus);
+ if (!(reg & CLKCTRL_HBUS_ASM_BUSY))
+ break;
+ }
+
+ if (!timeout)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int mxs_ocotp_scale_hclk(bool enter, uint32_t *val)
+{
+ uint32_t scale_val;
+ int ret;
+
+ ret = mxs_ocotp_wait_hclk_ready();
+ if (ret)
+ return ret;
+
+ /* Set CPU bypass */
+ writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
+ &clkctrl_regs->hw_clkctrl_clkseq_set);
+
+ if (enter) {
+ /* Return the original HCLK clock speed. */
+ *val = readl(&clkctrl_regs->hw_clkctrl_hbus);
+ *val &= CLKCTRL_HBUS_DIV_MASK;
+
+ /* Scale the HCLK to 454/19 = 23.9 MHz . */
+ scale_val = (~19) << CLKCTRL_HBUS_DIV_OFFSET;
+ scale_val &= CLKCTRL_HBUS_DIV_MASK;
+ } else {
+ /* Scale the HCLK back to original frequency. */
+ scale_val = (~(*val)) << CLKCTRL_HBUS_DIV_OFFSET;
+ scale_val &= CLKCTRL_HBUS_DIV_MASK;
+ }
+
+ writel(CLKCTRL_HBUS_DIV_MASK,
+ &clkctrl_regs->hw_clkctrl_hbus_set);
+ writel(scale_val,
+ &clkctrl_regs->hw_clkctrl_hbus_clr);
+
+ mdelay(10);
+
+ ret = mxs_ocotp_wait_hclk_ready();
+ if (ret)
+ return ret;
+
+ /* Disable CPU bypass */
+ writel(CLKCTRL_CLKSEQ_BYPASS_CPU,
+ &clkctrl_regs->hw_clkctrl_clkseq_clr);
+
+ mdelay(10);
+
+ return 0;
+}
+
+static int mxs_ocotp_write_fuse(uint32_t addr, uint32_t mask)
+{
+ uint32_t hclk_val, vddio_val;
+ int ret;
+
+ /* Make sure the banks are closed for reading. */
+ ret = mxs_ocotp_read_bank_open(0);
+ if (ret) {
+ puts("Failed closing banks for reading!\n");
+ return ret;
+ }
+
+ ret = mxs_ocotp_scale_hclk(1, &hclk_val);
+ if (ret) {
+ puts("Failed scaling down the HCLK!\n");
+ return ret;
+ }
+ mxs_ocotp_scale_vddio(1, &vddio_val);
+
+ ret = mxs_ocotp_wait_busy_clear();
+ if (ret) {
+ puts("Failed waiting for ready state!\n");
+ goto fail;
+ }
+
+ /* Program the fuse address */
+ writel(addr | OCOTP_CTRL_WR_UNLOCK_KEY, &ocotp_regs->hw_ocotp_ctrl);
+
+ /* Program the data. */
+ writel(mask, &ocotp_regs->hw_ocotp_data);
+
+ udelay(10);
+
+ ret = mxs_ocotp_wait_busy_clear();
+ if (ret) {
+ puts("Failed waiting for ready state!\n");
+ goto fail;
+ }
+
+fail:
+ mxs_ocotp_scale_vddio(0, &vddio_val);
+ ret = mxs_ocotp_scale_hclk(0, &hclk_val);
+ if (ret) {
+ puts("Failed scaling up the HCLK!\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+static int mxs_ocotp_read_fuse(uint32_t reg, uint32_t *val)
+{
+ int ret;
+
+ /* Register offset from CUST0 */
+ reg = ((uint32_t)&ocotp_regs->hw_ocotp_cust0) + (reg << 4);
+
+ ret = mxs_ocotp_wait_busy_clear();
+ if (ret) {
+ puts("Failed waiting for ready state!\n");
+ return ret;
+ }
+
+ mxs_ocotp_clear_error();
+
+ ret = mxs_ocotp_read_bank_open(1);
+ if (ret) {
+ puts("Failed opening banks for reading!\n");
+ return ret;
+ }
+
+ *val = readl(reg);
+
+ ret = mxs_ocotp_read_bank_open(0);
+ if (ret) {
+ puts("Failed closing banks for reading!\n");
+ return ret;
+ }
+
+ return ret;
+}
+
+static int mxs_ocotp_valid(u32 bank, u32 word)
+{
+ if (bank > 4)
+ return -EINVAL;
+ if (word > 7)
+ return -EINVAL;
+ return 0;
+}
+
+/*
+ * The 'fuse' command API
+ */
+int fuse_read(u32 bank, u32 word, u32 *val)
+{
+ int ret;
+
+ ret = mxs_ocotp_valid(bank, word);
+ if (ret)
+ return ret;
+
+ return mxs_ocotp_read_fuse((bank << 3) | word, val);
+}
+
+int fuse_prog(u32 bank, u32 word, u32 val)
+{
+ int ret;
+
+ ret = mxs_ocotp_valid(bank, word);
+ if (ret)
+ return ret;
+
+ return mxs_ocotp_write_fuse((bank << 3) | word, val);
+}
+
+int fuse_sense(u32 bank, u32 word, u32 *val)
+{
+ /* We do not support sensing :-( */
+ return -EINVAL;
+}
+
+int fuse_override(u32 bank, u32 word, u32 val)
+{
+ /* We do not support overriding :-( */
+ return -EINVAL;
+}
diff --git a/drivers/pci/pcie_imx.c b/drivers/pci/pcie_imx.c
index 1f600aa..c48737e 100644
--- a/drivers/pci/pcie_imx.c
+++ b/drivers/pci/pcie_imx.c
@@ -451,6 +451,17 @@ static int imx6_pcie_init_phy(void)
return 0;
}
+__weak int imx6_pcie_toggle_power(void)
+{
+#ifdef CONFIG_PCIE_IMX_POWER_GPIO
+ gpio_direction_output(CONFIG_PCIE_IMX_POWER_GPIO, 0);
+ mdelay(20);
+ gpio_set_value(CONFIG_PCIE_IMX_POWER_GPIO, 1);
+ mdelay(20);
+#endif
+ return 0;
+}
+
__weak int imx6_pcie_toggle_reset(void)
{
/*
@@ -496,7 +507,7 @@ static int imx6_pcie_deassert_core_reset(void)
{
struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
- /* FIXME: Power-up GPIO goes here. */
+ imx6_pcie_toggle_power();
/* Enable PCIe */
clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_TEST_POWERDOWN);
diff --git a/include/configs/m53evk.h b/include/configs/m53evk.h
index 16546c2..f401470 100644
--- a/include/configs/m53evk.h
+++ b/include/configs/m53evk.h
@@ -46,13 +46,13 @@
*/
#define CONFIG_NR_DRAM_BANKS 2
#define PHYS_SDRAM_1 CSD0_BASE_ADDR
-#define PHYS_SDRAM_1_SIZE (512 * 1024 * 1024)
+#define PHYS_SDRAM_1_SIZE (gd->bd->bi_dram[0].size)
#define PHYS_SDRAM_2 CSD1_BASE_ADDR
-#define PHYS_SDRAM_2_SIZE (512 * 1024 * 1024)
-#define PHYS_SDRAM_SIZE (PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE)
+#define PHYS_SDRAM_2_SIZE (gd->bd->bi_dram[1].size)
+#define PHYS_SDRAM_SIZE (gd->ram_size)
#define CONFIG_SYS_MALLOC_LEN (10 * 1024 * 1024)
#define CONFIG_SYS_MEMTEST_START 0x70000000
-#define CONFIG_SYS_MEMTEST_END 0xaff00000
+#define CONFIG_SYS_MEMTEST_END 0x8ff00000
#define CONFIG_SYS_SDRAM_BASE (PHYS_SDRAM_1)
#define CONFIG_SYS_INIT_RAM_ADDR (IRAM_BASE_ADDR)
diff --git a/include/configs/mx53loco.h b/include/configs/mx53loco.h
index 1415584..5859f36 100644
--- a/include/configs/mx53loco.h
+++ b/include/configs/mx53loco.h
@@ -194,11 +194,11 @@
/* Physical Memory Map */
#define CONFIG_NR_DRAM_BANKS 2
-#define PHYS_SDRAM_1 CSD0_BASE_ADDR
-#define PHYS_SDRAM_1_SIZE (512 * 1024 * 1024)
-#define PHYS_SDRAM_2 CSD1_BASE_ADDR
-#define PHYS_SDRAM_2_SIZE (512 * 1024 * 1024)
-#define PHYS_SDRAM_SIZE (PHYS_SDRAM_1_SIZE + PHYS_SDRAM_2_SIZE)
+#define PHYS_SDRAM_1 CSD0_BASE_ADDR
+#define PHYS_SDRAM_1_SIZE (gd->bd->bi_dram[0].size)
+#define PHYS_SDRAM_2 CSD1_BASE_ADDR
+#define PHYS_SDRAM_2_SIZE (gd->bd->bi_dram[1].size)
+#define PHYS_SDRAM_SIZE (gd->ram_size)
#define CONFIG_SYS_SDRAM_BASE (PHYS_SDRAM_1)
#define CONFIG_SYS_INIT_RAM_ADDR (IRAM_BASE_ADDR)
diff --git a/include/configs/mx6qsabreauto.h b/include/configs/mx6qsabreauto.h
index dbbb6f0..bd0144f 100644
--- a/include/configs/mx6qsabreauto.h
+++ b/include/configs/mx6qsabreauto.h
@@ -41,4 +41,7 @@
#define CONFIG_SYS_I2C_MXC
#define CONFIG_SYS_I2C_SPEED 100000
+#define CONFIG_OF_SEPARATE
+#define CONFIG_DEFAULT_DEVICE_TREE imx6q-sabreauto
+
#endif /* __MX6QSABREAUTO_CONFIG_H */
diff --git a/include/configs/mx6sabresd.h b/include/configs/mx6sabresd.h
index 4919f53..5d02d23 100644
--- a/include/configs/mx6sabresd.h
+++ b/include/configs/mx6sabresd.h
@@ -48,4 +48,14 @@
#define CONFIG_IPUV3_CLK 260000000
#define CONFIG_IMX_HDMI
+#define CONFIG_CMD_PCI
+#ifdef CONFIG_CMD_PCI
+#define CONFIG_PCI
+#define CONFIG_PCI_PNP
+#define CONFIG_PCI_SCAN_SHOW
+#define CONFIG_PCIE_IMX
+#define CONFIG_PCIE_IMX_PERST_GPIO IMX_GPIO_NR(7, 12)
+#define CONFIG_PCIE_IMX_POWER_GPIO IMX_GPIO_NR(3, 19)
+#endif
+
#endif /* __MX6QSABRESD_CONFIG_H */
diff --git a/include/configs/mxs.h b/include/configs/mxs.h
index 55ecef9..ba55177 100644
--- a/include/configs/mxs.h
+++ b/include/configs/mxs.h
@@ -80,8 +80,16 @@
* We need to sacrifice first 4 bytes of RAM here to avoid triggering some
* strange BUG in ROM corrupting first 4 bytes of RAM when loading U-Boot
* binary. In case there was more of this mess, 0x100 bytes are skipped.
+ *
+ * In case of a HAB boot, we cannot for some weird reason use the first 4KiB
+ * of DRAM when loading. Moreover, we use the first 4 KiB for IVT and CST
+ * blocks, thus U-Boot starts at offset +8 KiB of DRAM start.
+ *
+ * As for the SPL, we must avoid the first 4 KiB as well, but we load the
+ * IVT and CST to 0x8000, so we don't need to waste the subsequent 4 KiB.
*/
-#define CONFIG_SYS_TEXT_BASE 0x40000100
+#define CONFIG_SYS_TEXT_BASE 0x40002000
+#define CONFIG_SPL_TEXT_BASE 0x00001000
/* U-Boot general configuration */
#define CONFIG_SYS_LONGHELP
@@ -174,6 +182,11 @@
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
#endif
+/* OCOTP */
+#ifdef CONFIG_CMD_FUSE
+#define CONFIG_MXS_OCOTP
+#endif
+
/* SPI */
#ifdef CONFIG_CMD_SPI
#define CONFIG_HARD_SPI
diff --git a/include/configs/nitrogen6x.h b/include/configs/nitrogen6x.h
index f2db8c5..f7e7315 100644
--- a/include/configs/nitrogen6x.h
+++ b/include/configs/nitrogen6x.h
@@ -356,7 +356,6 @@
/*
* PCI express
*/
-#define CONFIG_CMD_PCI
#ifdef CONFIG_CMD_PCI
#define CONFIG_PCI
#define CONFIG_PCI_PNP
diff --git a/include/configs/woodburn_sd.h b/include/configs/woodburn_sd.h
index 10e1d17..437472f 100644
--- a/include/configs/woodburn_sd.h
+++ b/include/configs/woodburn_sd.h
@@ -17,8 +17,6 @@
/* Set TEXT in RAM */
#define CONFIG_SYS_TEXT_BASE 0x82000000
-#define CONFIG_BOOT_INTERNAL
-
/*
* SPL
*/