summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile2
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/Makefile11
-rw-r--r--arch/arm/boards/pcm049/board.c4
-rw-r--r--arch/arm/boards/pcm049/env/config2
-rw-r--r--arch/arm/boards/phycard-a-l1/env/config2
-rw-r--r--arch/arm/boards/phycard-a-l1/pca-a-l1.c6
-rw-r--r--arch/arm/boards/phycard-a-xl2/env/config2
-rw-r--r--arch/arm/boards/phycard-a-xl2/pca-a-xl2.c4
-rw-r--r--arch/arm/mach-omap/Kconfig24
-rw-r--r--arch/arm/mach-omap/gpio.c171
-rw-r--r--arch/arm/mach-omap/include/mach/xload.h4
-rw-r--r--arch/arm/mach-omap/omap3_clock.c14
-rw-r--r--arch/arm/mach-omap/omap3_generic.c19
-rw-r--r--arch/arm/mach-omap/omap4_generic.c19
-rw-r--r--arch/arm/mach-omap/xload.c99
-rw-r--r--common/filetype.c2
-rw-r--r--include/filetype.h16
-rw-r--r--scripts/.gitignore1
-rw-r--r--scripts/Makefile2
-rw-r--r--scripts/mk-am35xx-spi-image.c141
22 files changed, 403 insertions, 144 deletions
diff --git a/.gitignore b/.gitignore
index 7e98a2558b..9af6710290 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,6 +34,7 @@ barebox.bin
barebox.srec
barebox.netx
barebox.s5p
+barebox.spi
barebox.ubl
barebox.uimage
barebox.map
diff --git a/Makefile b/Makefile
index 5c4bab8e94..3d60927dae 100644
--- a/Makefile
+++ b/Makefile
@@ -1032,7 +1032,7 @@ CLEAN_FILES += barebox System.map include/generated/barebox_default_env.h \
.tmp_kallsyms* barebox_default_env* barebox.ldr \
scripts/bareboxenv-target barebox-flash-image \
Doxyfile.version barebox.srec barebox.s5p barebox.ubl \
- barebox.uimage
+ barebox.uimage barebox.spi
# Directories & files removed with 'make mrproper'
MRPROPER_DIRS += include/config include2 usr/include
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index a54ad03445..7b7b0585ae 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -58,6 +58,7 @@ config ARCH_NOMADIK
config ARCH_OMAP
bool "TI OMAP"
select HAS_DEBUG_LL
+ select GPIOLIB
config ARCH_PXA
bool "Intel/Marvell PXA based"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 208f0f401c..855043aedf 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -217,6 +217,17 @@ KBUILD_TARGET := barebox.ubl
KBUILD_IMAGE := barebox.ubl
endif
+quiet_cmd_am35xx_spi_image = SPI-IMG $@
+ cmd_am35xx_spi_image = scripts/mk-am35xx-spi-image $< > $@
+
+barebox.spi: $(KBUILD_BINARY) FORCE
+ $(call if_changed,am35xx_spi_image)
+
+ifeq ($(CONFIG_OMAP_BUILD_SPI),y)
+KBUILD_TARGET := barebox.spi
+KBUILD_IMAGE := barebox.spi
+endif
+
pbl := arch/arm/pbl
zbarebox.S zbarebox.bin zbarebox: barebox.bin
$(Q)$(MAKE) $(build)=$(pbl) $(pbl)/$@
diff --git a/arch/arm/boards/pcm049/board.c b/arch/arm/boards/pcm049/board.c
index 3ef38a7831..3b10d0a649 100644
--- a/arch/arm/boards/pcm049/board.c
+++ b/arch/arm/boards/pcm049/board.c
@@ -118,9 +118,9 @@ static int pcm049_devices_init(void)
#ifdef CONFIG_PARTITION
devfs_add_partition("nand0", 0x00000, SZ_128K, DEVFS_PARTITION_FIXED, "xload_raw");
dev_add_bb_dev("xload_raw", "xload");
- devfs_add_partition("nand0", SZ_128K, SZ_256K, DEVFS_PARTITION_FIXED, "self_raw");
+ devfs_add_partition("nand0", SZ_128K, SZ_512K, DEVFS_PARTITION_FIXED, "self_raw");
dev_add_bb_dev("self_raw", "self0");
- devfs_add_partition("nand0", SZ_128K + SZ_256K, SZ_128K, DEVFS_PARTITION_FIXED, "env_raw");
+ devfs_add_partition("nand0", SZ_128K + SZ_512K, SZ_128K, DEVFS_PARTITION_FIXED, "env_raw");
dev_add_bb_dev("env_raw", "env0");
#endif
diff --git a/arch/arm/boards/pcm049/env/config b/arch/arm/boards/pcm049/env/config
index fc64215e5e..0ae3e1bc3c 100644
--- a/arch/arm/boards/pcm049/env/config
+++ b/arch/arm/boards/pcm049/env/config
@@ -40,7 +40,7 @@ autoboot_timeout=3
bootargs="console=ttyO2,115200"
-nand_parts="128k(xload)ro,256k(barebox),128k(bareboxenv),2M(kernel),-(root)"
+nand_parts="128k(xload)ro,512k(barebox),128k(bareboxenv),4M(kernel),-(root)"
rootfs_mtdblock_nand=4
# set a fancy prompt (if support is compiled in)
diff --git a/arch/arm/boards/phycard-a-l1/env/config b/arch/arm/boards/phycard-a-l1/env/config
index 90b2c24781..6de97ed5d5 100644
--- a/arch/arm/boards/phycard-a-l1/env/config
+++ b/arch/arm/boards/phycard-a-l1/env/config
@@ -70,7 +70,7 @@ bootargs="$bootargs omapdss.def_disp=pd050vl1"
#bootargs="$bootargs omapdss.def_disp=pd104slf"
#bootargs="$bootargs omapdss.def_disp=pm070wl4"
-nand_parts="512k(x-loader)ro,1920k(barebox),128k(bareboxenv),4M(kernel),-(root)"
+nand_parts="128k(x-loader)ro,512k(barebox),128k(bareboxenv),4M(kernel),-(root)"
nand_device=omap2-nand.0
rootfs_mtdblock_nand=4
diff --git a/arch/arm/boards/phycard-a-l1/pca-a-l1.c b/arch/arm/boards/phycard-a-l1/pca-a-l1.c
index 907198d783..a08518f8d0 100644
--- a/arch/arm/boards/phycard-a-l1/pca-a-l1.c
+++ b/arch/arm/boards/phycard-a-l1/pca-a-l1.c
@@ -422,13 +422,13 @@ device_initcall(pcaal1_init_devices);
static int pcaal1_late_init(void)
{
#ifdef CONFIG_PARTITION
- devfs_add_partition("nand0", 0x00000, 0x80000, DEVFS_PARTITION_FIXED, "x-loader");
+ devfs_add_partition("nand0", 0x00000, SZ_128K, DEVFS_PARTITION_FIXED, "x-loader");
dev_add_bb_dev("self_raw", "x_loader0");
- devfs_add_partition("nand0", 0x80000, 0x1e0000, DEVFS_PARTITION_FIXED, "self_raw");
+ devfs_add_partition("nand0", SZ_128K, SZ_512K, DEVFS_PARTITION_FIXED, "self_raw");
dev_add_bb_dev("self_raw", "self0");
- devfs_add_partition("nand0", 0x260000, 0x20000, DEVFS_PARTITION_FIXED, "env_raw");
+ devfs_add_partition("nand0", SZ_128K + SZ_512K, SZ_128K, DEVFS_PARTITION_FIXED, "env_raw");
dev_add_bb_dev("env_raw", "env0");
#endif
return 0;
diff --git a/arch/arm/boards/phycard-a-xl2/env/config b/arch/arm/boards/phycard-a-xl2/env/config
index 532f2907f9..349a51fb43 100644
--- a/arch/arm/boards/phycard-a-xl2/env/config
+++ b/arch/arm/boards/phycard-a-xl2/env/config
@@ -39,7 +39,7 @@ autoboot_timeout=3
bootargs="console=ttyO2,115200"
-nand_parts="128k(xload)ro,256k(barebox),128k(bareboxenv),4M(kernel),-(root)"
+nand_parts="128k(xload)ro,512k(barebox),128k(bareboxenv),4M(kernel),-(root)"
rootfs_mtdblock_nand=4
# set a fancy prompt (if support is compiled in)
diff --git a/arch/arm/boards/phycard-a-xl2/pca-a-xl2.c b/arch/arm/boards/phycard-a-xl2/pca-a-xl2.c
index 4fec0f0e41..91d45dcc1b 100644
--- a/arch/arm/boards/phycard-a-xl2/pca-a-xl2.c
+++ b/arch/arm/boards/phycard-a-xl2/pca-a-xl2.c
@@ -136,10 +136,10 @@ static int pcaaxl2_devices_init(void)
devfs_add_partition("nand0", 0x00000, SZ_128K,
DEVFS_PARTITION_FIXED, "xload_raw");
dev_add_bb_dev("xload_raw", "xload");
- devfs_add_partition("nand0", SZ_128K, SZ_256K,
+ devfs_add_partition("nand0", SZ_128K, SZ_512K,
DEVFS_PARTITION_FIXED, "self_raw");
dev_add_bb_dev("self_raw", "self0");
- devfs_add_partition("nand0", SZ_128K + SZ_256K, SZ_128K,
+ devfs_add_partition("nand0", SZ_128K + SZ_512K, SZ_128K,
DEVFS_PARTITION_FIXED, "env_raw");
dev_add_bb_dev("env_raw", "env0");
#endif
diff --git a/arch/arm/mach-omap/Kconfig b/arch/arm/mach-omap/Kconfig
index d735284a11..98750c4eb2 100644
--- a/arch/arm/mach-omap/Kconfig
+++ b/arch/arm/mach-omap/Kconfig
@@ -52,20 +52,7 @@ config ARCH_OMAP4
endchoice
-### Generic Clock configurations to be enabled by Mach - invisible to enable.
-config OMAP_CLOCK_UART
- bool
-config OMAP_CLOCK_UART2
- bool
-config OMAP_CLOCK_UART3
- bool
-config OMAP_CLOCK_I2C
- bool
-
# Blind enable all possible clocks.. think twice before you do this.
-config OMAP_CLOCK_ALL
- bool
-
config OMAP_CLOCK_SOURCE_S32K
bool
@@ -91,6 +78,13 @@ config OMAP_BUILD_IFT
prompt "build ift binary"
bool
+config OMAP_BUILD_SPI
+ prompt "build SPI binary"
+ bool
+ help
+ Say Y here if you want to build an barebox.spi image as used
+ on the AM35xx chips when booting form SPI NOR flash.
+
config ARCH_TEXT_BASE
hex
default 0x80e80000 if MACH_OMAP343xSDP
@@ -110,14 +104,12 @@ choice
config MACH_OMAP343xSDP
bool "Texas Instrument's SDP343x"
- select OMAP_CLOCK_ALL
depends on ARCH_OMAP3
help
Say Y here if you are using SDP343x platform
config MACH_BEAGLE
bool "Texas Instrument's Beagle Board"
- select OMAP_CLOCK_ALL
select HAVE_NOSHELL
depends on ARCH_OMAP3
help
@@ -125,7 +117,6 @@ config MACH_BEAGLE
config MACH_OMAP3EVM
bool "Texas Instrument's OMAP3 EVM"
- select OMAP_CLOCK_ALL
select HAVE_NOSHELL
depends on ARCH_OMAP3
help
@@ -150,7 +141,6 @@ config MACH_PCM049
config MACH_PCAAL1
bool "Phytec phyCARD-A-L1"
- select OMAP_CLOCK_ALL
select HAVE_NOSHELL
depends on ARCH_OMAP3
help
diff --git a/arch/arm/mach-omap/gpio.c b/arch/arm/mach-omap/gpio.c
index 142cf524eb..d16d6d9aab 100644
--- a/arch/arm/mach-omap/gpio.c
+++ b/arch/arm/mach-omap/gpio.c
@@ -36,11 +36,10 @@
* published by the Free Software Foundation.
*/
#include <common.h>
-#include <mach/gpio.h>
#include <io.h>
#include <errno.h>
-
-#ifdef CONFIG_ARCH_OMAP3
+#include <gpio.h>
+#include <init.h>
#define OMAP_GPIO_OE 0x0034
#define OMAP_GPIO_DATAIN 0x0038
@@ -48,129 +47,115 @@
#define OMAP_GPIO_CLEARDATAOUT 0x0090
#define OMAP_GPIO_SETDATAOUT 0x0094
-static void __iomem *gpio_bank[] = {
- (void *)0x48310000,
- (void *)0x49050000,
- (void *)0x49052000,
- (void *)0x49054000,
- (void *)0x49056000,
- (void *)0x49058000,
-};
-#endif
-
-#ifdef CONFIG_ARCH_OMAP4
-
-#define OMAP_GPIO_OE 0x0134
-#define OMAP_GPIO_DATAIN 0x0138
-#define OMAP_GPIO_DATAOUT 0x013c
-#define OMAP_GPIO_CLEARDATAOUT 0x0190
-#define OMAP_GPIO_SETDATAOUT 0x0194
-
-static void __iomem *gpio_bank[] = {
- (void *)0x4a310000,
- (void *)0x48055000,
- (void *)0x48057000,
- (void *)0x48059000,
- (void *)0x4805b000,
- (void *)0x4805d000,
+struct omap_gpio_chip {
+ void __iomem *base;
+ struct gpio_chip chip;
};
-#endif
-
-static inline void __iomem *get_gpio_base(int gpio)
-{
- return gpio_bank[gpio >> 5];
-}
-static inline int get_gpio_index(int gpio)
+static inline int omap_get_gpio_index(int gpio)
{
return gpio & 0x1f;
}
-static inline int gpio_valid(int gpio)
+static void omap_gpio_set_value(struct gpio_chip *chip,
+ unsigned gpio, int value)
{
- if (gpio < 0)
- return -1;
- if (gpio / 32 < ARRAY_SIZE(gpio_bank))
- return 0;
- return -1;
-}
-
-static int check_gpio(int gpio)
-{
- if (gpio_valid(gpio) < 0) {
- printf("ERROR : check_gpio: invalid GPIO %d\n", gpio);
- return -1;
- }
- return 0;
-}
-
-void gpio_set_value(unsigned gpio, int value)
-{
- void __iomem *reg;
+ struct omap_gpio_chip *omapgpio =
+ container_of(chip, struct omap_gpio_chip, chip);
+ void __iomem *base = omapgpio->base;
u32 l = 0;
- if (check_gpio(gpio) < 0)
- return;
-
- reg = get_gpio_base(gpio);
-
if (value)
- reg += OMAP_GPIO_SETDATAOUT;
+ base += OMAP_GPIO_SETDATAOUT;
else
- reg += OMAP_GPIO_CLEARDATAOUT;
- l = 1 << get_gpio_index(gpio);
+ base += OMAP_GPIO_CLEARDATAOUT;
+
+ l = 1 << omap_get_gpio_index(gpio);
- __raw_writel(l, reg);
+ writel(l, base);
}
-int gpio_direction_input(unsigned gpio)
+static int omap_gpio_direction_input(struct gpio_chip *chip,
+ unsigned gpio)
{
- void __iomem *reg;
+ struct omap_gpio_chip *omapgpio =
+ container_of(chip, struct omap_gpio_chip, chip);
+ void __iomem *base = omapgpio->base;
u32 val;
- if (check_gpio(gpio) < 0)
- return -EINVAL;
-
- reg = get_gpio_base(gpio);
-
- reg += OMAP_GPIO_OE;
+ base += OMAP_GPIO_OE;
- val = __raw_readl(reg);
- val |= 1 << get_gpio_index(gpio);
- __raw_writel(val, reg);
+ val = readl(base);
+ val |= 1 << omap_get_gpio_index(gpio);
+ writel(val, base);
return 0;
}
-int gpio_direction_output(unsigned gpio, int value)
+static int omap_gpio_direction_output(struct gpio_chip *chip,
+ unsigned gpio, int value)
{
- void __iomem *reg;
+ struct omap_gpio_chip *omapgpio =
+ container_of(chip, struct omap_gpio_chip, chip);
+ void __iomem *base = omapgpio->base;
u32 val;
- if (check_gpio(gpio) < 0)
- return -EINVAL;
- reg = get_gpio_base(gpio);
+ omap_gpio_set_value(chip, gpio, value);
- gpio_set_value(gpio, value);
+ base += OMAP_GPIO_OE;
- reg += OMAP_GPIO_OE;
-
- val = __raw_readl(reg);
- val &= ~(1 << get_gpio_index(gpio));
- __raw_writel(val, reg);
+ val = readl(base);
+ val &= ~(1 << omap_get_gpio_index(gpio));
+ writel(val, base);
return 0;
}
-int gpio_get_value(unsigned gpio)
+static int omap_gpio_get_value(struct gpio_chip *chip, unsigned gpio)
+{
+ struct omap_gpio_chip *omapgpio =
+ container_of(chip, struct omap_gpio_chip, chip);
+ void __iomem *base = omapgpio->base;
+
+ base += OMAP_GPIO_DATAIN;
+
+ return (readl(base) & (1 << omap_get_gpio_index(gpio))) != 0;
+
+}
+
+static struct gpio_ops omap_gpio_ops = {
+ .direction_input = omap_gpio_direction_input,
+ .direction_output = omap_gpio_direction_output,
+ .get = omap_gpio_get_value,
+ .set = omap_gpio_set_value,
+};
+
+static int omap_gpio_probe(struct device_d *dev)
{
- void __iomem *reg;
+ struct omap_gpio_chip *omapgpio;
+
+ omapgpio = xzalloc(sizeof(*omapgpio));
+ omapgpio->base = dev_request_mem_region(dev, 0);
+ omapgpio->chip.ops = &omap_gpio_ops;
+ omapgpio->chip.base = -1;
+ omapgpio->chip.ngpio = 32;
+ omapgpio->chip.dev = dev;
+ gpiochip_add(&omapgpio->chip);
- if (check_gpio(gpio) < 0)
- return -EINVAL;
- reg = get_gpio_base(gpio);
+ dev_dbg(dev, "probed gpiochip%d with base %d\n",
+ dev->id, omapgpio->chip.base);
+
+ return 0;
+}
- reg += OMAP_GPIO_DATAIN;
+static struct driver_d omap_gpio_driver = {
+ .name = "omap-gpio",
+ .probe = omap_gpio_probe,
+};
- return (__raw_readl(reg) & (1 << get_gpio_index(gpio))) != 0;
+static int omap_gpio_add(void)
+{
+ register_driver(&omap_gpio_driver);
+ return 0;
}
+coredevice_initcall(omap_gpio_add);
diff --git a/arch/arm/mach-omap/include/mach/xload.h b/arch/arm/mach-omap/include/mach/xload.h
index 844b57f0e5..63b68df15c 100644
--- a/arch/arm/mach-omap/include/mach/xload.h
+++ b/arch/arm/mach-omap/include/mach/xload.h
@@ -1,13 +1,11 @@
#ifndef _MACH_XLOAD_H
#define _MACH_XLOAD_H
-void *omap_xload_boot_nand(int offset, int size);
-void *omap_xload_boot_mmc(void);
-
enum omap_boot_src {
OMAP_BOOTSRC_UNKNOWN,
OMAP_BOOTSRC_MMC1,
OMAP_BOOTSRC_NAND,
+ OMAP_BOOTSRC_SPI1,
};
enum omap_boot_src omap3_bootsrc(void);
diff --git a/arch/arm/mach-omap/omap3_clock.c b/arch/arm/mach-omap/omap3_clock.c
index 646235e4c2..463633a53d 100644
--- a/arch/arm/mach-omap/omap3_clock.c
+++ b/arch/arm/mach-omap/omap3_clock.c
@@ -674,18 +674,6 @@ static void per_clocks_enable(void)
/* Enable the ICLK for 32K Sync Timer as its used in udelay */
sr32(CM_REG(ICLKEN_WKUP), 2, 1, 0x1);
-#ifdef CONFIG_OMAP_CLOCK_UART
- /* Enable UART1 clocks */
- sr32(CM_REG(FCLKEN1_CORE), 13, 1, 0x1);
- sr32(CM_REG(ICLKEN1_CORE), 13, 1, 0x1);
-#endif
-#ifdef CONFIG_OMAP_CLOCK_I2C
- /* Turn on all 3 I2C clocks */
- sr32(CM_REG(FCLKEN1_CORE), 15, 3, 0x7);
- sr32(CM_REG(ICLKEN1_CORE), 15, 3, 0x7); /* I2C1,2,3 = on */
-#endif
-
-#ifdef CONFIG_OMAP_CLOCK_ALL
#define FCK_IVA2_ON 0x00000001
#define FCK_CORE1_ON 0x03fffe29
#define ICK_CORE1_ON 0x3ffffffb
@@ -710,7 +698,7 @@ static void per_clocks_enable(void)
sr32(CM_REG(ICLKEN_CAM), 0, 32, ICK_CAM_ON);
sr32(CM_REG(FCLKEN_PER), 0, 32, FCK_PER_ON);
sr32(CM_REG(ICLKEN_PER), 0, 32, ICK_PER_ON);
-#endif
+
/* Settle down my friend */
sdelay(1000);
}
diff --git a/arch/arm/mach-omap/omap3_generic.c b/arch/arm/mach-omap/omap3_generic.c
index 4ab265a9ba..0e9cd7162c 100644
--- a/arch/arm/mach-omap/omap3_generic.c
+++ b/arch/arm/mach-omap/omap3_generic.c
@@ -515,3 +515,22 @@ const struct gpmc_config omap3_nand_cfg = {
.base = 0x28000000,
.size = GPMC_SIZE_16M,
};
+
+static int omap3_gpio_init(void)
+{
+ add_generic_device("omap-gpio", 0, NULL, 0x48310000,
+ 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("omap-gpio", 1, NULL, 0x49050000,
+ 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("omap-gpio", 2, NULL, 0x49052000,
+ 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("omap-gpio", 3, NULL, 0x49054000,
+ 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("omap-gpio", 4, NULL, 0x49056000,
+ 0x100, IORESOURCE_MEM, NULL);
+ add_generic_device("omap-gpio", 5, NULL, 0x49058000,
+ 0x100, IORESOURCE_MEM, NULL);
+
+ return 0;
+}
+coredevice_initcall(omap3_gpio_init);
diff --git a/arch/arm/mach-omap/omap4_generic.c b/arch/arm/mach-omap/omap4_generic.c
index 617d786984..a159dfcb7e 100644
--- a/arch/arm/mach-omap/omap4_generic.c
+++ b/arch/arm/mach-omap/omap4_generic.c
@@ -572,3 +572,22 @@ const struct gpmc_config omap4_nand_cfg = {
.base = 0x28000000,
.size = GPMC_SIZE_16M,
};
+
+static int omap4_gpio_init(void)
+{
+ add_generic_device("omap-gpio", 0, NULL, 0x4a310100,
+ 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("omap-gpio", 1, NULL, 0x48055100,
+ 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("omap-gpio", 2, NULL, 0x48057100,
+ 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("omap-gpio", 3, NULL, 0x48059100,
+ 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("omap-gpio", 4, NULL, 0x4805b100,
+ 0x1000, IORESOURCE_MEM, NULL);
+ add_generic_device("omap-gpio", 5, NULL, 0x4805d100,
+ 0x1000, IORESOURCE_MEM, NULL);
+
+ return 0;
+}
+coredevice_initcall(omap4_gpio_init);
diff --git a/arch/arm/mach-omap/xload.c b/arch/arm/mach-omap/xload.c
index 13024abac7..9fa8221ec9 100644
--- a/arch/arm/mach-omap/xload.c
+++ b/arch/arm/mach-omap/xload.c
@@ -7,16 +7,65 @@
#include <fcntl.h>
#include <mach/xload.h>
#include <sizes.h>
+#include <filetype.h>
-void *omap_xload_boot_nand(int offset, int size)
+static void *read_image_head(const char *name)
{
+ void *header = xmalloc(ARM_HEAD_SIZE);
+ struct cdev *cdev;
int ret;
- void *to = xmalloc(size);
+
+ cdev = cdev_open(name, O_RDONLY);
+ if (!cdev) {
+ printf("failed to open partition\n");
+ return NULL;
+ }
+
+ ret = cdev_read(cdev, header, ARM_HEAD_SIZE, 0, 0);
+ cdev_close(cdev);
+
+ if (ret != ARM_HEAD_SIZE) {
+ printf("failed to read from partition\n");
+ return NULL;
+ }
+
+ return header;
+}
+
+static unsigned int get_image_size(void *head)
+{
+ unsigned int ret = 0;
+ unsigned int *psize = head + ARM_HEAD_SIZE_OFFSET;
+
+ if (is_barebox_arm_head(head))
+ ret = *psize;
+ debug("Detected barebox image size %u\n", ret);
+
+ return ret;
+}
+
+static void *omap_xload_boot_nand(int offset)
+{
+ int ret;
+ int size;
+ void *to, *header;
struct cdev *cdev;
- devfs_add_partition("nand0", offset, size, DEVFS_PARTITION_FIXED, "x");
+ devfs_add_partition("nand0", offset, SZ_1M, DEVFS_PARTITION_FIXED, "x");
dev_add_bb_dev("x", "bbx");
+ header = read_image_head("bbx");
+ if (header == NULL)
+ return NULL;
+
+ size = get_image_size(header);
+ if (!size) {
+ printf("failed to get image size\n");
+ return NULL;
+ }
+
+ to = xmalloc(size);
+
cdev = cdev_open("bbx", O_RDONLY);
if (!cdev) {
printf("failed to open nand\n");
@@ -32,7 +81,7 @@ void *omap_xload_boot_nand(int offset, int size)
return to;
}
-void *omap_xload_boot_mmc(void)
+static void *omap_xload_boot_mmc(void)
{
int ret;
void *buf;
@@ -54,6 +103,42 @@ void *omap_xload_boot_mmc(void)
return buf;
}
+static void *omap_xload_boot_spi(int offset)
+{
+ int ret;
+ int size;
+ void *to, *header;
+ struct cdev *cdev;
+
+ devfs_add_partition("m25p0", offset, SZ_1M, DEVFS_PARTITION_FIXED, "x");
+
+ header = read_image_head("x");
+ if (header == NULL)
+ return NULL;
+
+ size = get_image_size(header);
+ if (!size) {
+ printf("failed to get image size\n");
+ return NULL;
+ }
+
+ to = xmalloc(size);
+
+ cdev = cdev_open("x", O_RDONLY);
+ if (!cdev) {
+ printf("failed to open spi flash\n");
+ return NULL;
+ }
+
+ ret = cdev_read(cdev, to, size, 0, 0);
+ if (ret != size) {
+ printf("failed to read from spi flash\n");
+ return NULL;
+ }
+
+ return to;
+}
+
enum omap_boot_src omap_bootsrc(void)
{
#if defined(CONFIG_ARCH_OMAP3)
@@ -80,7 +165,11 @@ int run_shell(void)
printf("unknown boot source. Fall back to nand\n");
case OMAP_BOOTSRC_NAND:
printf("booting from NAND\n");
- func = omap_xload_boot_nand(SZ_128K, SZ_256K);
+ func = omap_xload_boot_nand(SZ_128K);
+ break;
+ case OMAP_BOOTSRC_SPI1:
+ printf("booting from SPI1\n");
+ func = omap_xload_boot_spi(SZ_128K);
break;
}
diff --git a/common/filetype.c b/common/filetype.c
index 6a0dcfb760..3d544cd6ce 100644
--- a/common/filetype.c
+++ b/common/filetype.c
@@ -102,7 +102,7 @@ enum filetype file_detect_type(void *_buf)
if (strncmp(buf8, "#!/bin/sh", 9) == 0)
return filetype_sh;
- if (buf[8] == 0x65726162 && buf[9] == 0x00786f62)
+ if (is_barebox_arm_head(_buf))
return filetype_arm_barebox;
if (buf[9] == 0x016f2818 || buf[9] == 0x18286f01)
return filetype_arm_zimage;
diff --git a/include/filetype.h b/include/filetype.h
index 37eb62020d..209dc11a3d 100644
--- a/include/filetype.h
+++ b/include/filetype.h
@@ -27,4 +27,20 @@ enum filetype file_detect_type(void *_buf);
enum filetype file_name_detect_type(const char *filename);
enum filetype is_fat_or_mbr(const unsigned char *sector, unsigned long *bootsec);
+#define ARM_HEAD_SIZE 0x30
+#define ARM_HEAD_MAGICWORD_OFFSET 0x20
+#define ARM_HEAD_SIZE_OFFSET 0x2C
+
+#ifdef CONFIG_ARM
+static inline int is_barebox_arm_head(const char *head)
+{
+ return !strcmp(head + ARM_HEAD_MAGICWORD_OFFSET, "barebox");
+}
+#else
+static inline int is_barebox_arm_head(const char *head)
+{
+ return 0;
+}
+#endif
+
#endif /* __FILE_TYPE_H */
diff --git a/scripts/.gitignore b/scripts/.gitignore
index 6e63f85792..3f1cbdb912 100644
--- a/scripts/.gitignore
+++ b/scripts/.gitignore
@@ -2,6 +2,7 @@ bareboxenv
bin2c
gen_netx_image
kallsyms
+mk-am35xx-spi-image
mkimage
mkublheader
omap_signGP
diff --git a/scripts/Makefile b/scripts/Makefile
index 7ca5e2973d..55ccdac539 100644
--- a/scripts/Makefile
+++ b/scripts/Makefile
@@ -9,7 +9,7 @@ hostprogs-y += bin2c
hostprogs-y += mkimage
hostprogs-y += bareboxenv
hostprogs-$(CONFIG_ARCH_NETX) += gen_netx_image
-hostprogs-$(CONFIG_ARCH_OMAP) += omap_signGP
+hostprogs-$(CONFIG_ARCH_OMAP) += omap_signGP mk-am35xx-spi-image
hostprogs-$(CONFIG_ARCH_S5PCxx) += s5p_cksum
hostprogs-$(CONFIG_ARCH_DAVINCI) += mkublheader
diff --git a/scripts/mk-am35xx-spi-image.c b/scripts/mk-am35xx-spi-image.c
new file mode 100644
index 0000000000..ec311fdd4d
--- /dev/null
+++ b/scripts/mk-am35xx-spi-image.c
@@ -0,0 +1,141 @@
+/*
+ * mk-am35xx-spi-image.c - convert a barebox image for SPI loading on AM35xx
+ *
+ * Copyright (C) 2012 Jan Luebbe <j.luebbe@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+/**
+ * @file
+ * @brief convert a barebox image for SPI loading on AM35xx
+ *
+ * FileName: scripts/mk-am35xx-spi-image.c
+ *
+ * Booting from SPI on an AM35xx (and possibly other TI SOCs) requires
+ * a special format:
+ *
+ * - 32 bit image size in big-endian
+ * - 32 bit load address in big-endian
+ * - binary image converted from little- to big-endian
+ *
+ * This tool converts barebox.bin to the required format.
+ */
+
+#define _BSD_SOURCE
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <limits.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <endian.h>
+
+void usage(char *prgname)
+{
+ printf("usage: %s [OPTION] FILE > IMAGE\n"
+ "\n"
+ "options:\n"
+ " -a <address> memory address for the loaded image in SRAM\n",
+ prgname);
+}
+
+int main(int argc, char *argv[])
+{
+ FILE *input;
+ int opt;
+ off_t pos;
+ size_t size;
+ uint32_t addr = 0x40200000;
+ uint32_t temp;
+
+ while((opt = getopt(argc, argv, "a:")) != -1) {
+ switch (opt) {
+ case 'a':
+ addr = strtoul(optarg, NULL, 0);
+ break;
+ }
+ }
+
+ if (optind >= argc) {
+ usage(argv[0]);
+ exit(1);
+ }
+
+ input = fopen(argv[optind], "r");
+ if (input == NULL) {
+ perror("fopen");
+ exit(EXIT_FAILURE);
+ }
+
+ if (fseeko(input, 0, SEEK_END) == -1) {
+ perror("fseeko");
+ exit(EXIT_FAILURE);
+ }
+
+ pos = ftello(input);
+ if (pos == -1) {
+ perror("ftello");
+ exit(EXIT_FAILURE);
+ }
+ if (pos % 4) {
+ printf("error: image size must be a multiple of 4 bytes\n");
+ exit(EXIT_FAILURE);
+ }
+ if (pos > 0x100000) {
+ printf("error: image should be smaller than 1 MiB\n");
+ exit(EXIT_FAILURE);
+ }
+
+ if (fseeko(input, 0, SEEK_SET) == -1) {
+ perror("fseeko");
+ exit(EXIT_FAILURE);
+ }
+
+ /* image size */
+ temp = htobe32((uint32_t)pos);
+ fwrite(&temp, sizeof(uint32_t), 1, stdout);
+
+ /* memory address */
+ temp = htobe32(addr);
+ fwrite(&temp, sizeof(uint32_t), 1, stdout);
+
+ for (;;) {
+ size = fread(&temp, 1, sizeof(uint32_t), input);
+ if (!size)
+ break;
+ if (size != 4) {
+ perror("fread");
+ exit(EXIT_FAILURE);
+ }
+ temp = htobe32(le32toh(temp));
+ if (fwrite(&temp, 1, sizeof(uint32_t), stdout) != 4) {
+ perror("fwrite");
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ if (fclose(input) != 0) {
+ perror("fclose");
+ exit(EXIT_FAILURE);
+ }
+
+ exit(EXIT_SUCCESS);
+}