summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.checkpatch.conf3
-rw-r--r--MAINTAINERS9
-rwxr-xr-xMAKEALL4
-rw-r--r--arch/arm/cpu/arm1176/bcm2835/timer.c14
-rw-r--r--arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c18
-rw-r--r--arch/arm/cpu/armv7/cache_v7.c3
-rw-r--r--arch/arm/cpu/armv7/mx6/soc.c12
-rw-r--r--arch/arm/cpu/armv7/omap-common/hwinit-common.c35
-rw-r--r--arch/arm/cpu/armv7/start.S1
-rw-r--r--arch/arm/imx-common/Makefile1
-rw-r--r--arch/arm/imx-common/cmd_hdmidet.c37
-rw-r--r--arch/arm/imx-common/timer.c26
-rw-r--r--arch/arm/include/asm/arch-bcm2835/timer.h2
-rw-r--r--arch/arm/include/asm/arch-mx6/mx6dl_pins.h3
-rw-r--r--arch/arm/include/asm/cache.h2
-rw-r--r--arch/arm/include/asm/system.h14
-rw-r--r--arch/arm/lib/cache-cp15.c11
-rw-r--r--arch/x86/lib/board.c8
-rw-r--r--board/boundary/nitrogen6x/nitrogen6x.c8
-rw-r--r--board/chromebook-x86/dts/link.dts11
-rw-r--r--board/freescale/mx6qsabreauto/mx6qsabreauto.c18
-rw-r--r--board/freescale/mx6qsabrelite/README4
-rw-r--r--board/freescale/mx6qsabrelite/mx6qsabrelite.c8
-rw-r--r--board/freescale/mx6qsabresd/mx6qsabresd.c48
-rw-r--r--board/wandboard/Makefile29
-rw-r--r--board/wandboard/README40
-rw-r--r--board/wandboard/wandboard.c178
-rw-r--r--boards.cfg5
-rw-r--r--common/cmd_bootm.c39
-rw-r--r--common/cmd_ext4.c6
-rw-r--r--common/cmd_sf.c8
-rw-r--r--common/env_callback.c2
-rw-r--r--common/image.c1
-rw-r--r--doc/README.mx28evk18
-rw-r--r--drivers/mmc/bcm2835_sdhci.c5
-rw-r--r--drivers/mmc/fsl_esdhc.c7
-rw-r--r--drivers/mtd/spi/atmel.c8
-rw-r--r--drivers/mtd/spi/eon.c8
-rw-r--r--drivers/mtd/spi/macronix.c8
-rw-r--r--drivers/mtd/spi/ramtron.c4
-rw-r--r--drivers/mtd/spi/spansion.c8
-rw-r--r--drivers/mtd/spi/spi_flash.c81
-rw-r--r--drivers/mtd/spi/sst.c8
-rw-r--r--drivers/mtd/spi/stmicro.c8
-rw-r--r--drivers/mtd/spi/winbond.c8
-rw-r--r--drivers/spi/Makefile4
-rw-r--r--drivers/spi/altera_spi.c4
-rw-r--r--drivers/spi/andes_spi.c4
-rw-r--r--drivers/spi/armada100_spi.c4
-rw-r--r--drivers/spi/atmel_spi.c4
-rw-r--r--drivers/spi/bfin_spi.c4
-rw-r--r--drivers/spi/bfin_spi6xx.c4
-rw-r--r--drivers/spi/cf_qspi.c4
-rw-r--r--drivers/spi/cf_spi.c4
-rw-r--r--drivers/spi/davinci_spi.c4
-rw-r--r--drivers/spi/exynos_spi.c4
-rw-r--r--drivers/spi/fsl_espi.c4
-rw-r--r--drivers/spi/ich.c754
-rw-r--r--drivers/spi/ich.h143
-rw-r--r--drivers/spi/kirkwood_spi.c5
-rw-r--r--drivers/spi/mpc52xx_spi.c5
-rw-r--r--drivers/spi/mpc8xxx_spi.c5
-rw-r--r--drivers/spi/mxc_spi.c12
-rw-r--r--drivers/spi/mxs_spi.c4
-rw-r--r--drivers/spi/oc_tiny_spi.c5
-rw-r--r--drivers/spi/omap3_spi.c27
-rw-r--r--drivers/spi/sh_spi.c4
-rw-r--r--drivers/spi/soft_spi.c4
-rw-r--r--drivers/spi/spi.c39
-rw-r--r--drivers/spi/tegra20_sflash.c2
-rw-r--r--drivers/spi/tegra20_slink.c4
-rw-r--r--drivers/spi/xilinx_spi.c4
-rw-r--r--include/config_defaults.h1
-rw-r--r--include/configs/coreboot.h14
-rw-r--r--include/configs/mx23_olinuxino.h162
-rw-r--r--include/configs/mx25pdk.h4
-rw-r--r--include/configs/mx28evk.h92
-rw-r--r--include/configs/mx6qsabre_common.h2
-rw-r--r--include/configs/mx6qsabrelite.h3
-rw-r--r--include/configs/rpi_b.h2
-rw-r--r--include/configs/wandboard.h209
-rw-r--r--include/env_callback.h1
-rw-r--r--include/fdtdec.h16
-rw-r--r--include/fsl_esdhc.h1
-rw-r--r--include/image.h1
-rw-r--r--include/spi.h44
-rw-r--r--include/spi_flash.h39
-rw-r--r--lib/fdtdec.c28
-rwxr-xr-xtools/checkpatch.pl1
89 files changed, 2107 insertions, 357 deletions
diff --git a/.checkpatch.conf b/.checkpatch.conf
index 38386b3..d88af57 100644
--- a/.checkpatch.conf
+++ b/.checkpatch.conf
@@ -15,3 +15,6 @@
# enable more tests
--strict
+
+# Not Linux, so we don't recommend usleep_range() over udelay()
+--ignore USLEEP_RANGE
diff --git a/MAINTAINERS b/MAINTAINERS
index 6469973..e131f80 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -663,6 +663,7 @@ Fabio Estevam <fabio.estevam@freescale.com>
mx53smd i.MX53
mx6qsabresd i.MX6Q
mx6qsabreauto i.MX6Q
+ wandboard i.MX6DL/S
Daniel Gorsulowski <daniel.gorsulowski@esd.eu>
@@ -688,6 +689,10 @@ Stefan Herbrechtsmeier <stefan@code.herbrechtsmeier.net>
dns325 ARM926EJS (Kirkwood SoC)
+Lauri Hintsala <lauri.hintsala@bluegiga.com>
+
+ apx4devkit i.MX28
+
Vaibhav Hiremath <hvaibhav@ti.com>
am3517_evm ARM ARMV7 (AM35x SoC)
@@ -806,10 +811,6 @@ Linus Walleij <linus.walleij@linaro.org>
integratorap various
integratorcp various
-Veli-Pekka Peltola <veli-pekka.peltola@bluegiga.com>
-
- apx4devkit i.MX28
-
Luka Perkov <luka@openwrt.org>
ib62x0 ARM926EJS
diff --git a/MAKEALL b/MAKEALL
index c1d8957..91fa495 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -104,9 +104,9 @@ while true ; do
-s|--soc)
# echo "Option SoC: argument \`$2'"
if [ "$opt_s" ] ; then
- opt_s="${opt_s%)} || \$6 == \"$2\")"
+ opt_s="${opt_s%)} || \$6 == \"$2\" || \$6 ~ /$2/)"
else
- opt_s="(\$6 == \"$2\")"
+ opt_s="(\$6 == \"$2\" || \$6 ~ /$2/)"
fi
SELECTED='y'
shift 2 ;;
diff --git a/arch/arm/cpu/arm1176/bcm2835/timer.c b/arch/arm/cpu/arm1176/bcm2835/timer.c
index d232d7e..2edd671 100644
--- a/arch/arm/cpu/arm1176/bcm2835/timer.c
+++ b/arch/arm/cpu/arm1176/bcm2835/timer.c
@@ -23,7 +23,7 @@ int timer_init(void)
return 0;
}
-ulong get_timer(ulong base)
+ulong get_timer_us(ulong base)
{
struct bcm2835_timer_regs *regs =
(struct bcm2835_timer_regs *)BCM2835_TIMER_PHYSADDR;
@@ -31,6 +31,14 @@ ulong get_timer(ulong base)
return readl(&regs->clo) - base;
}
+ulong get_timer(ulong base)
+{
+ ulong us = get_timer_us(0);
+ us /= (1000000 / CONFIG_SYS_HZ);
+ us -= base;
+ return us;
+}
+
unsigned long long get_ticks(void)
{
return get_timer(0);
@@ -46,10 +54,10 @@ void __udelay(unsigned long usec)
ulong endtime;
signed long diff;
- endtime = get_timer(0) + usec;
+ endtime = get_timer_us(0) + usec;
do {
- ulong now = get_timer(0);
+ ulong now = get_timer_us(0);
diff = endtime - now;
} while (diff >= 0);
}
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
index fdac73c..bc2d69c 100644
--- a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
+++ b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c
@@ -46,17 +46,17 @@ static uint32_t dram_vals[] = {
0x00000000, 0x00000000, 0x00010101, 0x01010101,
0x000f0f01, 0x0f02020a, 0x00000000, 0x00010101,
0x00000100, 0x00000100, 0x00000000, 0x00000002,
- 0x01010000, 0x05060302, 0x06005003, 0x0a0000c8,
- 0x02009c40, 0x0000030c, 0x0036a609, 0x031a0612,
+ 0x01010000, 0x07080403, 0x06005003, 0x0a0000c8,
+ 0x02009c40, 0x0002030c, 0x0036a609, 0x031a0612,
0x02030202, 0x00c8001c, 0x00000000, 0x00000000,
0x00012100, 0xffff0303, 0x00012100, 0xffff0303,
0x00012100, 0xffff0303, 0x00012100, 0xffff0303,
0x00000003, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000612, 0x01000F02,
- 0x06120612, 0x00000200, 0x00020007, 0xf5014b27,
- 0xf5014b27, 0xf5014b27, 0xf5014b27, 0x07000300,
- 0x07000300, 0x07000300, 0x07000300, 0x00000006,
+ 0x06120612, 0x00000200, 0x00020007, 0xf4004a27,
+ 0xf4004a27, 0xf4004a27, 0xf4004a27, 0x07000300,
+ 0x07000300, 0x07400300, 0x07400300, 0x00000005,
0x00000000, 0x00000000, 0x01000000, 0x01020408,
0x08040201, 0x000f1133, 0x00000000, 0x00001f04,
0x00001f04, 0x00001f04, 0x00001f04, 0x00001f04,
@@ -77,14 +77,14 @@ static uint32_t dram_vals[] = {
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00000000, 0x00010000, 0x00020304,
- 0x00000004, 0x00000000, 0x00000000, 0x00000000,
+ 0x00000000, 0x00000000, 0x00010000, 0x00030404,
+ 0x00000003, 0x00000000, 0x00000000, 0x00000000,
0x00000000, 0x00000000, 0x00000000, 0x01010000,
0x01000000, 0x03030000, 0x00010303, 0x01020202,
0x00000000, 0x02040303, 0x21002103, 0x00061200,
- 0x06120612, 0x04320432, 0x04320432, 0x00040004,
+ 0x06120612, 0x04420442, 0x04420442, 0x00040004,
0x00040004, 0x00000000, 0x00000000, 0x00000000,
- 0x00000000, 0x00010001
+ 0x00000000, 0xffffffff
/*
* i.MX23 DDR at 133MHz
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c
index 5f6d039..8748c14 100644
--- a/arch/arm/cpu/armv7/cache_v7.c
+++ b/arch/arm/cpu/armv7/cache_v7.c
@@ -340,6 +340,9 @@ void mmu_page_table_flush(unsigned long start, unsigned long stop)
{
}
+void arm_init_domains(void)
+{
+}
#endif /* #ifndef CONFIG_SYS_DCACHE_OFF */
#ifndef CONFIG_SYS_ICACHE_OFF
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
index 193ba12..2ea8ca3 100644
--- a/arch/arm/cpu/armv7/mx6/soc.c
+++ b/arch/arm/cpu/armv7/mx6/soc.c
@@ -61,6 +61,18 @@ u32 get_cpu_rev(void)
return (type << 12) | (reg + 0x10);
}
+#ifdef CONFIG_REVISION_TAG
+u32 __weak get_board_rev(void)
+{
+ u32 cpurev = get_cpu_rev();
+ u32 type = ((cpurev >> 12) & 0xff);
+ if (type == MXC_CPU_MX6SOLO)
+ cpurev = (MXC_CPU_MX6DL) << 12 | (cpurev & 0xFFF);
+
+ return cpurev;
+}
+#endif
+
void init_aips(void)
{
struct aipstz_regs *aips1, *aips2;
diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
index 05ff2e8..70d16a8 100644
--- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c
+++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
@@ -34,6 +34,12 @@
#include <asm/emif.h>
#include <asm/omap_common.h>
#include <linux/compiler.h>
+#include <asm/cache.h>
+#include <asm/system.h>
+
+#define ARMV7_DCACHE_WRITEBACK 0xe
+#define ARMV7_DOMAIN_CLIENT 1
+#define ARMV7_DOMAIN_MASK (0x3 << 0)
DECLARE_GLOBAL_DATA_PTR;
@@ -269,4 +275,33 @@ void enable_caches(void)
/* Enable D-cache. I-cache is already enabled in start.S */
dcache_enable();
}
+
+void dram_bank_mmu_setup(int bank)
+{
+ bd_t *bd = gd->bd;
+ int i;
+
+ u32 start = bd->bi_dram[bank].start >> 20;
+ u32 size = bd->bi_dram[bank].size >> 20;
+ u32 end = start + size;
+
+ debug("%s: bank: %d\n", __func__, bank);
+ for (i = start; i < end; i++)
+ set_section_dcache(i, ARMV7_DCACHE_WRITEBACK);
+
+}
+
+void arm_init_domains(void)
+{
+ u32 reg;
+
+ reg = get_dacr();
+ /*
+ * Set DOMAIN to client access so that all permissions
+ * set in pagetables are validated by the mmu.
+ */
+ reg &= ~ARMV7_DOMAIN_MASK;
+ reg |= ARMV7_DOMAIN_CLIENT;
+ set_dacr(reg);
+}
#endif
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index c0e1849..36a4c3c 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -254,7 +254,6 @@ ENTRY(c_runtime_cpu_setup)
#if !defined(CONFIG_TEGRA)
/* Set vector address in CP15 VBAR register */
ldr r0, =_start
- add r0, r0, r9
mcr p15, 0, r0, c12, c0, 0 @Set VBAR
#endif /* !Tegra */
diff --git a/arch/arm/imx-common/Makefile b/arch/arm/imx-common/Makefile
index 6309fcd..428a57e 100644
--- a/arch/arm/imx-common/Makefile
+++ b/arch/arm/imx-common/Makefile
@@ -32,6 +32,7 @@ COBJS-y = iomux-v3.o timer.o cpu.o speed.o
COBJS-$(CONFIG_I2C_MXC) += i2c-mxv7.o
endif
COBJS-$(CONFIG_CMD_BMODE) += cmd_bmode.o
+COBJS-$(CONFIG_CMD_HDMIDETECT) += cmd_hdmidet.o
COBJS := $(sort $(COBJS-y))
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/arch/arm/imx-common/cmd_hdmidet.c b/arch/arm/imx-common/cmd_hdmidet.c
new file mode 100644
index 0000000..794bf50
--- /dev/null
+++ b/arch/arm/imx-common/cmd_hdmidet.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 Boundary Devices Inc.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/mxc_hdmi.h>
+#include <asm/io.h>
+
+static int do_hdmidet(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR;
+ u8 reg = readb(&hdmi->phy_stat0) & HDMI_PHY_HPD;
+ return (reg&HDMI_PHY_HPD) ? 0 : 1;
+}
+
+U_BOOT_CMD(hdmidet, 1, 1, do_hdmidet,
+ "detect HDMI monitor",
+ ""
+);
diff --git a/arch/arm/imx-common/timer.c b/arch/arm/imx-common/timer.c
index ab37d64..1dbc413 100644
--- a/arch/arm/imx-common/timer.c
+++ b/arch/arm/imx-common/timer.c
@@ -48,9 +48,6 @@ static struct mxc_gpt *cur_gpt = (struct mxc_gpt *)GPT1_BASE_ADDR;
DECLARE_GLOBAL_DATA_PTR;
-#define timestamp (gd->arch.tbl)
-#define lastinc (gd->arch.lastinc)
-
static inline unsigned long long tick_to_time(unsigned long long tick)
{
tick *= CONFIG_SYS_HZ;
@@ -70,7 +67,6 @@ static inline unsigned long long us_to_tick(unsigned long long usec)
int timer_init(void)
{
int i;
- ulong val;
/* setup GP Timer 1 */
__raw_writel(GPTCR_SWR, &cur_gpt->control);
@@ -85,9 +81,8 @@ int timer_init(void)
i = __raw_readl(&cur_gpt->control);
__raw_writel(i | GPTCR_CLKSOURCE_32 | GPTCR_TEN, &cur_gpt->control);
- val = __raw_readl(&cur_gpt->counter);
- lastinc = val / (MXC_CLK32 / CONFIG_SYS_HZ);
- timestamp = 0;
+ gd->arch.tbl = __raw_readl(&cur_gpt->counter);
+ gd->arch.tbu = 0;
return 0;
}
@@ -96,18 +91,11 @@ unsigned long long get_ticks(void)
{
ulong now = __raw_readl(&cur_gpt->counter); /* current tick value */
- if (now >= lastinc) {
- /*
- * normal mode (non roll)
- * move stamp forward with absolut diff ticks
- */
- timestamp += (now - lastinc);
- } else {
- /* we have rollover of incrementer */
- timestamp += (0xFFFFFFFF - lastinc) + now;
- }
- lastinc = now;
- return timestamp;
+ /* increment tbu if tbl has rolled over */
+ if (now < gd->arch.tbl)
+ gd->arch.tbu++;
+ gd->arch.tbl = now;
+ return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
}
ulong get_timer_masked(void)
diff --git a/arch/arm/include/asm/arch-bcm2835/timer.h b/arch/arm/include/asm/arch-bcm2835/timer.h
index 30c70e0..c2001b6 100644
--- a/arch/arm/include/asm/arch-bcm2835/timer.h
+++ b/arch/arm/include/asm/arch-bcm2835/timer.h
@@ -34,4 +34,6 @@ struct bcm2835_timer_regs {
#define BCM2835_TIMER_CS_M1 (1 << 1)
#define BCM2835_TIMER_CS_M0 (1 << 0)
+extern ulong get_timer_us(ulong base);
+
#endif
diff --git a/arch/arm/include/asm/arch-mx6/mx6dl_pins.h b/arch/arm/include/asm/arch-mx6/mx6dl_pins.h
index 9494e41..9846f1b 100644
--- a/arch/arm/include/asm/arch-mx6/mx6dl_pins.h
+++ b/arch/arm/include/asm/arch-mx6/mx6dl_pins.h
@@ -50,6 +50,8 @@
#define NO_MUX_I 0
#define NO_PAD_I 0
enum {
+ MX6_PAD_CSI0_DAT10__UART1_TXD = IOMUX_PAD(0x0360, 0x004C, 3, 0x0000, 0, 0),
+ MX6_PAD_CSI0_DAT11__UART1_RXD = IOMUX_PAD(0x0364, 0x0050, 3, 0x08FC, 1, 0),
MX6_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK = IOMUX_PAD(0x03B0, 0x009C, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
MX6_PAD_DI0_PIN15__IPU1_DI0_PIN15 = IOMUX_PAD(0x03B4, 0x00A0, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
MX6_PAD_DI0_PIN2__IPU1_DI0_PIN2 = IOMUX_PAD(0x03B8, 0x00A4, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
@@ -90,6 +92,7 @@ enum {
MX6_PAD_EIM_D27__UART2_RXD = IOMUX_PAD(0x0540, 0x0170, 4, 0x0904, 1, 0),
MX6_PAD_EIM_D28__I2C1_SDA = IOMUX_PAD(0x0544, 0x0174, 1 | IOMUX_CONFIG_SION, 0x086C, 1, 0),
MX6_PAD_EIM_D28__GPIO_3_28 = IOMUX_PAD(0x0544, 0x0174, 5, 0x0000, 0, 0),
+ MX6_PAD_EIM_D29__GPIO_3_29 = IOMUX_PAD(0x0548, 0x0178, 5, 0x0000, 0, 0),
MX6_PAD_ENET_MDC__ENET_MDC = IOMUX_PAD(0x05B8, 0x01E8, 1, 0x0000, 0, 0),
MX6_PAD_ENET_MDIO__ENET_MDIO = IOMUX_PAD(0x05BC, 0x01EC, 1, 0x0810, 0, 0),
MX6_PAD_ENET_REF_CLK__ENET_TX_CLK = IOMUX_PAD(0x05C0, 0x01F0, 1, 0x0000, 0, 0),
diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h
index eef6a5a..8153484 100644
--- a/arch/arm/include/asm/cache.h
+++ b/arch/arm/include/asm/cache.h
@@ -41,7 +41,9 @@ static inline void invalidate_l2_cache(void)
void l2_cache_enable(void);
void l2_cache_disable(void);
+void set_section_dcache(int section, enum dcache_option option);
+void dram_bank_mmu_setup(int bank);
/*
* The current upper bound for ARM L1 data cache line sizes is 64 bytes. We
* use that value for aligning DMA buffers unless the board config has specified
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 1918492..760345f 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -81,6 +81,20 @@ static inline void set_cr(unsigned int val)
isb();
}
+static inline unsigned int get_dacr(void)
+{
+ unsigned int val;
+ asm("mrc p15, 0, %0, c3, c0, 0 @ get DACR" : "=r" (val) : : "cc");
+ return val;
+}
+
+static inline void set_dacr(unsigned int val)
+{
+ asm volatile("mcr p15, 0, %0, c3, c0, 0 @ set DACR"
+ : : "r" (val) : "cc");
+ isb();
+}
+
/* options available for data cache on each page */
enum dcache_option {
DCACHE_OFF = 0x12,
diff --git a/arch/arm/lib/cache-cp15.c b/arch/arm/lib/cache-cp15.c
index b6e5e95..4abe1cf 100644
--- a/arch/arm/lib/cache-cp15.c
+++ b/arch/arm/lib/cache-cp15.c
@@ -23,6 +23,8 @@
#include <common.h>
#include <asm/system.h>
+#include <asm/cache.h>
+#include <linux/compiler.h>
#if !(defined(CONFIG_SYS_ICACHE_OFF) && defined(CONFIG_SYS_DCACHE_OFF))
@@ -34,6 +36,10 @@ void __arm_init_before_mmu(void)
void arm_init_before_mmu(void)
__attribute__((weak, alias("__arm_init_before_mmu")));
+__weak void arm_init_domains(void)
+{
+}
+
static void cp_delay (void)
{
volatile int i;
@@ -77,7 +83,7 @@ void mmu_set_region_dcache_behaviour(u32 start, int size,
mmu_page_table_flush((u32)&page_table[start], (u32)&page_table[end]);
}
-static inline void dram_bank_mmu_setup(int bank)
+__weak void dram_bank_mmu_setup(int bank)
{
bd_t *bd = gd->bd;
int i;
@@ -115,6 +121,9 @@ static inline void mmu_setup(void)
/* Set the access control to all-supervisor */
asm volatile("mcr p15, 0, %0, c3, c0, 0"
: : "r" (~0));
+
+ arm_init_domains();
+
/* and enable the mmu */
reg = get_cr(); /* get control reg. */
cp_delay();
diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c
index 452e5d8..f372898 100644
--- a/arch/x86/lib/board.c
+++ b/arch/x86/lib/board.c
@@ -164,13 +164,13 @@ init_fnc_t *init_sequence_r[] = {
#ifndef CONFIG_SYS_NO_FLASH
flash_init_r,
#endif
-#ifdef CONFIG_SPI
- init_func_spi;
-#endif
- env_relocate_r,
#ifdef CONFIG_PCI
pci_init_r,
#endif
+#ifdef CONFIG_SPI
+ init_func_spi,
+#endif
+ env_relocate_r,
stdio_init,
jumptable_init_r,
console_init_r,
diff --git a/board/boundary/nitrogen6x/nitrogen6x.c b/board/boundary/nitrogen6x/nitrogen6x.c
index 229c237..cc071d6 100644
--- a/board/boundary/nitrogen6x/nitrogen6x.c
+++ b/board/boundary/nitrogen6x/nitrogen6x.c
@@ -304,6 +304,9 @@ int board_mmc_init(bd_t *bis)
usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
+ usdhc_cfg[0].max_bus_width = 4;
+ usdhc_cfg[1].max_bus_width = 4;
+
for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) {
switch (index) {
case 0:
@@ -328,11 +331,6 @@ int board_mmc_init(bd_t *bis)
}
#endif
-u32 get_board_rev(void)
-{
- return 0x63000;
-}
-
#ifdef CONFIG_MXC_SPI
iomux_v3_cfg_t const ecspi1_pads[] = {
/* SS1 */
diff --git a/board/chromebook-x86/dts/link.dts b/board/chromebook-x86/dts/link.dts
index ae8217d..d0738cb 100644
--- a/board/chromebook-x86/dts/link.dts
+++ b/board/chromebook-x86/dts/link.dts
@@ -21,4 +21,15 @@
chosen { };
memory { device_type = "memory"; reg = <0 0>; };
+
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "intel,ich9";
+ spi-flash@0 {
+ reg = <0>;
+ compatible = "winbond,w25q64", "spi-flash";
+ memory-map = <0xff800000 0x00800000>;
+ };
+ };
};
diff --git a/board/freescale/mx6qsabreauto/mx6qsabreauto.c b/board/freescale/mx6qsabreauto/mx6qsabreauto.c
index 91cc007..aec3286 100644
--- a/board/freescale/mx6qsabreauto/mx6qsabreauto.c
+++ b/board/freescale/mx6qsabreauto/mx6qsabreauto.c
@@ -26,6 +26,7 @@
#include <asm/errno.h>
#include <asm/gpio.h>
#include <asm/imx-common/iomux-v3.h>
+#include <asm/imx-common/boot_mode.h>
#include <mmc.h>
#include <fsl_esdhc.h>
#include <miiphy.h>
@@ -216,6 +217,23 @@ int board_init(void)
return 0;
}
+#ifdef CONFIG_CMD_BMODE
+static const struct boot_mode board_boot_modes[] = {
+ /* 4 bit bus width */
+ {"mmc0", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
+ {NULL, 0},
+};
+#endif
+
+int board_late_init(void)
+{
+#ifdef CONFIG_CMD_BMODE
+ add_board_boot_modes(board_boot_modes);
+#endif
+
+ return 0;
+}
+
int checkboard(void)
{
int rev = mx6sabre_rev();
diff --git a/board/freescale/mx6qsabrelite/README b/board/freescale/mx6qsabrelite/README
index 6f2f534..12a9c85 100644
--- a/board/freescale/mx6qsabrelite/README
+++ b/board/freescale/mx6qsabrelite/README
@@ -40,7 +40,7 @@ enter the following commands:
MX6Q SABRELITE U-Boot > mmc dev 0
MX6Q SABRELITE U-Boot > mmc read 0x10800000 0 200
- MX6Q SABRELITE U-Boot > sf probe 1
+ MX6Q SABRELITE U-Boot > sf probe
MX6Q SABRELITE U-Boot > sf erase 0 0x40000
MX6Q SABRELITE U-Boot > sf write 0x10800000 0 0x40000
@@ -63,7 +63,7 @@ https://wiki.linaro.org/Boards/MX6QSabreLite
To build U-Boot for the SabreLite board:
make mx6qsabrelite_config
- make u-boot.imx
+ make
To copy the resulting u-boot.imx to the SD card:
diff --git a/board/freescale/mx6qsabrelite/mx6qsabrelite.c b/board/freescale/mx6qsabrelite/mx6qsabrelite.c
index 5b69a6d..9f9cac8 100644
--- a/board/freescale/mx6qsabrelite/mx6qsabrelite.c
+++ b/board/freescale/mx6qsabrelite/mx6qsabrelite.c
@@ -274,6 +274,9 @@ int board_mmc_init(bd_t *bis)
usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
usdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC4_CLK);
+ usdhc_cfg[0].max_bus_width = 4;
+ usdhc_cfg[1].max_bus_width = 4;
+
for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) {
switch (index) {
case 0:
@@ -298,11 +301,6 @@ int board_mmc_init(bd_t *bis)
}
#endif
-u32 get_board_rev(void)
-{
- return 0x63000 ;
-}
-
#ifdef CONFIG_MXC_SPI
iomux_v3_cfg_t const ecspi1_pads[] = {
/* SS1 */
diff --git a/board/freescale/mx6qsabresd/mx6qsabresd.c b/board/freescale/mx6qsabresd/mx6qsabresd.c
index 2b3926a..0d7cb9e 100644
--- a/board/freescale/mx6qsabresd/mx6qsabresd.c
+++ b/board/freescale/mx6qsabresd/mx6qsabresd.c
@@ -26,10 +26,12 @@
#include <asm/errno.h>
#include <asm/gpio.h>
#include <asm/imx-common/iomux-v3.h>
+#include <asm/imx-common/boot_mode.h>
#include <mmc.h>
#include <fsl_esdhc.h>
#include <miiphy.h>
#include <netdev.h>
+
DECLARE_GLOBAL_DATA_PTR;
#define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
@@ -145,21 +147,34 @@ struct fsl_esdhc_cfg usdhc_cfg[3] = {
int board_mmc_getcd(struct mmc *mmc)
{
struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+ int ret = 0;
switch (cfg->esdhc_base) {
case USDHC2_BASE_ADDR:
- return !gpio_get_value(USDHC2_CD_GPIO);
+ ret = !gpio_get_value(USDHC2_CD_GPIO);
+ break;
case USDHC3_BASE_ADDR:
- return !gpio_get_value(USDHC3_CD_GPIO);
- default:
- return 1; /* eMMC/uSDHC4 is always present */
+ ret = !gpio_get_value(USDHC3_CD_GPIO);
+ break;
+ case USDHC4_BASE_ADDR:
+ ret = 1; /* eMMC/uSDHC4 is always present */
+ break;
}
+
+ return ret;
}
int board_mmc_init(bd_t *bis)
{
int i;
+ /*
+ * According to the board_mmc_init() the following map is done:
+ * (U-boot device node) (Physical Port)
+ * mmc0 SD2
+ * mmc1 SD3
+ * mmc2 eMMC
+ */
for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) {
switch (i) {
case 0:
@@ -239,11 +254,6 @@ int board_eth_init(bd_t *bis)
return 0;
}
-u32 get_board_rev(void)
-{
- return 0x63000;
-}
-
int board_early_init_f(void)
{
setup_iomux_uart();
@@ -259,6 +269,26 @@ int board_init(void)
return 0;
}
+#ifdef CONFIG_CMD_BMODE
+static const struct boot_mode board_boot_modes[] = {
+ /* 4 bit bus width */
+ {"sd2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)},
+ {"sd3", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)},
+ /* 8 bit bus width */
+ {"emmc", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)},
+ {NULL, 0},
+};
+#endif
+
+int board_late_init(void)
+{
+#ifdef CONFIG_CMD_BMODE
+ add_board_boot_modes(board_boot_modes);
+#endif
+
+ return 0;
+}
+
int checkboard(void)
{
puts("Board: MX6Q-SabreSD\n");
diff --git a/board/wandboard/Makefile b/board/wandboard/Makefile
new file mode 100644
index 0000000..014ea6c
--- /dev/null
+++ b/board/wandboard/Makefile
@@ -0,0 +1,29 @@
+#
+# (C) Copyright 2013 Freescale Semiconductor, Inc.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+
+include $(TOPDIR)/config.mk
+
+LIB = $(obj)lib$(BOARD).o
+
+COBJS := wandboard.o
+
+SRCS := $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+
+$(LIB): $(obj).depend $(OBJS)
+ $(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/wandboard/README b/board/wandboard/README
new file mode 100644
index 0000000..e0b0b33
--- /dev/null
+++ b/board/wandboard/README
@@ -0,0 +1,40 @@
+U-Boot for Wandboard
+--------------------
+
+This file contains information for the port of U-Boot to the Wandboard.
+
+Wandboard is a development board that has two variants: one version based
+on mx6 dual lite and another one based on mx6 solo.
+
+For more details about Wandboard, please refer to:
+http://www.wandboard.org/
+
+Building U-boot for Wandboard
+-----------------------------
+
+To build U-Boot for the Wandboard Dual Lite version:
+
+$ make wanboard_dl_config
+$ make
+
+To build U-Boot for the Wandboard Solo version:
+
+$ make wanboard_solo_config
+$ make
+
+Flashing U-boot into the SD card
+--------------------------------
+
+- After the 'make' command completes, the generated 'u-boot.imx' binary must be
+flashed into the SD card;
+
+$ sudo dd if=u-boot.imx of=/dev/mmcblk0 bs=512 seek=2; sync
+
+(Note - the SD card node may vary, so adjust this as needed).
+
+- Insert the SD card into the slot located in the bottom of the board (same side
+as the mx6 processor)
+
+- Connect the serial cable to the host PC
+
+- Power up the board and U-boot messages will appear in the serial console.
diff --git a/board/wandboard/wandboard.c b/board/wandboard/wandboard.c
new file mode 100644
index 0000000..ac7b89a
--- /dev/null
+++ b/board/wandboard/wandboard.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * Author: Fabio Estevam <fabio.estevam@freescale.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#include <asm/arch/clock.h>
+#include <asm/arch/iomux.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/mx6-pins.h>
+#include <asm/arch/sys_proto.h>
+#include <asm/gpio.h>
+#include <asm/imx-common/iomux-v3.h>
+#include <asm/io.h>
+#include <asm/sizes.h>
+#include <common.h>
+#include <fsl_esdhc.h>
+#include <mmc.h>
+#include <miiphy.h>
+#include <netdev.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define ENET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define ETH_PHY_RESET IMX_GPIO_NR(3, 29)
+
+int dram_init(void)
+{
+ gd->ram_size = CONFIG_DDR_MB * SZ_1M;
+
+ return 0;
+}
+
+static iomux_v3_cfg_t const uart1_pads[] = {
+ MX6_PAD_CSI0_DAT10__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+ MX6_PAD_CSI0_DAT11__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const usdhc3_pads[] = {
+ MX6_PAD_SD3_CLK__USDHC3_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_SD3_CMD__USDHC3_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+ MX6_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
+};
+
+static iomux_v3_cfg_t const enet_pads[] = {
+ MX6_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(ENET_PAD_CTRL),
+ MX6_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(ENET_PAD_CTRL),
+ MX6_PAD_RGMII_TXC__ENET_RGMII_TXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
+ MX6_PAD_RGMII_TD0__ENET_RGMII_TD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+ MX6_PAD_RGMII_TD1__ENET_RGMII_TD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+ MX6_PAD_RGMII_TD2__ENET_RGMII_TD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+ MX6_PAD_RGMII_TD3__ENET_RGMII_TD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+ MX6_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
+ MX6_PAD_ENET_REF_CLK__ENET_TX_CLK | MUX_PAD_CTRL(ENET_PAD_CTRL),
+ MX6_PAD_RGMII_RXC__ENET_RGMII_RXC | MUX_PAD_CTRL(ENET_PAD_CTRL),
+ MX6_PAD_RGMII_RD0__ENET_RGMII_RD0 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+ MX6_PAD_RGMII_RD1__ENET_RGMII_RD1 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+ MX6_PAD_RGMII_RD2__ENET_RGMII_RD2 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+ MX6_PAD_RGMII_RD3__ENET_RGMII_RD3 | MUX_PAD_CTRL(ENET_PAD_CTRL),
+ MX6_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
+ /* AR8031 PHY Reset */
+ MX6_PAD_EIM_D29__GPIO_3_29 | MUX_PAD_CTRL(NO_PAD_CTRL),
+};
+
+static void setup_iomux_uart(void)
+{
+ imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
+}
+
+static void setup_iomux_enet(void)
+{
+ imx_iomux_v3_setup_multiple_pads(enet_pads, ARRAY_SIZE(enet_pads));
+
+ /* Reset AR8031 PHY */
+ gpio_direction_output(ETH_PHY_RESET, 0);
+ udelay(500);
+ gpio_set_value(ETH_PHY_RESET, 1);
+}
+
+static struct fsl_esdhc_cfg usdhc_cfg[1] = {
+ {USDHC3_BASE_ADDR},
+};
+
+int board_mmc_init(bd_t *bis)
+{
+ imx_iomux_v3_setup_multiple_pads(usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
+
+ usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK);
+ usdhc_cfg[0].max_bus_width = 4;
+
+ return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
+}
+
+static int mx6_rgmii_rework(struct phy_device *phydev)
+{
+ unsigned short val;
+
+ /* To enable AR8031 ouput a 125MHz clk from CLK_25M */
+ phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x7);
+ phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
+ phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
+
+ val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
+ val &= 0xffe3;
+ val |= 0x18;
+ phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val);
+
+ /* introduce tx clock delay */
+ phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x5);
+ val = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
+ val |= 0x0100;
+ phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, val);
+
+ return 0;
+}
+
+int board_phy_config(struct phy_device *phydev)
+{
+ mx6_rgmii_rework(phydev);
+
+ if (phydev->drv->config)
+ phydev->drv->config(phydev);
+
+ return 0;
+}
+
+int board_eth_init(bd_t *bis)
+{
+ int ret;
+
+ setup_iomux_enet();
+
+ ret = cpu_eth_init(bis);
+ if (ret)
+ printf("FEC MXC: %s:failed\n", __func__);
+
+ return 0;
+}
+
+int board_early_init_f(void)
+{
+ setup_iomux_uart();
+ return 0;
+}
+
+int board_init(void)
+{
+ /* address of boot parameters */
+ gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
+
+ return 0;
+}
+
+int checkboard(void)
+{
+ puts("Board: Wandboard\n");
+
+ return 0;
+}
diff --git a/boards.cfg b/boards.cfg
index 5fc70be..d7bda36 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -196,7 +196,8 @@ mx23_olinuxino arm arm926ejs mx23_olinuxino olimex
apx4devkit arm arm926ejs apx4devkit bluegiga mxs apx4devkit
mx23evk arm arm926ejs mx23evk freescale mxs mx23evk
m28evk arm arm926ejs m28evk denx mxs m28evk
-mx28evk arm arm926ejs mx28evk freescale mxs mx28evk
+mx28evk arm arm926ejs mx28evk freescale mxs mx28evk:ENV_IS_IN_MMC
+mx28evk_nand arm arm926ejs mx28evk freescale mxs mx28evk:ENV_IS_IN_NAND
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
@@ -264,6 +265,8 @@ nitrogen6q arm armv7 nitrogen6x boundar
nitrogen6q2g arm armv7 nitrogen6x boundary mx6 nitrogen6x:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6q2g.cfg,MX6Q,DDR_MB=2048
nitrogen6s arm armv7 nitrogen6x boundary mx6 nitrogen6x:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6s.cfg,MX6S,DDR_MB=512
nitrogen6s1g arm armv7 nitrogen6x boundary mx6 nitrogen6x:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6s1g.cfg,MX6S,DDR_MB=1024
+wandboard_dl arm armv7 wandboard - mx6 wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6dl.cfg,MX6DL,DDR_MB=1024
+wandboard_solo arm armv7 wandboard - mx6 wandboard:IMX_CONFIG=board/boundary/nitrogen6x/nitrogen6s.cfg,MX6S,DDR_MB=512
cm_t35 arm armv7 cm_t35 - omap3
omap3_overo arm armv7 overo - omap3
omap3_pandora arm armv7 pandora - omap3
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 5d2ce00..7438469 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -128,6 +128,9 @@ static boot_os_fn do_bootm_rtems;
#if defined(CONFIG_BOOTM_OSE)
static boot_os_fn do_bootm_ose;
#endif
+#if defined(CONFIG_BOOTM_PLAN9)
+static boot_os_fn do_bootm_plan9;
+#endif
#if defined(CONFIG_CMD_ELF)
static boot_os_fn do_bootm_vxworks;
static boot_os_fn do_bootm_qnxelf;
@@ -154,6 +157,9 @@ static boot_os_fn *boot_os[] = {
#if defined(CONFIG_BOOTM_OSE)
[IH_OS_OSE] = do_bootm_ose,
#endif
+#if defined(CONFIG_BOOTM_PLAN9)
+ [IH_OS_PLAN9] = do_bootm_plan9,
+#endif
#if defined(CONFIG_CMD_ELF)
[IH_OS_VXWORKS] = do_bootm_vxworks,
[IH_OS_QNX] = do_bootm_qnxelf,
@@ -1628,6 +1634,39 @@ static int do_bootm_ose(int flag, int argc, char * const argv[],
}
#endif /* CONFIG_BOOTM_OSE */
+#if defined(CONFIG_BOOTM_PLAN9)
+static int do_bootm_plan9(int flag, int argc, char * const argv[],
+ bootm_headers_t *images)
+{
+ void (*entry_point)(void);
+
+ if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
+ return 1;
+
+#if defined(CONFIG_FIT)
+ if (!images->legacy_hdr_valid) {
+ fit_unsupported_reset("Plan 9");
+ return 1;
+ }
+#endif
+
+ entry_point = (void (*)(void))images->ep;
+
+ printf("## Transferring control to Plan 9 (at address %08lx) ...\n",
+ (ulong)entry_point);
+
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+
+ /*
+ * Plan 9 Parameters:
+ * None
+ */
+ (*entry_point)();
+
+ return 1;
+}
+#endif /* CONFIG_BOOTM_PLAN9 */
+
#if defined(CONFIG_CMD_ELF)
static int do_bootm_vxworks(int flag, int argc, char * const argv[],
bootm_headers_t *images)
diff --git a/common/cmd_ext4.c b/common/cmd_ext4.c
index dcf76a5..706fd54 100644
--- a/common/cmd_ext4.c
+++ b/common/cmd_ext4.c
@@ -88,10 +88,10 @@ int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc,
dev = dev_desc->dev;
/* get the filename */
- filename = argv[3];
+ filename = argv[4];
/* get the address in hexadecimal format (string to int) */
- ram_address = simple_strtoul(argv[4], NULL, 16);
+ ram_address = simple_strtoul(argv[3], NULL, 16);
/* get the filesize in base 10 format */
file_size = simple_strtoul(argv[5], NULL, 10);
@@ -122,7 +122,7 @@ fail:
U_BOOT_CMD(ext4write, 6, 1, do_ext4_write,
"create a file in the root directory",
- "<interface> <dev[:part]> [Absolute filename path] [Address] [sizebytes]\n"
+ "<interface> <dev[:part]> <addr> <absolute filename path> [sizebytes]\n"
" - create a file in / directory");
#endif
diff --git a/common/cmd_sf.c b/common/cmd_sf.c
index b175358..3f0d414 100644
--- a/common/cmd_sf.c
+++ b/common/cmd_sf.c
@@ -369,8 +369,8 @@ static void spi_test_next_stage(struct test_info *test)
* @param vbuf Verification buffer
* @return 0 if ok, -1 on error
*/
-static int spi_flash_test(struct spi_flash *flash, char *buf, ulong len,
- ulong offset, char *vbuf)
+static int spi_flash_test(struct spi_flash *flash, uint8_t *buf, ulong len,
+ ulong offset, uint8_t *vbuf)
{
struct test_info test;
int i;
@@ -431,9 +431,9 @@ static int do_spi_flash_test(int argc, char * const argv[])
{
unsigned long offset;
unsigned long len;
- char *buf = (char *)CONFIG_SYS_TEXT_BASE;
+ uint8_t *buf = (uint8_t *)CONFIG_SYS_TEXT_BASE;
char *endp;
- char *vbuf;
+ uint8_t *vbuf;
int ret;
offset = simple_strtoul(argv[1], &endp, 16);
diff --git a/common/env_callback.c b/common/env_callback.c
index 78ca367..78aafb4 100644
--- a/common/env_callback.c
+++ b/common/env_callback.c
@@ -31,7 +31,7 @@ DECLARE_GLOBAL_DATA_PTR;
/*
* Look up a callback function pointer by name
*/
-struct env_clbk_tbl *find_env_callback(const char *name)
+static struct env_clbk_tbl *find_env_callback(const char *name)
{
struct env_clbk_tbl *clbkp;
int i;
diff --git a/common/image.c b/common/image.c
index 6afbb40..60c2127 100644
--- a/common/image.c
+++ b/common/image.c
@@ -108,6 +108,7 @@ static const table_entry_t uimage_os[] = {
#endif
{ IH_OS_NETBSD, "netbsd", "NetBSD", },
{ IH_OS_OSE, "ose", "Enea OSE", },
+ { IH_OS_PLAN9, "plan9", "Plan 9", },
{ IH_OS_RTEMS, "rtems", "RTEMS", },
{ IH_OS_U_BOOT, "u-boot", "U-Boot", },
#if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC)
diff --git a/doc/README.mx28evk b/doc/README.mx28evk
index 2fc5069..76db474 100644
--- a/doc/README.mx28evk
+++ b/doc/README.mx28evk
@@ -23,6 +23,24 @@ To boot MX28EVK from an SD card, set the boot mode DIP switches as:
* VDD 5V: To the left (off)
* Hold Button: Down (off)
+
+Environment Storage
+-------------------
+
+There are two targets for mx28evk:
+
+"make mx28evk_config" - store enviroment variables into MMC
+
+or
+
+"make mx28evk_nand_config" - store enviroment variables into NAND flash
+
+Choose the target accordingly.
+
+Note: The mx28evk board does not come with a NAND flash populated from the
+factory. It comes with an empty slot (U23), which allows the insertion of a
+48-pin TSOP flash device.
+
Follow the instructions from doc/README.mx28_common to generate a bootable SD
card.
diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c
index b0afc3c..54cfabf 100644
--- a/drivers/mmc/bcm2835_sdhci.c
+++ b/drivers/mmc/bcm2835_sdhci.c
@@ -39,6 +39,7 @@
#include <common.h>
#include <malloc.h>
#include <sdhci.h>
+#include <asm/arch/timer.h>
/* 400KHz is max freq for card ID etc. Use that as min */
#define MIN_FREQ 400000
@@ -67,11 +68,11 @@ static inline void bcm2835_sdhci_raw_writel(struct sdhci_host *host, u32 val,
* (Which is just as well - otherwise we'd have to nobble the DMA engine
* too)
*/
- while (get_timer(bcm_host->last_write) < bcm_host->twoticks_delay)
+ while (get_timer_us(bcm_host->last_write) < bcm_host->twoticks_delay)
;
writel(val, host->ioaddr + reg);
- bcm_host->last_write = get_timer(0);
+ bcm_host->last_write = get_timer_us(0);
}
static inline u32 bcm2835_sdhci_raw_readl(struct sdhci_host *host, int reg)
diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c
index 54b5363..35f879e 100644
--- a/drivers/mmc/fsl_esdhc.c
+++ b/drivers/mmc/fsl_esdhc.c
@@ -580,6 +580,13 @@ int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT | MMC_MODE_HC;
+ if (cfg->max_bus_width > 0) {
+ if (cfg->max_bus_width < 8)
+ mmc->host_caps &= ~MMC_MODE_8BIT;
+ if (cfg->max_bus_width < 4)
+ mmc->host_caps &= ~MMC_MODE_4BIT;
+ }
+
if (caps & ESDHC_HOSTCAPBLT_HSS)
mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
diff --git a/drivers/mtd/spi/atmel.c b/drivers/mtd/spi/atmel.c
index 006f6d5..6a92c4b 100644
--- a/drivers/mtd/spi/atmel.c
+++ b/drivers/mtd/spi/atmel.c
@@ -480,15 +480,13 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)
return NULL;
}
- asf = malloc(sizeof(struct atmel_spi_flash));
+ asf = spi_flash_alloc(struct atmel_spi_flash, spi, params->name);
if (!asf) {
debug("SF: Failed to allocate memory\n");
return NULL;
}
asf->params = params;
- asf->flash.spi = spi;
- asf->flash.name = params->name;
/* Assuming power-of-two page size initially. */
page_size = 1 << params->l2_page_size;
@@ -513,7 +511,6 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)
asf->flash.erase = dataflash_erase_at45;
page_size += 1 << (params->l2_page_size - 5);
} else {
- asf->flash.read = spi_flash_cmd_read_fast;
asf->flash.write = dataflash_write_p2;
asf->flash.erase = dataflash_erase_p2;
}
@@ -524,9 +521,6 @@ struct spi_flash *spi_flash_probe_atmel(struct spi_slave *spi, u8 *idcode)
case DF_FAMILY_AT26F:
case DF_FAMILY_AT26DF:
- asf->flash.read = spi_flash_cmd_read_fast;
- asf->flash.write = spi_flash_cmd_write_multi;
- asf->flash.erase = spi_flash_cmd_erase;
asf->flash.page_size = page_size;
asf->flash.sector_size = 4096;
/* clear SPRL# bit for locked flash */
diff --git a/drivers/mtd/spi/eon.c b/drivers/mtd/spi/eon.c
index 691ed4e..b16e7ab 100644
--- a/drivers/mtd/spi/eon.c
+++ b/drivers/mtd/spi/eon.c
@@ -46,18 +46,12 @@ struct spi_flash *spi_flash_probe_eon(struct spi_slave *spi, u8 *idcode)
return NULL;
}
- flash = malloc(sizeof(*flash));
+ flash = spi_flash_alloc_base(spi, params->name);
if (!flash) {
debug("SF: Failed to allocate memory\n");
return NULL;
}
- flash->spi = spi;
- flash->name = params->name;
-
- flash->write = spi_flash_cmd_write_multi;
- flash->erase = spi_flash_cmd_erase;
- flash->read = spi_flash_cmd_read_fast;
flash->page_size = 256;
flash->sector_size = 256 * 16 * 16;
flash->size = 256 * 16
diff --git a/drivers/mtd/spi/macronix.c b/drivers/mtd/spi/macronix.c
index c97a39d..036c30d 100644
--- a/drivers/mtd/spi/macronix.c
+++ b/drivers/mtd/spi/macronix.c
@@ -97,18 +97,12 @@ struct spi_flash *spi_flash_probe_macronix(struct spi_slave *spi, u8 *idcode)
return NULL;
}
- flash = malloc(sizeof(*flash));
+ flash = spi_flash_alloc_base(spi, params->name);
if (!flash) {
debug("SF: Failed to allocate memory\n");
return NULL;
}
- flash->spi = spi;
- flash->name = params->name;
-
- flash->write = spi_flash_cmd_write_multi;
- flash->erase = spi_flash_cmd_erase;
- flash->read = spi_flash_cmd_read_fast;
flash->page_size = 256;
flash->sector_size = 256 * 16 * 16;
flash->size = flash->sector_size * params->nr_blocks;
diff --git a/drivers/mtd/spi/ramtron.c b/drivers/mtd/spi/ramtron.c
index 0999781..5299a6d 100644
--- a/drivers/mtd/spi/ramtron.c
+++ b/drivers/mtd/spi/ramtron.c
@@ -284,15 +284,13 @@ struct spi_flash *spi_fram_probe_ramtron(struct spi_slave *spi, u8 *idcode)
return NULL;
found:
- sn = malloc(sizeof(*sn));
+ sn = spi_flash_alloc(struct ramtron_spi_fram, spi, params->name);
if (!sn) {
debug("SF: Failed to allocate memory\n");
return NULL;
}
sn->params = params;
- sn->flash.spi = spi;
- sn->flash.name = params->name;
sn->flash.write = ramtron_write;
sn->flash.read = ramtron_read;
diff --git a/drivers/mtd/spi/spansion.c b/drivers/mtd/spi/spansion.c
index 9288672..bc558c4 100644
--- a/drivers/mtd/spi/spansion.c
+++ b/drivers/mtd/spi/spansion.c
@@ -128,18 +128,12 @@ struct spi_flash *spi_flash_probe_spansion(struct spi_slave *spi, u8 *idcode)
return NULL;
}
- flash = malloc(sizeof(*flash));
+ flash = spi_flash_alloc_base(spi, params->name);
if (!flash) {
debug("SF: Failed to allocate memory\n");
return NULL;
}
- flash->spi = spi;
- flash->name = params->name;
-
- flash->write = spi_flash_cmd_write_multi;
- flash->erase = spi_flash_cmd_erase;
- flash->read = spi_flash_cmd_read_fast;
flash->page_size = 256;
flash->sector_size = 256 * params->pages_per_sector;
flash->size = flash->sector_size * params->nr_sectors;
diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
index 00aece9..111185a 100644
--- a/drivers/mtd/spi/spi_flash.c
+++ b/drivers/mtd/spi/spi_flash.c
@@ -8,6 +8,7 @@
*/
#include <common.h>
+#include <fdtdec.h>
#include <malloc.h>
#include <spi.h>
#include <spi_flash.h>
@@ -15,6 +16,8 @@
#include "spi_flash_internal.h"
+DECLARE_GLOBAL_DATA_PTR;
+
static void spi_flash_addr(u32 addr, u8 *cmd)
{
/* cmd[0] is actual command */
@@ -87,6 +90,9 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,
for (actual = 0; actual < len; actual += chunk_len) {
chunk_len = min(len - actual, page_size - byte_addr);
+ if (flash->spi->max_write_size)
+ chunk_len = min(chunk_len, flash->spi->max_write_size);
+
cmd[1] = page_addr >> 8;
cmd[2] = page_addr;
cmd[3] = byte_addr;
@@ -111,8 +117,11 @@ int spi_flash_cmd_write_multi(struct spi_flash *flash, u32 offset,
if (ret)
break;
- page_addr++;
- byte_addr = 0;
+ byte_addr += chunk_len;
+ if (byte_addr == page_size) {
+ page_addr++;
+ byte_addr = 0;
+ }
}
debug("SF: program %s %zu bytes @ %#x\n",
@@ -140,6 +149,10 @@ int spi_flash_cmd_read_fast(struct spi_flash *flash, u32 offset,
{
u8 cmd[5];
+ /* Handle memory-mapped SPI */
+ if (flash->memory_map)
+ memcpy(data, flash->memory_map + offset, len);
+
cmd[0] = CMD_READ_ARRAY_FAST;
spi_flash_addr(offset, cmd);
cmd[4] = 0x00;
@@ -269,6 +282,34 @@ int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr)
return 0;
}
+#ifdef CONFIG_OF_CONTROL
+int spi_flash_decode_fdt(const void *blob, struct spi_flash *flash)
+{
+ fdt_addr_t addr;
+ fdt_size_t size;
+ int node;
+
+ /* If there is no node, do nothing */
+ node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH);
+ if (node < 0)
+ return 0;
+
+ addr = fdtdec_get_addr_size(blob, node, "memory-map", &size);
+ if (addr == FDT_ADDR_T_NONE) {
+ debug("%s: Cannot decode address\n", __func__);
+ return 0;
+ }
+
+ if (flash->size != size) {
+ debug("%s: Memory map must cover entire device\n", __func__);
+ return -1;
+ }
+ flash->memory_map = (void *)addr;
+
+ return 0;
+}
+#endif /* CONFIG_OF_CONTROL */
+
/*
* The following table holds all device probe functions
*
@@ -385,9 +426,18 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
goto err_manufacturer_probe;
}
+#ifdef CONFIG_OF_CONTROL
+ if (spi_flash_decode_fdt(gd->fdt_blob, flash)) {
+ debug("SF: FDT decode error\n");
+ goto err_manufacturer_probe;
+ }
+#endif
printf("SF: Detected %s with page size ", flash->name);
print_size(flash->sector_size, ", total ");
- print_size(flash->size, "\n");
+ print_size(flash->size, "");
+ if (flash->memory_map)
+ printf(", mapped at %p", flash->memory_map);
+ puts("\n");
spi_release_bus(spi);
@@ -401,6 +451,31 @@ err_claim_bus:
return NULL;
}
+void *spi_flash_do_alloc(int offset, int size, struct spi_slave *spi,
+ const char *name)
+{
+ struct spi_flash *flash;
+ void *ptr;
+
+ ptr = malloc(size);
+ if (!ptr) {
+ debug("SF: Failed to allocate memory\n");
+ return NULL;
+ }
+ memset(ptr, '\0', size);
+ flash = (struct spi_flash *)(ptr + offset);
+
+ /* Set up some basic fields - caller will sort out sizes */
+ flash->spi = spi;
+ flash->name = name;
+
+ flash->read = spi_flash_cmd_read_fast;
+ flash->write = spi_flash_cmd_write_multi;
+ flash->erase = spi_flash_cmd_erase;
+
+ return flash;
+}
+
void spi_flash_free(struct spi_flash *flash)
{
spi_free_slave(flash->spi);
diff --git a/drivers/mtd/spi/sst.c b/drivers/mtd/spi/sst.c
index ced4f24..95f5490 100644
--- a/drivers/mtd/spi/sst.c
+++ b/drivers/mtd/spi/sst.c
@@ -203,22 +203,16 @@ spi_flash_probe_sst(struct spi_slave *spi, u8 *idcode)
return NULL;
}
- stm = malloc(sizeof(*stm));
+ stm = spi_flash_alloc(struct sst_spi_flash, spi, params->name);
if (!stm) {
debug("SF: Failed to allocate memory\n");
return NULL;
}
stm->params = params;
- stm->flash.spi = spi;
- stm->flash.name = params->name;
if (stm->params->flags & SST_FEAT_WP)
stm->flash.write = sst_write_wp;
- else
- stm->flash.write = spi_flash_cmd_write_multi;
- stm->flash.erase = spi_flash_cmd_erase;
- stm->flash.read = spi_flash_cmd_read_fast;
stm->flash.page_size = 256;
stm->flash.sector_size = 4096;
stm->flash.size = stm->flash.sector_size * params->nr_sectors;
diff --git a/drivers/mtd/spi/stmicro.c b/drivers/mtd/spi/stmicro.c
index 8a19344..2a9972b 100644
--- a/drivers/mtd/spi/stmicro.c
+++ b/drivers/mtd/spi/stmicro.c
@@ -176,18 +176,12 @@ struct spi_flash *spi_flash_probe_stmicro(struct spi_slave *spi, u8 * idcode)
return NULL;
}
- flash = malloc(sizeof(*flash));
+ flash = spi_flash_alloc_base(spi, params->name);
if (!flash) {
debug("SF: Failed to allocate memory\n");
return NULL;
}
- flash->spi = spi;
- flash->name = params->name;
-
- flash->write = spi_flash_cmd_write_multi;
- flash->erase = spi_flash_cmd_erase;
- flash->read = spi_flash_cmd_read_fast;
flash->page_size = 256;
flash->sector_size = 256 * params->pages_per_sector;
flash->size = flash->sector_size * params->nr_sectors;
diff --git a/drivers/mtd/spi/winbond.c b/drivers/mtd/spi/winbond.c
index 3560fcb..2716209 100644
--- a/drivers/mtd/spi/winbond.c
+++ b/drivers/mtd/spi/winbond.c
@@ -97,18 +97,12 @@ struct spi_flash *spi_flash_probe_winbond(struct spi_slave *spi, u8 *idcode)
return NULL;
}
- flash = malloc(sizeof(*flash));
+ flash = spi_flash_alloc_base(spi, params->name);
if (!flash) {
debug("SF: Failed to allocate memory\n");
return NULL;
}
- flash->spi = spi;
- flash->name = params->name;
-
- flash->write = spi_flash_cmd_write_multi;
- flash->erase = spi_flash_cmd_erase;
- flash->read = spi_flash_cmd_read_fast;
flash->page_size = 256;
flash->sector_size = 4096;
flash->size = 4096 * 16 * params->nr_blocks;
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 46e8fa3..d08609e 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -25,6 +25,9 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libspi.o
+# There are many options which enable SPI, so make this library available
+COBJS-y += spi.o
+
COBJS-$(CONFIG_ALTERA_SPI) += altera_spi.o
COBJS-$(CONFIG_ANDES_SPI) += andes_spi.o
COBJS-$(CONFIG_ARMADA100_SPI) += armada100_spi.o
@@ -36,6 +39,7 @@ COBJS-$(CONFIG_CF_SPI) += cf_spi.o
COBJS-$(CONFIG_CF_QSPI) += cf_qspi.o
COBJS-$(CONFIG_DAVINCI_SPI) += davinci_spi.o
COBJS-$(CONFIG_EXYNOS_SPI) += exynos_spi.o
+COBJS-$(CONFIG_ICH_SPI) += ich.o
COBJS-$(CONFIG_KIRKWOOD_SPI) += kirkwood_spi.o
COBJS-$(CONFIG_MPC52XX_SPI) += mpc52xx_spi.o
COBJS-$(CONFIG_MPC8XXX_SPI) += mpc8xxx_spi.o
diff --git a/drivers/spi/altera_spi.c b/drivers/spi/altera_spi.c
index 138d6f4..b53607a 100644
--- a/drivers/spi/altera_spi.c
+++ b/drivers/spi/altera_spi.c
@@ -83,12 +83,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (!spi_cs_is_valid(bus, cs))
return NULL;
- altspi = malloc(sizeof(*altspi));
+ altspi = spi_alloc_slave(struct altera_spi_slave, bus, cs);
if (!altspi)
return NULL;
- altspi->slave.bus = bus;
- altspi->slave.cs = cs;
altspi->base = altera_spi_base_list[bus];
debug("%s: bus:%i cs:%i base:%lx\n", __func__,
bus, cs, altspi->base);
diff --git a/drivers/spi/andes_spi.c b/drivers/spi/andes_spi.c
index fdde139..c56377b 100644
--- a/drivers/spi/andes_spi.c
+++ b/drivers/spi/andes_spi.c
@@ -53,12 +53,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (!spi_cs_is_valid(bus, cs))
return NULL;
- ds = malloc(sizeof(*ds));
+ ds = spi_alloc_slave(struct andes_spi_slave, bus, cs);
if (!ds)
return NULL;
- ds->slave.bus = bus;
- ds->slave.cs = cs;
ds->regs = (struct andes_spi_regs *)CONFIG_SYS_SPI_BASE;
/*
diff --git a/drivers/spi/armada100_spi.c b/drivers/spi/armada100_spi.c
index 7384c9c..afdbe05 100644
--- a/drivers/spi/armada100_spi.c
+++ b/drivers/spi/armada100_spi.c
@@ -120,12 +120,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
{
struct armd_spi_slave *pss;
- pss = malloc(sizeof(*pss));
+ pss = spi_alloc_slave(struct armd_spi_slave, bus, cs);
if (!pss)
return NULL;
- pss->slave.bus = bus;
- pss->slave.cs = cs;
pss->spi_reg = (struct ssp_reg *)SSP_REG_BASE(CONFIG_SYS_SSP_PORT);
pss->cr0 = SSCR0_MOTO | SSCR0_DATASIZE(DEFAULT_WORD_LEN) | SSCR0_SSE;
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index ce7d460..f4b1bad 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -84,12 +84,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (mode & SPI_CPOL)
csrx |= ATMEL_SPI_CSRx_CPOL;
- as = malloc(sizeof(struct atmel_spi_slave));
+ as = spi_alloc_slave(struct atmel_spi_slave, bus, cs);
if (!as)
return NULL;
- as->slave.bus = bus;
- as->slave.cs = cs;
as->regs = regs;
as->mr = ATMEL_SPI_MR_MSTR | ATMEL_SPI_MR_MODFDIS
#if defined(CONFIG_AT91SAM9X5) || defined(CONFIG_AT91SAM9M10G45)
diff --git a/drivers/spi/bfin_spi.c b/drivers/spi/bfin_spi.c
index e080bec..ab2e8b9 100644
--- a/drivers/spi/bfin_spi.c
+++ b/drivers/spi/bfin_spi.c
@@ -182,12 +182,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
default: return NULL;
}
- bss = malloc(sizeof(*bss));
+ bss = spi_alloc_slave(struct bfin_spi_slave, bus, cs);
if (!bss)
return NULL;
- bss->slave.bus = bus;
- bss->slave.cs = cs;
bss->mmr_base = (void *)mmr_base;
bss->ctl = SPE | MSTR | TDBR_CORE;
if (mode & SPI_CPHA) bss->ctl |= CPHA;
diff --git a/drivers/spi/bfin_spi6xx.c b/drivers/spi/bfin_spi6xx.c
index fde3447..c25c4a9 100644
--- a/drivers/spi/bfin_spi6xx.c
+++ b/drivers/spi/bfin_spi6xx.c
@@ -178,12 +178,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
return NULL;
}
- bss = malloc(sizeof(*bss));
+ bss = spi_alloc_slave(struct bfin_spi_slave, bus, cs);
if (!bss)
return NULL;
- bss->slave.bus = bus;
- bss->slave.cs = cs;
bss->regs = (struct bfin_spi_regs *)reg_base;
bss->control = SPI_CTL_EN | SPI_CTL_MSTR;
if (mode & SPI_CPHA)
diff --git a/drivers/spi/cf_qspi.c b/drivers/spi/cf_qspi.c
index 72dd1a5..a37ac4e 100644
--- a/drivers/spi/cf_qspi.c
+++ b/drivers/spi/cf_qspi.c
@@ -120,13 +120,11 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (!spi_cs_is_valid(bus, cs))
return NULL;
- dev = malloc(sizeof(struct cf_qspi_slave));
+ dev = spi_alloc_slave(struct cf_qspi_slave, bus, cs);
if (!dev)
return NULL;
/* Initialize to known value */
- dev->slave.bus = bus;
- dev->slave.cs = cs;
dev->regs = (qspi_t *)MMAP_QSPI;
dev->qmr = 0;
dev->qwr = 0;
diff --git a/drivers/spi/cf_spi.c b/drivers/spi/cf_spi.c
index a883da9..afe7917 100644
--- a/drivers/spi/cf_spi.c
+++ b/drivers/spi/cf_spi.c
@@ -330,12 +330,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (!spi_cs_is_valid(bus, cs))
return NULL;
- cfslave = malloc(sizeof(struct cf_spi_slave));
+ cfslave = spi_alloc_slave(struct cf_spi_slave, bus, cs);
if (!cfslave)
return NULL;
- cfslave->slave.bus = bus;
- cfslave->slave.cs = cs;
cfslave->baudrate = max_hz;
/* specific setup */
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c
index 13aca52..74792af 100644
--- a/drivers/spi/davinci_spi.c
+++ b/drivers/spi/davinci_spi.c
@@ -44,12 +44,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (!spi_cs_is_valid(bus, cs))
return NULL;
- ds = malloc(sizeof(*ds));
+ ds = spi_alloc_slave(struct davinci_spi_slave, bus, cs);
if (!ds)
return NULL;
- ds->slave.bus = bus;
- ds->slave.cs = cs;
ds->regs = (struct davinci_spi_regs *)CONFIG_SYS_SPI_BASE;
ds->freq = max_hz;
diff --git a/drivers/spi/exynos_spi.c b/drivers/spi/exynos_spi.c
index 2260d59..607e1cd 100644
--- a/drivers/spi/exynos_spi.c
+++ b/drivers/spi/exynos_spi.c
@@ -89,15 +89,13 @@ struct spi_slave *spi_setup_slave(unsigned int busnum, unsigned int cs,
return NULL;
}
- spi_slave = malloc(sizeof(*spi_slave));
+ spi_slave = spi_alloc_slave(struct exynos_spi_slave, busnum, cs);
if (!spi_slave) {
debug("%s: Could not allocate spi_slave\n", __func__);
return NULL;
}
bus = &spi_bus[busnum];
- spi_slave->slave.bus = busnum;
- spi_slave->slave.cs = cs;
spi_slave->regs = bus->regs;
spi_slave->mode = mode;
spi_slave->periph_id = bus->periph_id;
diff --git a/drivers/spi/fsl_espi.c b/drivers/spi/fsl_espi.c
index eb99e90..28609ee 100644
--- a/drivers/spi/fsl_espi.c
+++ b/drivers/spi/fsl_espi.c
@@ -79,12 +79,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (!spi_cs_is_valid(bus, cs))
return NULL;
- fsl = malloc(sizeof(struct fsl_spi_slave));
+ fsl = spi_alloc_slave(struct fsl_spi_slave, bus, cs);
if (!fsl)
return NULL;
- fsl->slave.bus = bus;
- fsl->slave.cs = cs;
fsl->mode = mode;
fsl->max_transfer_length = ESPI_MAX_DATA_TRANSFER_LEN;
diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
new file mode 100644
index 0000000..8865df5
--- /dev/null
+++ b/drivers/spi/ich.c
@@ -0,0 +1,754 @@
+/*
+ * Copyright (c) 2011-12 The Chromium OS Authors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * This file is derived from the flashrom project.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <spi.h>
+#include <pci.h>
+#include <pci_ids.h>
+#include <asm/io.h>
+
+#include "ich.h"
+
+#define SPI_OPCODE_WREN 0x06
+#define SPI_OPCODE_FAST_READ 0x0b
+
+struct ich_ctlr {
+ pci_dev_t dev; /* PCI device number */
+ int ich_version; /* Controller version, 7 or 9 */
+ int ichspi_lock;
+ int locked;
+ uint8_t *opmenu;
+ int menubytes;
+ void *base; /* Base of register set */
+ uint16_t *preop;
+ uint16_t *optype;
+ uint32_t *addr;
+ uint8_t *data;
+ unsigned databytes;
+ uint8_t *status;
+ uint16_t *control;
+ uint32_t *bbar;
+ uint32_t *pr; /* only for ich9 */
+ uint8_t *speed; /* pointer to speed control */
+ ulong max_speed; /* Maximum bus speed in MHz */
+};
+
+struct ich_ctlr ctlr;
+
+static inline struct ich_spi_slave *to_ich_spi(struct spi_slave *slave)
+{
+ return container_of(slave, struct ich_spi_slave, slave);
+}
+
+static unsigned int ich_reg(const void *addr)
+{
+ return (unsigned)(addr - ctlr.base) & 0xffff;
+}
+
+static u8 ich_readb(const void *addr)
+{
+ u8 value = readb(addr);
+
+ debug("read %2.2x from %4.4x\n", value, ich_reg(addr));
+
+ return value;
+}
+
+static u16 ich_readw(const void *addr)
+{
+ u16 value = readw(addr);
+
+ debug("read %4.4x from %4.4x\n", value, ich_reg(addr));
+
+ return value;
+}
+
+static u32 ich_readl(const void *addr)
+{
+ u32 value = readl(addr);
+
+ debug("read %8.8x from %4.4x\n", value, ich_reg(addr));
+
+ return value;
+}
+
+static void ich_writeb(u8 value, void *addr)
+{
+ writeb(value, addr);
+ debug("wrote %2.2x to %4.4x\n", value, ich_reg(addr));
+}
+
+static void ich_writew(u16 value, void *addr)
+{
+ writew(value, addr);
+ debug("wrote %4.4x to %4.4x\n", value, ich_reg(addr));
+}
+
+static void ich_writel(u32 value, void *addr)
+{
+ writel(value, addr);
+ debug("wrote %8.8x to %4.4x\n", value, ich_reg(addr));
+}
+
+static void write_reg(const void *value, void *dest, uint32_t size)
+{
+ memcpy_toio(dest, value, size);
+}
+
+static void read_reg(const void *src, void *value, uint32_t size)
+{
+ memcpy_fromio(value, src, size);
+}
+
+static void ich_set_bbar(struct ich_ctlr *ctlr, uint32_t minaddr)
+{
+ const uint32_t bbar_mask = 0x00ffff00;
+ uint32_t ichspi_bbar;
+
+ minaddr &= bbar_mask;
+ ichspi_bbar = ich_readl(ctlr->bbar) & ~bbar_mask;
+ ichspi_bbar |= minaddr;
+ ich_writel(ichspi_bbar, ctlr->bbar);
+}
+
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+ puts("spi_cs_is_valid used but not implemented\n");
+ return 0;
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+ unsigned int max_hz, unsigned int mode)
+{
+ struct ich_spi_slave *ich;
+
+ ich = spi_alloc_slave(struct ich_spi_slave, bus, cs);
+ if (!ich) {
+ puts("ICH SPI: Out of memory\n");
+ return NULL;
+ }
+
+ /*
+ * Yes this controller can only write a small number of bytes at
+ * once! The limit is typically 64 bytes.
+ */
+ ich->slave.max_write_size = ctlr.databytes;
+ ich->speed = max_hz;
+
+ return &ich->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+ struct ich_spi_slave *ich = to_ich_spi(slave);
+
+ free(ich);
+}
+
+/*
+ * Check if this device ID matches one of supported Intel PCH devices.
+ *
+ * Return the ICH version if there is a match, or zero otherwise.
+ */
+static int get_ich_version(uint16_t device_id)
+{
+ if (device_id == PCI_DEVICE_ID_INTEL_TGP_LPC)
+ return 7;
+
+ if ((device_id >= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN &&
+ device_id <= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX) ||
+ (device_id >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN &&
+ device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX))
+ return 9;
+
+ return 0;
+}
+
+/* @return 1 if the SPI flash supports the 33MHz speed */
+static int ich9_can_do_33mhz(pci_dev_t dev)
+{
+ u32 fdod, speed;
+
+ /* Observe SPI Descriptor Component Section 0 */
+ pci_write_config_dword(dev, 0xb0, 0x1000);
+
+ /* Extract the Write/Erase SPI Frequency from descriptor */
+ pci_read_config_dword(dev, 0xb4, &fdod);
+
+ /* Bits 23:21 have the fast read clock frequency, 0=20MHz, 1=33MHz */
+ speed = (fdod >> 21) & 7;
+
+ return speed == 1;
+}
+
+static int ich_find_spi_controller(pci_dev_t *devp, int *ich_versionp)
+{
+ int last_bus = pci_last_busno();
+ int bus;
+
+ if (last_bus == -1) {
+ debug("No PCI busses?\n");
+ return -1;
+ }
+
+ for (bus = 0; bus <= last_bus; bus++) {
+ uint16_t vendor_id, device_id;
+ uint32_t ids;
+ pci_dev_t dev;
+
+ dev = PCI_BDF(bus, 31, 0);
+ pci_read_config_dword(dev, 0, &ids);
+ vendor_id = ids;
+ device_id = ids >> 16;
+
+ if (vendor_id == PCI_VENDOR_ID_INTEL) {
+ *devp = dev;
+ *ich_versionp = get_ich_version(device_id);
+ return 0;
+ }
+ }
+
+ debug("ICH SPI: No ICH found.\n");
+ return -1;
+}
+
+static int ich_init_controller(struct ich_ctlr *ctlr)
+{
+ uint8_t *rcrb; /* Root Complex Register Block */
+ uint32_t rcba; /* Root Complex Base Address */
+
+ pci_read_config_dword(ctlr->dev, 0xf0, &rcba);
+ /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */
+ rcrb = (uint8_t *)(rcba & 0xffffc000);
+ if (ctlr->ich_version == 7) {
+ struct ich7_spi_regs *ich7_spi;
+
+ ich7_spi = (struct ich7_spi_regs *)(rcrb + 0x3020);
+ ctlr->ichspi_lock = ich_readw(&ich7_spi->spis) & SPIS_LOCK;
+ ctlr->opmenu = ich7_spi->opmenu;
+ ctlr->menubytes = sizeof(ich7_spi->opmenu);
+ ctlr->optype = &ich7_spi->optype;
+ ctlr->addr = &ich7_spi->spia;
+ ctlr->data = (uint8_t *)ich7_spi->spid;
+ ctlr->databytes = sizeof(ich7_spi->spid);
+ ctlr->status = (uint8_t *)&ich7_spi->spis;
+ ctlr->control = &ich7_spi->spic;
+ ctlr->bbar = &ich7_spi->bbar;
+ ctlr->preop = &ich7_spi->preop;
+ ctlr->base = ich7_spi;
+ } else if (ctlr->ich_version == 9) {
+ struct ich9_spi_regs *ich9_spi;
+
+ ich9_spi = (struct ich9_spi_regs *)(rcrb + 0x3800);
+ ctlr->ichspi_lock = ich_readw(&ich9_spi->hsfs) & HSFS_FLOCKDN;
+ ctlr->opmenu = ich9_spi->opmenu;
+ ctlr->menubytes = sizeof(ich9_spi->opmenu);
+ ctlr->optype = &ich9_spi->optype;
+ ctlr->addr = &ich9_spi->faddr;
+ ctlr->data = (uint8_t *)ich9_spi->fdata;
+ ctlr->databytes = sizeof(ich9_spi->fdata);
+ ctlr->status = &ich9_spi->ssfs;
+ ctlr->control = (uint16_t *)ich9_spi->ssfc;
+ ctlr->speed = ich9_spi->ssfc + 2;
+ ctlr->bbar = &ich9_spi->bbar;
+ ctlr->preop = &ich9_spi->preop;
+ ctlr->pr = &ich9_spi->pr[0];
+ ctlr->base = ich9_spi;
+ } else {
+ debug("ICH SPI: Unrecognized ICH version %d.\n",
+ ctlr->ich_version);
+ return -1;
+ }
+ debug("ICH SPI: Version %d detected\n", ctlr->ich_version);
+
+ /* Work out the maximum speed we can support */
+ ctlr->max_speed = 20000000;
+ if (ctlr->ich_version == 9 && ich9_can_do_33mhz(ctlr->dev))
+ ctlr->max_speed = 33000000;
+
+ ich_set_bbar(ctlr, 0);
+
+ return 0;
+}
+
+void spi_init(void)
+{
+ uint8_t bios_cntl;
+
+ if (ich_find_spi_controller(&ctlr.dev, &ctlr.ich_version)) {
+ printf("ICH SPI: Cannot find device\n");
+ return;
+ }
+
+ if (ich_init_controller(&ctlr)) {
+ printf("ICH SPI: Cannot setup controller\n");
+ return;
+ }
+
+ /*
+ * Disable the BIOS write protect so write commands are allowed. On
+ * v9, deassert SMM BIOS Write Protect Disable.
+ */
+ pci_read_config_byte(ctlr.dev, 0xdc, &bios_cntl);
+ if (ctlr.ich_version == 9)
+ bios_cntl &= ~(1 << 5);
+ pci_write_config_byte(ctlr.dev, 0xdc, bios_cntl | 0x1);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+ /* Handled by ICH automatically. */
+ return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+ /* Handled by ICH automatically. */
+}
+
+void spi_cs_activate(struct spi_slave *slave)
+{
+ /* Handled by ICH automatically. */
+}
+
+void spi_cs_deactivate(struct spi_slave *slave)
+{
+ /* Handled by ICH automatically. */
+}
+
+static inline void spi_use_out(struct spi_trans *trans, unsigned bytes)
+{
+ trans->out += bytes;
+ trans->bytesout -= bytes;
+}
+
+static inline void spi_use_in(struct spi_trans *trans, unsigned bytes)
+{
+ trans->in += bytes;
+ trans->bytesin -= bytes;
+}
+
+static void spi_setup_type(struct spi_trans *trans, int data_bytes)
+{
+ trans->type = 0xFF;
+
+ /* Try to guess spi type from read/write sizes. */
+ if (trans->bytesin == 0) {
+ if (trans->bytesout + data_bytes > 4)
+ /*
+ * If bytesin = 0 and bytesout > 4, we presume this is
+ * a write data operation, which is accompanied by an
+ * address.
+ */
+ trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;
+ else
+ trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS;
+ return;
+ }
+
+ if (trans->bytesout == 1) { /* and bytesin is > 0 */
+ trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS;
+ return;
+ }
+
+ if (trans->bytesout == 4) /* and bytesin is > 0 */
+ trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
+
+ /* Fast read command is called with 5 bytes instead of 4 */
+ if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) {
+ trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
+ --trans->bytesout;
+ }
+}
+
+static int spi_setup_opcode(struct spi_trans *trans)
+{
+ uint16_t optypes;
+ uint8_t opmenu[ctlr.menubytes];
+
+ trans->opcode = trans->out[0];
+ spi_use_out(trans, 1);
+ if (!ctlr.ichspi_lock) {
+ /* The lock is off, so just use index 0. */
+ ich_writeb(trans->opcode, ctlr.opmenu);
+ optypes = ich_readw(ctlr.optype);
+ optypes = (optypes & 0xfffc) | (trans->type & 0x3);
+ ich_writew(optypes, ctlr.optype);
+ return 0;
+ } else {
+ /* The lock is on. See if what we need is on the menu. */
+ uint8_t optype;
+ uint16_t opcode_index;
+
+ /* Write Enable is handled as atomic prefix */
+ if (trans->opcode == SPI_OPCODE_WREN)
+ return 0;
+
+ read_reg(ctlr.opmenu, opmenu, sizeof(opmenu));
+ for (opcode_index = 0; opcode_index < ctlr.menubytes;
+ opcode_index++) {
+ if (opmenu[opcode_index] == trans->opcode)
+ break;
+ }
+
+ if (opcode_index == ctlr.menubytes) {
+ printf("ICH SPI: Opcode %x not found\n",
+ trans->opcode);
+ return -1;
+ }
+
+ optypes = ich_readw(ctlr.optype);
+ optype = (optypes >> (opcode_index * 2)) & 0x3;
+ if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS &&
+ optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS &&
+ trans->bytesout >= 3) {
+ /* We guessed wrong earlier. Fix it up. */
+ trans->type = optype;
+ }
+ if (optype != trans->type) {
+ printf("ICH SPI: Transaction doesn't fit type %d\n",
+ optype);
+ return -1;
+ }
+ return opcode_index;
+ }
+}
+
+static int spi_setup_offset(struct spi_trans *trans)
+{
+ /* Separate the SPI address and data. */
+ switch (trans->type) {
+ case SPI_OPCODE_TYPE_READ_NO_ADDRESS:
+ case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS:
+ return 0;
+ case SPI_OPCODE_TYPE_READ_WITH_ADDRESS:
+ case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS:
+ trans->offset = ((uint32_t)trans->out[0] << 16) |
+ ((uint32_t)trans->out[1] << 8) |
+ ((uint32_t)trans->out[2] << 0);
+ spi_use_out(trans, 3);
+ return 1;
+ default:
+ printf("Unrecognized SPI transaction type %#x\n", trans->type);
+ return -1;
+ }
+}
+
+/*
+ * Wait for up to 6s til status register bit(s) turn 1 (in case wait_til_set
+ * below is True) or 0. In case the wait was for the bit(s) to set - write
+ * those bits back, which would cause resetting them.
+ *
+ * Return the last read status value on success or -1 on failure.
+ */
+static int ich_status_poll(u16 bitmask, int wait_til_set)
+{
+ int timeout = 600000; /* This will result in 6s */
+ u16 status = 0;
+
+ while (timeout--) {
+ status = ich_readw(ctlr.status);
+ if (wait_til_set ^ ((status & bitmask) == 0)) {
+ if (wait_til_set)
+ ich_writew((status & bitmask), ctlr.status);
+ return status;
+ }
+ udelay(10);
+ }
+
+ printf("ICH SPI: SCIP timeout, read %x, expected %x\n",
+ status, bitmask);
+ return -1;
+}
+
+/*
+int spi_xfer(struct spi_slave *slave, const void *dout,
+ unsigned int bitsout, void *din, unsigned int bitsin)
+*/
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+ void *din, unsigned long flags)
+{
+ struct ich_spi_slave *ich = to_ich_spi(slave);
+ uint16_t control;
+ int16_t opcode_index;
+ int with_address;
+ int status;
+ int bytes = bitlen / 8;
+ struct spi_trans *trans = &ich->trans;
+ unsigned type = flags & (SPI_XFER_BEGIN | SPI_XFER_END);
+ int using_cmd = 0;
+ /* Align read transactions to 64-byte boundaries */
+ char buff[ctlr.databytes];
+
+ /* Ee don't support writing partial bytes. */
+ if (bitlen % 8) {
+ debug("ICH SPI: Accessing partial bytes not supported\n");
+ return -1;
+ }
+
+ /* An empty end transaction can be ignored */
+ if (type == SPI_XFER_END && !dout && !din)
+ return 0;
+
+ if (type & SPI_XFER_BEGIN)
+ memset(trans, '\0', sizeof(*trans));
+
+ /* Dp we need to come back later to finish it? */
+ if (dout && type == SPI_XFER_BEGIN) {
+ if (bytes > ICH_MAX_CMD_LEN) {
+ debug("ICH SPI: Command length limit exceeded\n");
+ return -1;
+ }
+ memcpy(trans->cmd, dout, bytes);
+ trans->cmd_len = bytes;
+ debug("ICH SPI: Saved %d bytes\n", bytes);
+ return 0;
+ }
+
+ /*
+ * We process a 'middle' spi_xfer() call, which has no
+ * SPI_XFER_BEGIN/END, as an independent transaction as if it had
+ * an end. We therefore repeat the command. This is because ICH
+ * seems to have no support for this, or because interest (in digging
+ * out the details and creating a special case in the code) is low.
+ */
+ if (trans->cmd_len) {
+ trans->out = trans->cmd;
+ trans->bytesout = trans->cmd_len;
+ using_cmd = 1;
+ debug("ICH SPI: Using %d bytes\n", trans->cmd_len);
+ } else {
+ trans->out = dout;
+ trans->bytesout = dout ? bytes : 0;
+ }
+
+ trans->in = din;
+ trans->bytesin = din ? bytes : 0;
+
+ /* There has to always at least be an opcode. */
+ if (!trans->bytesout) {
+ debug("ICH SPI: No opcode for transfer\n");
+ return -1;
+ }
+
+ if (ich_status_poll(SPIS_SCIP, 0) == -1)
+ return -1;
+
+ ich_writew(SPIS_CDS | SPIS_FCERR, ctlr.status);
+
+ spi_setup_type(trans, using_cmd ? bytes : 0);
+ opcode_index = spi_setup_opcode(trans);
+ if (opcode_index < 0)
+ return -1;
+ with_address = spi_setup_offset(trans);
+ if (with_address < 0)
+ return -1;
+
+ if (trans->opcode == SPI_OPCODE_WREN) {
+ /*
+ * Treat Write Enable as Atomic Pre-Op if possible
+ * in order to prevent the Management Engine from
+ * issuing a transaction between WREN and DATA.
+ */
+ if (!ctlr.ichspi_lock)
+ ich_writew(trans->opcode, ctlr.preop);
+ return 0;
+ }
+
+ if (ctlr.speed && ctlr.max_speed >= 33000000) {
+ int byte;
+
+ byte = ich_readb(ctlr.speed);
+ if (ich->speed >= 33000000)
+ byte |= SSFC_SCF_33MHZ;
+ else
+ byte &= ~SSFC_SCF_33MHZ;
+ ich_writeb(byte, ctlr.speed);
+ }
+
+ /* See if we have used up the command data */
+ if (using_cmd && dout && bytes) {
+ trans->out = dout;
+ trans->bytesout = bytes;
+ debug("ICH SPI: Moving to data, %d bytes\n", bytes);
+ }
+
+ /* Preset control fields */
+ control = ich_readw(ctlr.control);
+ control &= ~SSFC_RESERVED;
+ control = SPIC_SCGO | ((opcode_index & 0x07) << 4);
+
+ /* Issue atomic preop cycle if needed */
+ if (ich_readw(ctlr.preop))
+ control |= SPIC_ACS;
+
+ if (!trans->bytesout && !trans->bytesin) {
+ /* SPI addresses are 24 bit only */
+ if (with_address)
+ ich_writel(trans->offset & 0x00FFFFFF, ctlr.addr);
+
+ /*
+ * This is a 'no data' command (like Write Enable), its
+ * bitesout size was 1, decremented to zero while executing
+ * spi_setup_opcode() above. Tell the chip to send the
+ * command.
+ */
+ ich_writew(control, ctlr.control);
+
+ /* wait for the result */
+ status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1);
+ if (status == -1)
+ return -1;
+
+ if (status & SPIS_FCERR) {
+ debug("ICH SPI: Command transaction error\n");
+ return -1;
+ }
+
+ return 0;
+ }
+
+ /*
+ * Check if this is a write command atempting to transfer more bytes
+ * than the controller can handle. Iterations for writes are not
+ * supported here because each SPI write command needs to be preceded
+ * and followed by other SPI commands, and this sequence is controlled
+ * by the SPI chip driver.
+ */
+ if (trans->bytesout > ctlr.databytes) {
+ debug("ICH SPI: Too much to write. This should be prevented by the driver's max_write_size?\n");
+ return -1;
+ }
+
+ /*
+ * Read or write up to databytes bytes at a time until everything has
+ * been sent.
+ */
+ while (trans->bytesout || trans->bytesin) {
+ uint32_t data_length;
+ uint32_t aligned_offset;
+ uint32_t diff;
+
+ aligned_offset = trans->offset & ~(ctlr.databytes - 1);
+ diff = trans->offset - aligned_offset;
+
+ /* SPI addresses are 24 bit only */
+ ich_writel(aligned_offset & 0x00FFFFFF, ctlr.addr);
+
+ if (trans->bytesout)
+ data_length = min(trans->bytesout, ctlr.databytes);
+ else
+ data_length = min(trans->bytesin, ctlr.databytes);
+
+ /* Program data into FDATA0 to N */
+ if (trans->bytesout) {
+ write_reg(trans->out, ctlr.data, data_length);
+ spi_use_out(trans, data_length);
+ if (with_address)
+ trans->offset += data_length;
+ }
+
+ /* Add proper control fields' values */
+ control &= ~((ctlr.databytes - 1) << 8);
+ control |= SPIC_DS;
+ control |= (data_length - 1) << 8;
+
+ /* write it */
+ ich_writew(control, ctlr.control);
+
+ /* Wait for Cycle Done Status or Flash Cycle Error. */
+ status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1);
+ if (status == -1)
+ return -1;
+
+ if (status & SPIS_FCERR) {
+ debug("ICH SPI: Data transaction error\n");
+ return -1;
+ }
+
+ if (trans->bytesin) {
+ if (diff) {
+ data_length -= diff;
+ read_reg(ctlr.data, buff, ctlr.databytes);
+ memcpy(trans->in, buff + diff, data_length);
+ } else {
+ read_reg(ctlr.data, trans->in, data_length);
+ }
+ spi_use_in(trans, data_length);
+ if (with_address)
+ trans->offset += data_length;
+ }
+ }
+
+ /* Clear atomic preop now that xfer is done */
+ ich_writew(0, ctlr.preop);
+
+ return 0;
+}
+
+
+/*
+ * This uses the SPI controller from the Intel Cougar Point and Panther Point
+ * PCH to write-protect portions of the SPI flash until reboot. The changes
+ * don't actually take effect until the HSFS[FLOCKDN] bit is set, but that's
+ * done elsewhere.
+ */
+int spi_write_protect_region(uint32_t lower_limit, uint32_t length, int hint)
+{
+ uint32_t tmplong;
+ uint32_t upper_limit;
+
+ if (!ctlr.pr) {
+ printf("%s: operation not supported on this chipset\n",
+ __func__);
+ return -1;
+ }
+
+ if (length == 0 ||
+ lower_limit > (0xFFFFFFFFUL - length) + 1 ||
+ hint < 0 || hint > 4) {
+ printf("%s(0x%x, 0x%x, %d): invalid args\n", __func__,
+ lower_limit, length, hint);
+ return -1;
+ }
+
+ upper_limit = lower_limit + length - 1;
+
+ /*
+ * Determine bits to write, as follows:
+ * 31 Write-protection enable (includes erase operation)
+ * 30:29 reserved
+ * 28:16 Upper Limit (FLA address bits 24:12, with 11:0 == 0xfff)
+ * 15 Read-protection enable
+ * 14:13 reserved
+ * 12:0 Lower Limit (FLA address bits 24:12, with 11:0 == 0x000)
+ */
+ tmplong = 0x80000000 |
+ ((upper_limit & 0x01fff000) << 4) |
+ ((lower_limit & 0x01fff000) >> 12);
+
+ printf("%s: writing 0x%08x to %p\n", __func__, tmplong,
+ &ctlr.pr[hint]);
+ ctlr.pr[hint] = tmplong;
+
+ return 0;
+}
diff --git a/drivers/spi/ich.h b/drivers/spi/ich.h
new file mode 100644
index 0000000..bd7bc12
--- /dev/null
+++ b/drivers/spi/ich.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ * This file is derived from the flashrom project.
+ */
+
+struct ich7_spi_regs {
+ uint16_t spis;
+ uint16_t spic;
+ uint32_t spia;
+ uint64_t spid[8];
+ uint64_t _pad;
+ uint32_t bbar;
+ uint16_t preop;
+ uint16_t optype;
+ uint8_t opmenu[8];
+} __packed;
+
+struct ich9_spi_regs {
+ uint32_t bfpr; /* 0x00 */
+ uint16_t hsfs;
+ uint16_t hsfc;
+ uint32_t faddr;
+ uint32_t _reserved0;
+ uint32_t fdata[16]; /* 0x10 */
+ uint32_t frap; /* 0x50 */
+ uint32_t freg[5];
+ uint32_t _reserved1[3];
+ uint32_t pr[5]; /* 0x74 */
+ uint32_t _reserved2[2];
+ uint8_t ssfs; /* 0x90 */
+ uint8_t ssfc[3];
+ uint16_t preop; /* 0x94 */
+ uint16_t optype;
+ uint8_t opmenu[8]; /* 0x98 */
+ uint32_t bbar;
+ uint8_t _reserved3[12];
+ uint32_t fdoc;
+ uint32_t fdod;
+ uint8_t _reserved4[8];
+ uint32_t afc;
+ uint32_t lvscc;
+ uint32_t uvscc;
+ uint8_t _reserved5[4];
+ uint32_t fpb;
+ uint8_t _reserved6[28];
+ uint32_t srdl;
+ uint32_t srdc;
+ uint32_t srd;
+} __packed;
+
+enum {
+ SPIS_SCIP = 0x0001,
+ SPIS_GRANT = 0x0002,
+ SPIS_CDS = 0x0004,
+ SPIS_FCERR = 0x0008,
+ SSFS_AEL = 0x0010,
+ SPIS_LOCK = 0x8000,
+ SPIS_RESERVED_MASK = 0x7ff0,
+ SSFS_RESERVED_MASK = 0x7fe2
+};
+
+enum {
+ SPIC_SCGO = 0x000002,
+ SPIC_ACS = 0x000004,
+ SPIC_SPOP = 0x000008,
+ SPIC_DBC = 0x003f00,
+ SPIC_DS = 0x004000,
+ SPIC_SME = 0x008000,
+ SSFC_SCF_MASK = 0x070000,
+ SSFC_RESERVED = 0xf80000,
+
+ /* Mask for speed byte, biuts 23:16 of SSFC */
+ SSFC_SCF_33MHZ = 0x01,
+};
+
+enum {
+ HSFS_FDONE = 0x0001,
+ HSFS_FCERR = 0x0002,
+ HSFS_AEL = 0x0004,
+ HSFS_BERASE_MASK = 0x0018,
+ HSFS_BERASE_SHIFT = 3,
+ HSFS_SCIP = 0x0020,
+ HSFS_FDOPSS = 0x2000,
+ HSFS_FDV = 0x4000,
+ HSFS_FLOCKDN = 0x8000
+};
+
+enum {
+ HSFC_FGO = 0x0001,
+ HSFC_FCYCLE_MASK = 0x0006,
+ HSFC_FCYCLE_SHIFT = 1,
+ HSFC_FDBC_MASK = 0x3f00,
+ HSFC_FDBC_SHIFT = 8,
+ HSFC_FSMIE = 0x8000
+};
+
+enum {
+ SPI_OPCODE_TYPE_READ_NO_ADDRESS = 0,
+ SPI_OPCODE_TYPE_WRITE_NO_ADDRESS = 1,
+ SPI_OPCODE_TYPE_READ_WITH_ADDRESS = 2,
+ SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3
+};
+
+enum {
+ ICH_MAX_CMD_LEN = 5,
+};
+
+struct spi_trans {
+ uint8_t cmd[ICH_MAX_CMD_LEN];
+ int cmd_len;
+ const uint8_t *out;
+ uint32_t bytesout;
+ uint8_t *in;
+ uint32_t bytesin;
+ uint8_t type;
+ uint8_t opcode;
+ uint32_t offset;
+};
+
+struct ich_spi_slave {
+ struct spi_slave slave;
+ struct spi_trans trans; /* current transaction in progress */
+ int speed; /* SPI speed in Hz */
+};
diff --git a/drivers/spi/kirkwood_spi.c b/drivers/spi/kirkwood_spi.c
index de81064..caa91e3 100644
--- a/drivers/spi/kirkwood_spi.c
+++ b/drivers/spi/kirkwood_spi.c
@@ -49,13 +49,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (!spi_cs_is_valid(bus, cs))
return NULL;
- slave = malloc(sizeof(struct spi_slave));
+ slave = spi_alloc_slave_base(bus, cs);
if (!slave)
return NULL;
- slave->bus = bus;
- slave->cs = cs;
-
writel(~KWSPI_CSN_ACT | KWSPI_SMEMRDY, &spireg->ctrl);
/* calculate spi clock prescaller using max_hz */
diff --git a/drivers/spi/mpc52xx_spi.c b/drivers/spi/mpc52xx_spi.c
index 3e96b3f..4b50bca 100644
--- a/drivers/spi/mpc52xx_spi.c
+++ b/drivers/spi/mpc52xx_spi.c
@@ -48,13 +48,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
{
struct spi_slave *slave;
- slave = malloc(sizeof(struct spi_slave));
+ slave = spi_alloc_slave_base(bus, cs);
if (!slave)
return NULL;
- slave->bus = bus;
- slave->cs = cs;
-
return slave;
}
diff --git a/drivers/spi/mpc8xxx_spi.c b/drivers/spi/mpc8xxx_spi.c
index 4e46041..6b0e3b4 100644
--- a/drivers/spi/mpc8xxx_spi.c
+++ b/drivers/spi/mpc8xxx_spi.c
@@ -45,13 +45,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (!spi_cs_is_valid(bus, cs))
return NULL;
- slave = malloc(sizeof(struct spi_slave));
+ slave = spi_alloc_slave_base(bus, cs);
if (!slave)
return NULL;
- slave->bus = bus;
- slave->cs = cs;
-
/*
* TODO: Some of the code in spi_init() should probably move
* here, or into spi_claim_bus() below.
diff --git a/drivers/spi/mxc_spi.c b/drivers/spi/mxc_spi.c
index 859c43f..cb48019 100644
--- a/drivers/spi/mxc_spi.c
+++ b/drivers/spi/mxc_spi.c
@@ -137,11 +137,11 @@ static s32 spi_cfg_mxc(struct mxc_spi_slave *mxcs, unsigned int cs,
return -1;
}
- reg_ctrl = reg_read(&regs->ctrl);
-
/* Reset spi */
- reg_write(&regs->ctrl, (reg_ctrl & ~MXC_CSPICTRL_EN));
- reg_write(&regs->ctrl, (reg_ctrl | MXC_CSPICTRL_EN));
+ reg_write(&regs->ctrl, 0);
+ reg_write(&regs->ctrl, MXC_CSPICTRL_EN);
+
+ reg_ctrl = reg_read(&regs->ctrl);
/*
* The following computation is taken directly from Freescale's code.
@@ -408,7 +408,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (bus >= ARRAY_SIZE(spi_bases))
return NULL;
- mxcs = calloc(sizeof(struct mxc_spi_slave), 1);
+ mxcs = spi_alloc_slave(struct mxc_spi_slave, bus, cs);
if (!mxcs) {
puts("mxc_spi: SPI Slave not allocated !\n");
return NULL;
@@ -424,8 +424,6 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
cs = ret;
- mxcs->slave.bus = bus;
- mxcs->slave.cs = cs;
mxcs->base = spi_bases[bus];
ret = spi_cfg_mxc(mxcs, cs, max_hz, mode);
diff --git a/drivers/spi/mxs_spi.c b/drivers/spi/mxs_spi.c
index ffa3c1d..aa999f9 100644
--- a/drivers/spi/mxs_spi.c
+++ b/drivers/spi/mxs_spi.c
@@ -77,15 +77,13 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
return NULL;
}
- mxs_slave = calloc(sizeof(struct mxs_spi_slave), 1);
+ mxs_slave = spi_alloc_slave(struct mxs_spi_slave, bus, cs);
if (!mxs_slave)
return NULL;
if (mxs_dma_init_channel(MXS_DMA_CHANNEL_AHB_APBH_SSP0 + bus))
goto err_init;
- mxs_slave->slave.bus = bus;
- mxs_slave->slave.cs = cs;
mxs_slave->max_khz = max_hz / 1000;
mxs_slave->mode = mode;
mxs_slave->regs = mxs_ssp_regs_by_bus(bus);
diff --git a/drivers/spi/oc_tiny_spi.c b/drivers/spi/oc_tiny_spi.c
index fc01fb8..6f7b1ed 100644
--- a/drivers/spi/oc_tiny_spi.c
+++ b/drivers/spi/oc_tiny_spi.c
@@ -90,13 +90,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (!spi_cs_is_valid(bus, cs) || gpio_request(cs, "tiny_spi"))
return NULL;
- tiny_spi = malloc(sizeof(*tiny_spi));
+ tiny_spi = spi_alloc_slave(struct tiny_spi_slave, bus, cs);
if (!tiny_spi)
return NULL;
- memset(tiny_spi, 0, sizeof(*tiny_spi));
- tiny_spi->slave.bus = bus;
- tiny_spi->slave.cs = cs;
tiny_spi->host = &tiny_spi_host_list[bus];
tiny_spi->mode = mode & (SPI_CPOL | SPI_CPHA);
tiny_spi->flg = mode & SPI_CS_HIGH ? 1 : 0;
diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
index 344d5b8..80a4e47 100644
--- a/drivers/spi/omap3_spi.c
+++ b/drivers/spi/omap3_spi.c
@@ -80,12 +80,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int mode)
{
struct omap3_spi_slave *ds;
-
- ds = malloc(sizeof(struct omap3_spi_slave));
- if (!ds) {
- printf("SPI error: malloc of SPI structure failed\n");
- return NULL;
- }
+ struct mcspi *regs;
/*
* OMAP3 McSPI (MultiChannel SPI) has 4 busses (modules)
@@ -98,21 +93,21 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
switch (bus) {
case 0:
- ds->regs = (struct mcspi *)OMAP3_MCSPI1_BASE;
+ regs = (struct mcspi *)OMAP3_MCSPI1_BASE;
break;
#ifdef OMAP3_MCSPI2_BASE
case 1:
- ds->regs = (struct mcspi *)OMAP3_MCSPI2_BASE;
+ regs = (struct mcspi *)OMAP3_MCSPI2_BASE;
break;
#endif
#ifdef OMAP3_MCSPI3_BASE
case 2:
- ds->regs = (struct mcspi *)OMAP3_MCSPI3_BASE;
+ regs = (struct mcspi *)OMAP3_MCSPI3_BASE;
break;
#endif
#ifdef OMAP3_MCSPI4_BASE
case 3:
- ds->regs = (struct mcspi *)OMAP3_MCSPI4_BASE;
+ regs = (struct mcspi *)OMAP3_MCSPI4_BASE;
break;
#endif
default:
@@ -120,7 +115,6 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
Supported busses 0 - 3\n", bus);
return NULL;
}
- ds->slave.bus = bus;
if (((bus == 0) && (cs > 3)) ||
((bus == 1) && (cs > 1)) ||
@@ -130,19 +124,26 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
on bus %i\n", cs, bus);
return NULL;
}
- ds->slave.cs = cs;
if (max_hz > OMAP3_MCSPI_MAX_FREQ) {
printf("SPI error: unsupported frequency %i Hz. \
Max frequency is 48 Mhz\n", max_hz);
return NULL;
}
- ds->freq = max_hz;
if (mode > SPI_MODE_3) {
printf("SPI error: unsupported SPI mode %i\n", mode);
return NULL;
}
+
+ ds = spi_alloc_slave(struct omap3_spi_slave, bus, cs);
+ if (!ds) {
+ printf("SPI error: malloc of SPI structure failed\n");
+ return NULL;
+ }
+
+ ds->regs = regs;
+ ds->freq = max_hz;
ds->mode = mode;
return &ds->slave;
diff --git a/drivers/spi/sh_spi.c b/drivers/spi/sh_spi.c
index e944b23..744afe3 100644
--- a/drivers/spi/sh_spi.c
+++ b/drivers/spi/sh_spi.c
@@ -103,12 +103,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (!spi_cs_is_valid(bus, cs))
return NULL;
- ss = malloc(sizeof(struct spi_slave));
+ ss = spi_alloc_slave(struct sh_spi, bus, cs);
if (!ss)
return NULL;
- ss->slave.bus = bus;
- ss->slave.cs = cs;
ss->regs = (struct sh_spi_regs *)CONFIG_SH_SPI_BASE;
/* SPI sycle stop */
diff --git a/drivers/spi/soft_spi.c b/drivers/spi/soft_spi.c
index 13df8cb..a1b84b6 100644
--- a/drivers/spi/soft_spi.c
+++ b/drivers/spi/soft_spi.c
@@ -73,12 +73,10 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
if (!spi_cs_is_valid(bus, cs))
return NULL;
- ss = malloc(sizeof(struct soft_spi_slave));
+ ss = spi_alloc_slave(struct soft_spi_slave, bus, cs);
if (!ss)
return NULL;
- ss->slave.bus = bus;
- ss->slave.cs = cs;
ss->mode = mode;
/* TODO: Use max_hz to limit the SCK rate */
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
new file mode 100644
index 0000000..cb36c5e
--- /dev/null
+++ b/drivers/spi/spi.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but without any warranty; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <spi.h>
+
+void *spi_do_alloc_slave(int offset, int size, unsigned int bus,
+ unsigned int cs)
+{
+ struct spi_slave *slave;
+ void *ptr;
+
+ ptr = malloc(size);
+ if (ptr) {
+ memset(ptr, '\0', size);
+ slave = (struct spi_slave *)(ptr + offset);
+ slave->bus = bus;
+ slave->cs = cs;
+ }
+
+ return ptr;
+}
diff --git a/drivers/spi/tegra20_sflash.c b/drivers/spi/tegra20_sflash.c
index a4e6c9a..9322ce7 100644
--- a/drivers/spi/tegra20_sflash.c
+++ b/drivers/spi/tegra20_sflash.c
@@ -127,7 +127,7 @@ struct spi_slave *tegra20_spi_setup_slave(unsigned int bus, unsigned int cs,
return NULL;
}
- spi = malloc(sizeof(struct tegra_spi_slave));
+ spi = spi_alloc_slave(struct tegra_spi_slave, bus, cs);
if (!spi) {
printf("SPI error: malloc of SPI structure failed\n");
return NULL;
diff --git a/drivers/spi/tegra20_slink.c b/drivers/spi/tegra20_slink.c
index 2ef2eb8..664de6e 100644
--- a/drivers/spi/tegra20_slink.c
+++ b/drivers/spi/tegra20_slink.c
@@ -135,13 +135,11 @@ struct spi_slave *tegra30_spi_setup_slave(unsigned int bus, unsigned int cs,
return NULL;
}
- spi = malloc(sizeof(struct tegra_spi_slave));
+ spi = spi_alloc_slave(struct tegra_spi_slave, bus, cs);
if (!spi) {
printf("SPI error: malloc of SPI structure failed\n");
return NULL;
}
- spi->slave.bus = bus;
- spi->slave.cs = cs;
spi->ctrl = &spi_ctrls[bus];
if (!spi->ctrl) {
printf("SPI error: could not find controller for bus %d\n",
diff --git a/drivers/spi/xilinx_spi.c b/drivers/spi/xilinx_spi.c
index db01cc2..a82b056 100644
--- a/drivers/spi/xilinx_spi.c
+++ b/drivers/spi/xilinx_spi.c
@@ -85,14 +85,12 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
return NULL;
}
- xilspi = malloc(sizeof(*xilspi));
+ xilspi = spi_alloc_slave(struct xilinx_spi_slave, bus, cs);
if (!xilspi) {
printf("XILSPI error: %s: malloc of SPI structure failed\n",
__func__);
return NULL;
}
- xilspi->slave.bus = bus;
- xilspi->slave.cs = cs;
xilspi->regs = (struct xilinx_spi_reg *)xilinx_spi_base_list[bus];
xilspi->freq = max_hz;
xilspi->mode = mode;
diff --git a/include/config_defaults.h b/include/config_defaults.h
index d023c63..567b46c 100644
--- a/include/config_defaults.h
+++ b/include/config_defaults.h
@@ -12,6 +12,7 @@
/* Support bootm-ing different OSes */
#define CONFIG_BOOTM_LINUX 1
#define CONFIG_BOOTM_NETBSD 1
+#define CONFIG_BOOTM_PLAN9 1
#define CONFIG_BOOTM_RTEMS 1
#define CONFIG_GZIP 1
diff --git a/include/configs/coreboot.h b/include/configs/coreboot.h
index 87daf62..a4aa8f7 100644
--- a/include/configs/coreboot.h
+++ b/include/configs/coreboot.h
@@ -179,6 +179,8 @@
#define CONFIG_CMD_SAVEENV
#define CONFIG_CMD_SETGETDCR
#define CONFIG_CMD_SOURCE
+#define CONFIG_CMD_TIME
+#define CONFIG_CMD_GETTIME
#define CONFIG_CMD_XIMG
#define CONFIG_CMD_SCSI
@@ -257,10 +259,16 @@
/*-----------------------------------------------------------------------
* FLASH configuration
*/
+#define CONFIG_ICH_SPI
+#define CONFIG_SPI_FLASH
+#define CONFIG_SPI_FLASH_MACRONIX
+#define CONFIG_SPI_FLASH_WINBOND
+#define CONFIG_SPI_FLASH_GIGADEVICE
#define CONFIG_SYS_NO_FLASH
-#undef CONFIG_FLASH_CFI_DRIVER
-#define CONFIG_SYS_MAX_FLASH_SECT 1
-#define CONFIG_SYS_MAX_FLASH_BANKS 1
+#define CONFIG_CMD_SF
+#define CONFIG_CMD_SF_TEST
+#define CONFIG_CMD_SPI
+#define CONFIG_SPI
/*-----------------------------------------------------------------------
* Environment configuration
diff --git a/include/configs/mx23_olinuxino.h b/include/configs/mx23_olinuxino.h
index 03893d7..38ad7f4 100644
--- a/include/configs/mx23_olinuxino.h
+++ b/include/configs/mx23_olinuxino.h
@@ -24,57 +24,57 @@
/*
* SoC configurations
*/
-#define CONFIG_MX23 /* i.MX23 SoC */
-#define CONFIG_MXS_GPIO /* GPIO control */
-#define CONFIG_SYS_HZ 1000 /* Ticks per second */
+#define CONFIG_MX23 /* i.MX23 SoC */
+#define CONFIG_MXS_GPIO /* GPIO control */
+#define CONFIG_SYS_HZ 1000 /* Ticks per second */
-#define CONFIG_MACH_TYPE 4105
+#define CONFIG_MACH_TYPE 4105
#include <asm/arch/regs-base.h>
-#define CONFIG_SYS_NO_FLASH
-#define CONFIG_BOARD_EARLY_INIT_F
-#define CONFIG_ARCH_MISC_INIT
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_ARCH_MISC_INIT
/*
* SPL
*/
-#define CONFIG_SPL
-#define CONFIG_SPL_NO_CPU_SUPPORT_CODE
-#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/arm926ejs/mxs"
-#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds"
-#define CONFIG_SPL_LIBCOMMON_SUPPORT
-#define CONFIG_SPL_LIBGENERIC_SUPPORT
-#define CONFIG_SPL_GPIO_SUPPORT
+#define CONFIG_SPL
+#define CONFIG_SPL_NO_CPU_SUPPORT_CODE
+#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/arm926ejs/mxs"
+#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds"
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_GPIO_SUPPORT
/*
* U-Boot Commands
*/
#include <config_cmd_default.h>
-#define CONFIG_DISPLAY_CPUINFO
-#define CONFIG_DOS_PARTITION
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DOS_PARTITION
-#define CONFIG_CMD_CACHE
-#define CONFIG_CMD_DHCP
-#define CONFIG_CMD_EXT2
-#define CONFIG_CMD_FAT
-#define CONFIG_CMD_GPIO
-#define CONFIG_CMD_LED
-#define CONFIG_CMD_MMC
-#define CONFIG_CMD_NET
-#define CONFIG_CMD_USB
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_GPIO
+#define CONFIG_CMD_LED
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_USB
/*
* Memory configurations
*/
-#define CONFIG_NR_DRAM_BANKS 1 /* 1 bank of DRAM */
-#define PHYS_SDRAM_1 0x40000000 /* Base address */
-#define PHYS_SDRAM_1_SIZE 0x08000000 /* Max 128 MB RAM */
-#define CONFIG_SYS_MALLOC_LEN 0x00400000 /* 4 MB for malloc */
-#define CONFIG_SYS_GBL_DATA_SIZE 128 /* Initial data */
-#define CONFIG_SYS_MEMTEST_START 0x40000000 /* Memtest start adr */
-#define CONFIG_SYS_MEMTEST_END 0x40400000 /* 4 MB RAM test */
-#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
+#define CONFIG_NR_DRAM_BANKS 1 /* 1 bank of DRAM */
+#define PHYS_SDRAM_1 0x40000000 /* Base address */
+#define PHYS_SDRAM_1_SIZE 0x08000000 /* Max 128 MB RAM */
+#define CONFIG_SYS_MALLOC_LEN 0x00400000 /* 4 MB for malloc */
+#define CONFIG_SYS_GBL_DATA_SIZE 128 /* Initial data */
+#define CONFIG_SYS_MEMTEST_START 0x40000000 /* Memtest start adr */
+#define CONFIG_SYS_MEMTEST_END 0x40400000 /* 4 MB RAM test */
+#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1
/* Point initial SP in SRAM so SPL can use it too. */
#define CONFIG_SYS_INIT_RAM_ADDR 0x00000000
@@ -89,49 +89,49 @@
* strange BUG in ROM corrupting first 4 bytes of RAM when loading U-Boot
* binary. In case there was more of this mess, 0x100 bytes are skipped.
*/
-#define CONFIG_SYS_TEXT_BASE 0x40000100
+#define CONFIG_SYS_TEXT_BASE 0x40000100
/*
* U-Boot general configurations
*/
-#define CONFIG_SYS_LONGHELP
-#define CONFIG_SYS_PROMPT "=> "
-#define CONFIG_SYS_CBSIZE 1024 /* Console I/O buffer size */
-#define CONFIG_SYS_PBSIZE \
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_PROMPT "=> "
+#define CONFIG_SYS_CBSIZE 1024 /* Console I/O buffer size */
+#define CONFIG_SYS_PBSIZE \
(CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
/* Print buffer size */
-#define CONFIG_SYS_MAXARGS 32 /* Max number of command args */
-#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+#define CONFIG_SYS_MAXARGS 32 /* Max number of command args */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
/* Boot argument buffer size */
-#define CONFIG_VERSION_VARIABLE /* U-BOOT version */
-#define CONFIG_AUTO_COMPLETE /* Command auto complete */
-#define CONFIG_CMDLINE_EDITING /* Command history etc */
-#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_VERSION_VARIABLE /* U-BOOT version */
+#define CONFIG_AUTO_COMPLETE /* Command auto complete */
+#define CONFIG_CMDLINE_EDITING /* Command history etc */
+#define CONFIG_SYS_HUSH_PARSER
/*
* Serial Driver
*/
-#define CONFIG_PL011_SERIAL
-#define CONFIG_PL011_CLOCK 24000000
-#define CONFIG_PL01x_PORTS { (void *)MXS_UARTDBG_BASE }
-#define CONFIG_CONS_INDEX 0
-#define CONFIG_BAUDRATE 115200 /* Default baud rate */
+#define CONFIG_PL011_SERIAL
+#define CONFIG_PL011_CLOCK 24000000
+#define CONFIG_PL01x_PORTS { (void *)MXS_UARTDBG_BASE }
+#define CONFIG_CONS_INDEX 0
+#define CONFIG_BAUDRATE 115200 /* Default baud rate */
/*
* Status LED
*/
-#define CONFIG_STATUS_LED
-#define CONFIG_GPIO_LED
-#define CONFIG_BOARD_SPECIFIC_LED
-#define STATUS_LED_BOOT 0
-#define STATUS_LED_BIT MX23_PAD_SSP1_DETECT__GPIO_2_1
-#define STATUS_LED_STATE STATUS_LED_ON
-#define STATUS_LED_PERIOD (CONFIG_SYS_HZ / 2)
+#define CONFIG_STATUS_LED
+#define CONFIG_GPIO_LED
+#define CONFIG_BOARD_SPECIFIC_LED
+#define STATUS_LED_BOOT 0
+#define STATUS_LED_BIT MX23_PAD_SSP1_DETECT__GPIO_2_1
+#define STATUS_LED_STATE STATUS_LED_ON
+#define STATUS_LED_PERIOD (CONFIG_SYS_HZ / 2)
/*
* MMC Driver
*/
-#ifdef CONFIG_CMD_MMC
+#ifdef CONFIG_CMD_MMC
#define CONFIG_MMC
#define CONFIG_BOUNCE_BUFFER
#define CONFIG_GENERIC_MMC
@@ -144,41 +144,41 @@
#define CONFIG_APBH_DMA
/* USB */
-#ifdef CONFIG_CMD_USB
-#define CONFIG_USB_EHCI
-#define CONFIG_USB_EHCI_MXS
-#define CONFIG_EHCI_MXS_PORT0
-#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
-#define CONFIG_EHCI_IS_TDI
-#define CONFIG_USB_STORAGE
+#ifdef CONFIG_CMD_USB
+#define CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_MXS
+#define CONFIG_EHCI_MXS_PORT0
+#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
+#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_STORAGE
#endif
/* Ethernet */
-#ifdef CONFIG_CMD_NET
-#define CONFIG_USB_HOST_ETHER
-#define CONFIG_USB_ETHER_SMSC95XX
+#ifdef CONFIG_CMD_NET
+#define CONFIG_USB_HOST_ETHER
+#define CONFIG_USB_ETHER_SMSC95XX
#endif
/*
* Boot Linux
*/
-#define CONFIG_CMDLINE_TAG
-#define CONFIG_SETUP_MEMORY_TAGS
-#define CONFIG_BOOTDELAY 3
-#define CONFIG_BOOTFILE "uImage"
-#define CONFIG_LOADADDR 0x42000000
-#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
-#define CONFIG_OF_LIBFDT
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_BOOTDELAY 3
+#define CONFIG_BOOTFILE "uImage"
+#define CONFIG_LOADADDR 0x42000000
+#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
+#define CONFIG_OF_LIBFDT
/*
* Environment
*/
-#define CONFIG_ENV_IS_IN_MMC
-#define CONFIG_ENV_OVERWRITE
-#ifdef CONFIG_ENV_IS_IN_MMC
-#define CONFIG_ENV_OFFSET (256 * 1024)
-#define CONFIG_ENV_SIZE (16 * 1024)
-#define CONFIG_SYS_MMC_ENV_DEV 0
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_ENV_OVERWRITE
+#ifdef CONFIG_ENV_IS_IN_MMC
+#define CONFIG_ENV_OFFSET (256 * 1024)
+#define CONFIG_ENV_SIZE (16 * 1024)
+#define CONFIG_SYS_MMC_ENV_DEV 0
#endif
/*
@@ -227,7 +227,7 @@
"else " \
"bootm; " \
"fi;\0" \
- "netargs=setenv bootargs console=${console_mainline},${baudrate} " \
+ "netargs=setenv bootargs console=${console},${baudrate} " \
"root=/dev/nfs " \
"ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
"netboot=echo Booting from net ...; " \
diff --git a/include/configs/mx25pdk.h b/include/configs/mx25pdk.h
index c10e78b..4782f68 100644
--- a/include/configs/mx25pdk.h
+++ b/include/configs/mx25pdk.h
@@ -124,6 +124,10 @@
#define CONFIG_SYS_I2C_BASE IMX_I2C_BASE
#define CONFIG_SYS_I2C_SPEED 100000
+/* RTC */
+#define CONFIG_RTC_IMXDI
+#define CONFIG_CMD_DATE
+
/* Ethernet Configs */
#define CONFIG_CMD_PING
diff --git a/include/configs/mx28evk.h b/include/configs/mx28evk.h
index 0d918a1..d470b47 100644
--- a/include/configs/mx28evk.h
+++ b/include/configs/mx28evk.h
@@ -19,9 +19,7 @@
#ifndef __MX28EVK_CONFIG_H__
#define __MX28EVK_CONFIG_H__
-/*
- * SoC configurations
- */
+/* SoC configurations */
#define CONFIG_MX28 /* i.MX28 SoC */
#define CONFIG_MXS_GPIO /* GPIO control */
@@ -35,9 +33,7 @@
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_ARCH_MISC_INIT
-/*
- * SPL
- */
+/* SPL */
#define CONFIG_SPL
#define CONFIG_SPL_NO_CPU_SUPPORT_CODE
#define CONFIG_SPL_START_S_PATH "arch/arm/cpu/arm926ejs/mxs"
@@ -46,9 +42,7 @@
#define CONFIG_SPL_LIBGENERIC_SUPPORT
#define CONFIG_SPL_GPIO_SUPPORT
-/*
- * U-Boot Commands
- */
+/* U-Boot Commands */
#include <config_cmd_default.h>
#define CONFIG_DISPLAY_CPUINFO
#define CONFIG_DOS_PARTITION
@@ -68,11 +62,9 @@
#define CONFIG_CMD_SPI
#define CONFIG_CMD_USB
#define CONFIG_CMD_BOOTZ
-#define CONFIG_CMD_I2C
+#define CONFIG_CMD_NAND
-/*
- * Memory configurations
- */
+/* Memory configurations */
#define CONFIG_NR_DRAM_BANKS 1 /* 1 bank of DRAM */
#define PHYS_SDRAM_1 0x40000000 /* Base address */
#define PHYS_SDRAM_1_SIZE 0x40000000 /* Max 1 GB RAM */
@@ -98,9 +90,7 @@
#define CONFIG_SYS_TEXT_BASE 0x40000100
#define CONFIG_ENV_OVERWRITE
-/*
- * U-Boot general configurations
- */
+/* U-Boot general configurations */
#define CONFIG_SYS_LONGHELP
#define CONFIG_SYS_PROMPT "MX28EVK U-Boot > "
#define CONFIG_SYS_CBSIZE 1024 /* Console I/O buffer size */
@@ -115,24 +105,17 @@
#define CONFIG_CMDLINE_EDITING /* Command history etc */
#define CONFIG_SYS_HUSH_PARSER
-/*
- * Serial Driver
- */
+/* Serial Driver */
#define CONFIG_PL011_SERIAL
#define CONFIG_PL011_CLOCK 24000000
#define CONFIG_PL01x_PORTS { (void *)MXS_UARTDBG_BASE }
#define CONFIG_CONS_INDEX 0
#define CONFIG_BAUDRATE 115200 /* Default baud rate */
-/*
- * DMA
- */
+/* DMA */
#define CONFIG_APBH_DMA
-/*
- * MMC Driver
- */
-#define CONFIG_ENV_IS_IN_MMC
+/* MMC Driver */
#ifdef CONFIG_ENV_IS_IN_MMC
#define CONFIG_ENV_OFFSET (256 * 1024)
#define CONFIG_ENV_SIZE (16 * 1024)
@@ -146,19 +129,44 @@
#define CONFIG_MXS_MMC
#endif
-/*
- * NAND Driver
- */
+/* NAND Driver */
+#define CONFIG_ENV_SIZE (16 * 1024)
#ifdef CONFIG_CMD_NAND
#define CONFIG_NAND_MXS
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define CONFIG_SYS_NAND_BASE 0x60000000
#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+
+/* Environment is in NAND */
+#define CONFIG_ENV_SIZE_REDUND CONFIG_ENV_SIZE
+#define CONFIG_ENV_SECT_SIZE (128 * 1024)
+#define CONFIG_ENV_RANGE (512 * 1024)
+#ifndef CONFIG_ENV_OFFSET
+#define CONFIG_ENV_OFFSET 0x300000
#endif
+#define CONFIG_ENV_OFFSET_REDUND \
+ (CONFIG_ENV_OFFSET + CONFIG_ENV_RANGE)
-/*
- * Ethernet on SOC (FEC)
- */
+#define CONFIG_CMD_UBI
+#define CONFIG_CMD_UBIFS
+#define CONFIG_CMD_MTDPARTS
+#define CONFIG_RBTREE
+#define CONFIG_LZO
+#define CONFIG_MTD_DEVICE
+#define CONFIG_MTD_PARTITIONS
+#define MTDIDS_DEFAULT "nand0=gpmi-nand"
+#define MTDPARTS_DEFAULT \
+ "mtdparts=gpmi-nand:" \
+ "3m(bootloader)ro," \
+ "512k(environment)," \
+ "512k(redundant-environment)," \
+ "4m(kernel)," \
+ "128k(fdt)," \
+ "8m(ramdisk)," \
+ "-(filesystem)"
+#endif
+
+/* Ethernet on SOC (FEC) */
#ifdef CONFIG_CMD_NET
#define CONFIG_NET_MULTI
#define CONFIG_ETHPRIME "FEC0"
@@ -168,16 +176,12 @@
#define CONFIG_MX28_FEC_MAC_IN_OCOTP
#endif
-/*
- * RTC
- */
+/* RTC */
#ifdef CONFIG_CMD_DATE
#define CONFIG_RTC_MXS
#endif
-/*
- * USB
- */
+/* USB */
#ifdef CONFIG_CMD_USB
#define CONFIG_USB_EHCI
#define CONFIG_USB_EHCI_MXS
@@ -197,9 +201,7 @@
#define CONFIG_SYS_I2C_SPEED 400000
#endif
-/*
- * SPI
- */
+/* SPI */
#ifdef CONFIG_CMD_SPI
#define CONFIG_HARD_SPI
#define CONFIG_MXS_SPI
@@ -232,9 +234,7 @@
#endif
#endif
-/*
- * Boot Linux
- */
+/* Boot Linux */
#define CONFIG_CMDLINE_TAG
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_BOOTDELAY 1
@@ -243,9 +243,7 @@
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
#define CONFIG_OF_LIBFDT
-/*
- * Extra Environments
- */
+/* Extra Environments */
#define CONFIG_EXTRA_ENV_SETTINGS \
"update_nand_full_filename=u-boot.nand\0" \
"update_nand_firmware_filename=u-boot.sb\0" \
diff --git a/include/configs/mx6qsabre_common.h b/include/configs/mx6qsabre_common.h
index 9eda9ed..0965b8f 100644
--- a/include/configs/mx6qsabre_common.h
+++ b/include/configs/mx6qsabre_common.h
@@ -36,6 +36,7 @@
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024)
#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_BOARD_LATE_INIT
#define CONFIG_MXC_GPIO
#define CONFIG_MXC_UART
@@ -75,6 +76,7 @@
/* Command definition */
#include <config_cmd_default.h>
+#define CONFIG_CMD_BMODE
#define CONFIG_CMD_BOOTZ
#undef CONFIG_CMD_IMLS
diff --git a/include/configs/mx6qsabrelite.h b/include/configs/mx6qsabrelite.h
index 5dc8255..6d4b837 100644
--- a/include/configs/mx6qsabrelite.h
+++ b/include/configs/mx6qsabrelite.h
@@ -216,7 +216,6 @@
"fi;\0"
#define CONFIG_BOOTCOMMAND \
- "mmc dev ${mmcdev};" \
"mmc dev ${mmcdev}; if mmc rescan; then " \
"if run loadbootscript; then " \
"run bootscript; " \
@@ -228,8 +227,6 @@
"fi; " \
"else run netboot; fi"
-#define CONFIG_ARP_TIMEOUT 200UL
-
/* Miscellaneous configurable options */
#define CONFIG_SYS_LONGHELP
#define CONFIG_SYS_HUSH_PARSER
diff --git a/include/configs/rpi_b.h b/include/configs/rpi_b.h
index 3d55d36..c18b35b 100644
--- a/include/configs/rpi_b.h
+++ b/include/configs/rpi_b.h
@@ -31,7 +31,7 @@
#define CONFIG_MACH_TYPE MACH_TYPE_BCM2708
/* Timer */
-#define CONFIG_SYS_HZ 1000000
+#define CONFIG_SYS_HZ 1000
/* Memory layout */
#define CONFIG_NR_DRAM_BANKS 1
diff --git a/include/configs/wandboard.h b/include/configs/wandboard.h
new file mode 100644
index 0000000..120e3f6
--- /dev/null
+++ b/include/configs/wandboard.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * Configuration settings for the Wandboard.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <asm/arch/imx-regs.h>
+#include <asm/imx-common/gpio.h>
+#include <asm/sizes.h>
+
+#define CONFIG_MX6
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DISPLAY_BOARDINFO
+
+#define MACH_TYPE_WANDBOARD 4412
+#define CONFIG_MACH_TYPE MACH_TYPE_WANDBOARD
+
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+#define CONFIG_REVISION_TAG
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN (3 * SZ_1M)
+
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_MXC_GPIO
+
+#define CONFIG_MXC_UART
+#define CONFIG_MXC_UART_BASE UART1_BASE
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_CONS_INDEX 1
+#define CONFIG_BAUDRATE 115200
+
+/* Command definition */
+#include <config_cmd_default.h>
+
+#undef CONFIG_CMD_IMLS
+
+#define CONFIG_BOOTDELAY 5
+
+#define CONFIG_SYS_MEMTEST_START 0x10000000
+#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_MEMTEST_START + 500 * SZ_1M)
+#define CONFIG_LOADADDR 0x12000000
+#define CONFIG_SYS_TEXT_BASE 0x17800000
+
+/* MMC Configuration */
+#define CONFIG_FSL_ESDHC
+#define CONFIG_FSL_USDHC
+#define CONFIG_SYS_FSL_ESDHC_ADDR 0
+
+#define CONFIG_MMC
+#define CONFIG_CMD_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_BOUNCE_BUFFER
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_FAT
+#define CONFIG_DOS_PARTITION
+
+/* Ethernet Configuration */
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_NET
+#define CONFIG_FEC_MXC
+#define CONFIG_MII
+#define IMX_FEC_BASE ENET_BASE_ADDR
+#define CONFIG_FEC_XCV_TYPE RGMII
+#define CONFIG_ETHPRIME "FEC"
+#define CONFIG_FEC_MXC_PHYADDR 1
+#define CONFIG_PHYLIB
+#define CONFIG_PHY_ATHEROS
+
+#if defined(CONFIG_MX6DL)
+#define CONFIG_DEFAULT_FDT_FILE "imx6dl-wandboard.dtb"
+#elif defined(CONFIG_MX6S)
+#define CONFIG_DEFAULT_FDT_FILE "imx6s-wandboard.dtb"
+#endif
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ "script=boot.scr\0" \
+ "uimage=uImage\0" \
+ "console=ttymxc0\0" \
+ "fdt_high=0xffffffff\0" \
+ "initrd_high=0xffffffff\0" \
+ "fdt_file=" CONFIG_DEFAULT_FDT_FILE "\0" \
+ "fdt_addr=0x11000000\0" \
+ "boot_fdt=try\0" \
+ "ip_dyn=yes\0" \
+ "mmcdev=0\0" \
+ "mmcpart=2\0" \
+ "mmcroot=/dev/mmcblk0p3 rootwait rw\0" \
+ "mmcargs=setenv bootargs console=${console},${baudrate} " \
+ "root=${mmcroot}\0" \
+ "loadbootscript=" \
+ "fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
+ "bootscript=echo Running bootscript from mmc ...; " \
+ "source\0" \
+ "loaduimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${uimage}\0" \
+ "loadfdt=fatload mmc ${mmcdev}:${mmcpart} ${fdt_addr} ${fdt_file}\0" \
+ "mmcboot=echo Booting from mmc ...; " \
+ "run mmcargs; " \
+ "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
+ "if run loadfdt; then " \
+ "bootm ${loadaddr} - ${fdt_addr}; " \
+ "else " \
+ "if test ${boot_fdt} = try; then " \
+ "bootm; " \
+ "else " \
+ "echo WARN: Cannot load the DT; " \
+ "fi; " \
+ "fi; " \
+ "else " \
+ "bootm; " \
+ "fi;\0" \
+ "netargs=setenv bootargs console=${console},${baudrate} " \
+ "root=/dev/nfs " \
+ "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
+ "netboot=echo Booting from net ...; " \
+ "run netargs; " \
+ "if test ${ip_dyn} = yes; then " \
+ "setenv get_cmd dhcp; " \
+ "else " \
+ "setenv get_cmd tftp; " \
+ "fi; " \
+ "${get_cmd} ${uimage}; " \
+ "if test ${boot_fdt} = yes || test ${boot_fdt} = try; then " \
+ "if ${get_cmd} ${fdt_addr} ${fdt_file}; then " \
+ "bootm ${loadaddr} - ${fdt_addr}; " \
+ "else " \
+ "if test ${boot_fdt} = try; then " \
+ "bootm; " \
+ "else " \
+ "echo WARN: Cannot load the DT; " \
+ "fi; " \
+ "fi; " \
+ "else " \
+ "bootm; " \
+ "fi;\0"
+
+#define CONFIG_BOOTCOMMAND \
+ "mmc dev ${mmcdev}; if mmc rescan; then " \
+ "if run loadbootscript; then " \
+ "run bootscript; " \
+ "else " \
+ "if run loaduimage; then " \
+ "run mmcboot; " \
+ "else run netboot; " \
+ "fi; " \
+ "fi; " \
+ "else run netboot; fi"
+
+/* Miscellaneous configurable options */
+#define CONFIG_SYS_LONGHELP
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT "=> "
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_SYS_CBSIZE 256
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS 16
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
+
+#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
+#define CONFIG_SYS_HZ 1000
+
+#define CONFIG_CMDLINE_EDITING
+
+/* Physical Memory Map */
+#define CONFIG_NR_DRAM_BANKS 1
+#define PHYS_SDRAM MMDC0_ARB_BASE_ADDR
+
+#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM
+#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR
+#define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE
+
+#define CONFIG_SYS_INIT_SP_OFFSET \
+ (CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR \
+ (CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
+
+/* FLASH and environment organization */
+#define CONFIG_SYS_NO_FLASH
+
+#define CONFIG_ENV_SIZE (8 * 1024)
+
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_ENV_OFFSET (6 * 64 * 1024)
+#define CONFIG_SYS_MMC_ENV_DEV 0
+
+#define CONFIG_OF_LIBFDT
+#define CONFIG_CMD_BOOTZ
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+#define CONFIG_CMD_CACHE
+#endif
+
+#endif /* __CONFIG_H * */
diff --git a/include/env_callback.h b/include/env_callback.h
index e89b6da..b856000 100644
--- a/include/env_callback.h
+++ b/include/env_callback.h
@@ -67,7 +67,6 @@ struct env_clbk_tbl {
int flags);
};
-struct env_clbk_tbl *find_env_callback(const char *);
void env_callback_init(ENTRY *var_entry);
/*
diff --git a/include/fdtdec.h b/include/fdtdec.h
index a83b160..844991e 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -38,11 +38,13 @@
*/
#ifdef CONFIG_PHYS_64BIT
typedef u64 fdt_addr_t;
+typedef u64 fdt_size_t;
#define FDT_ADDR_T_NONE (-1ULL)
#define fdt_addr_to_cpu(reg) be64_to_cpu(reg)
#define fdt_size_to_cpu(reg) be64_to_cpu(reg)
#else
typedef u32 fdt_addr_t;
+typedef u32 fdt_size_t;
#define FDT_ADDR_T_NONE (-1U)
#define fdt_addr_to_cpu(reg) be32_to_cpu(reg)
#define fdt_size_to_cpu(reg) be32_to_cpu(reg)
@@ -88,6 +90,7 @@ enum fdt_compat_id {
COMPAT_SAMSUNG_EXYNOS_FIMD, /* Exynos Display controller */
COMPAT_SAMSUNG_EXYNOS5_DP, /* Exynos Display port controller */
COMPAT_MAXIM_MAX77686_PMIC, /* MAX77686 PMIC */
+ COMPAT_GENERIC_SPI_FLASH, /* Generic SPI Flash chip */
COMPAT_MAXIM_98095_CODEC, /* MAX98095 Codec */
COMPAT_COUNT,
@@ -205,6 +208,19 @@ fdt_addr_t fdtdec_get_addr(const void *blob, int node,
const char *prop_name);
/**
+ * Look up an address property in a node and return it as an address.
+ * The property must hold one address with a length. This is only tested
+ * on 32-bit machines.
+ *
+ * @param blob FDT blob
+ * @param node node to examine
+ * @param prop_name name of property to find
+ * @return address, if found, or FDT_ADDR_T_NONE if not
+ */
+fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
+ const char *prop_name, fdt_size_t *sizep);
+
+/**
* Look up a 32-bit integer property in a node and return it. The property
* must have at least 4 bytes of data. The value of the first cell is
* returned.
diff --git a/include/fsl_esdhc.h b/include/fsl_esdhc.h
index 47d2fe4..0a1a071 100644
--- a/include/fsl_esdhc.h
+++ b/include/fsl_esdhc.h
@@ -168,6 +168,7 @@
struct fsl_esdhc_cfg {
u32 esdhc_base;
u32 sdhc_clk;
+ u8 max_bus_width;
};
/* Select the correct accessors depending on endianess */
diff --git a/include/image.h b/include/image.h
index 8e285f9..4ad0e6b 100644
--- a/include/image.h
+++ b/include/image.h
@@ -84,6 +84,7 @@
#define IH_OS_UNITY 20 /* Unity OS */
#define IH_OS_INTEGRITY 21 /* INTEGRITY */
#define IH_OS_OSE 22 /* OSE */
+#define IH_OS_PLAN9 23 /* Plan 9 */
/*
* CPU Architecture Codes (supported by Linux)
diff --git a/include/spi.h b/include/spi.h
index 60e85db..3fe2e1e 100644
--- a/include/spi.h
+++ b/include/spi.h
@@ -49,10 +49,13 @@
*
* bus: ID of the bus that the slave is attached to.
* cs: ID of the chip select connected to the slave.
+ * max_write_size: If non-zero, the maximum number of bytes which can
+ * be written at once, excluding command bytes.
*/
struct spi_slave {
unsigned int bus;
unsigned int cs;
+ unsigned int max_write_size;
};
/*-----------------------------------------------------------------------
@@ -62,6 +65,47 @@ struct spi_slave {
*/
void spi_init(void);
+/**
+ * spi_do_alloc_slave - Allocate a new SPI slave (internal)
+ *
+ * Allocate and zero all fields in the spi slave, and set the bus/chip
+ * select. Use the helper macro spi_alloc_slave() to call this.
+ *
+ * @offset: Offset of struct spi_slave within slave structure
+ * @size: Size of slave structure
+ * @bus: Bus ID of the slave chip.
+ * @cs: Chip select ID of the slave chip on the specified bus.
+ */
+void *spi_do_alloc_slave(int offset, int size, unsigned int bus,
+ unsigned int cs);
+
+/**
+ * spi_alloc_slave - Allocate a new SPI slave
+ *
+ * Allocate and zero all fields in the spi slave, and set the bus/chip
+ * select.
+ *
+ * @_struct: Name of structure to allocate (e.g. struct tegra_spi). This
+ * structure must contain a member 'struct spi_slave *slave'.
+ * @bus: Bus ID of the slave chip.
+ * @cs: Chip select ID of the slave chip on the specified bus.
+ */
+#define spi_alloc_slave(_struct, bus, cs) \
+ spi_do_alloc_slave(offsetof(_struct, slave), \
+ sizeof(_struct), bus, cs)
+
+/**
+ * spi_alloc_slave_base - Allocate a new SPI slave with no private data
+ *
+ * Allocate and zero all fields in the spi slave, and set the bus/chip
+ * select.
+ *
+ * @bus: Bus ID of the slave chip.
+ * @cs: Chip select ID of the slave chip on the specified bus.
+ */
+#define spi_alloc_slave_base(bus, cs) \
+ spi_do_alloc_slave(0, sizeof(struct spi_slave), bus, cs)
+
/*-----------------------------------------------------------------------
* Set up communications parameters for a SPI slave.
*
diff --git a/include/spi_flash.h b/include/spi_flash.h
index 9da9062..3b6a44e 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -39,6 +39,7 @@ struct spi_flash {
/* Erase (sector) size */
u32 sector_size;
+ void *memory_map; /* Address of read-only SPI flash access */
int (*read)(struct spi_flash *flash, u32 offset,
size_t len, void *buf);
int (*write)(struct spi_flash *flash, u32 offset,
@@ -47,6 +48,44 @@ struct spi_flash {
size_t len);
};
+/**
+ * spi_flash_do_alloc - Allocate a new spi flash structure
+ *
+ * The structure is allocated and cleared with default values for
+ * read, write and erase, which the caller can modify. The caller must set
+ * up size, page_size and sector_size.
+ *
+ * Use the helper macro spi_flash_alloc() to call this.
+ *
+ * @offset: Offset of struct spi_slave within slave structure
+ * @size: Size of slave structure
+ * @spi: SPI slave
+ * @name: Name of SPI flash device
+ */
+void *spi_flash_do_alloc(int offset, int size, struct spi_slave *spi,
+ const char *name);
+
+/**
+ * spi_flash_alloc - Allocate a new SPI flash structure
+ *
+ * @_struct: Name of structure to allocate (e.g. struct ramtron_spi_fram). This
+ * structure must contain a member 'struct spi_flash *flash'.
+ * @spi: SPI slave
+ * @name: Name of SPI flash device
+ */
+#define spi_flash_alloc(_struct, spi, name) \
+ spi_flash_do_alloc(offsetof(_struct, flash), sizeof(_struct), \
+ spi, name)
+
+/**
+ * spi_flash_alloc_base - Allocate a new SPI flash structure with no private data
+ *
+ * @spi: SPI slave
+ * @name: Name of SPI flash device
+ */
+#define spi_flash_alloc_base(spi, name) \
+ spi_flash_do_alloc(0, sizeof(struct spi_flash), spi, name)
+
struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
unsigned int max_hz, unsigned int spi_mode);
void spi_flash_free(struct spi_flash *flash);
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 0f34bdc..403babd 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -63,6 +63,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(SAMSUNG_EXYNOS_FIMD, "samsung,exynos-fimd"),
COMPAT(SAMSUNG_EXYNOS5_DP, "samsung,exynos5-dp"),
COMPAT(MAXIM_MAX77686_PMIC, "maxim,max77686_pmic"),
+ COMPAT(GENERIC_SPI_FLASH, "spi-flash"),
COMPAT(MAXIM_98095_CODEC, "maxim,max98095-codec"),
};
@@ -73,25 +74,40 @@ const char *fdtdec_get_compatible(enum fdt_compat_id id)
return compat_names[id];
}
-fdt_addr_t fdtdec_get_addr(const void *blob, int node,
- const char *prop_name)
+fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
+ const char *prop_name, fdt_size_t *sizep)
{
const fdt_addr_t *cell;
int len;
debug("%s: %s: ", __func__, prop_name);
cell = fdt_getprop(blob, node, prop_name, &len);
- if (cell && (len == sizeof(fdt_addr_t) ||
- len == sizeof(fdt_addr_t) * 2)) {
+ if (cell && ((!sizep && len == sizeof(fdt_addr_t)) ||
+ len == sizeof(fdt_addr_t) * 2)) {
fdt_addr_t addr = fdt_addr_to_cpu(*cell);
-
- debug("%p\n", (void *)addr);
+ if (sizep) {
+ const fdt_size_t *size;
+
+ size = (fdt_size_t *)((char *)cell +
+ sizeof(fdt_addr_t));
+ *sizep = fdt_size_to_cpu(*size);
+ debug("addr=%p, size=%p\n", (void *)addr,
+ (void *)*sizep);
+ } else {
+ debug("%p\n", (void *)addr);
+ }
return addr;
}
debug("(not found)\n");
return FDT_ADDR_T_NONE;
}
+fdt_addr_t fdtdec_get_addr(const void *blob, int node,
+ const char *prop_name)
+{
+ return fdtdec_get_addr_size(blob, node, prop_name, NULL);
+}
+
s32 fdtdec_get_int(const void *blob, int node, const char *prop_name,
s32 default_val)
{
diff --git a/tools/checkpatch.pl b/tools/checkpatch.pl
index 051ba0d..9f23901 100755
--- a/tools/checkpatch.pl
+++ b/tools/checkpatch.pl
@@ -272,6 +272,7 @@ our $logFunctions = qr{(?x:
[a-z0-9]+_(?:printk|emerg|alert|crit|err|warning|warn|notice|info|debug|dbg|vdbg|devel|cont|WARN)(?:_ratelimited|_once|)|
WARN(?:_RATELIMIT|_ONCE|)|
panic|
+ debug|
MODULE_[A-Z_]+
)};