diff --git a/arch/arm/configs/mvebu_defconfig b/arch/arm/configs/mvebu_defconfig index 39e7ef1..dab3d7a 100644 --- a/arch/arm/configs/mvebu_defconfig +++ b/arch/arm/configs/mvebu_defconfig @@ -10,6 +10,7 @@ CONFIG_MACH_USI_TOPKICK=y CONFIG_AEABI=y CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_MMU=y CONFIG_TEXT_BASE=0x0 CONFIG_MALLOC_SIZE=0x0 CONFIG_MALLOC_TLSF=y diff --git a/arch/mips/configs/qemu-malta_defconfig b/arch/mips/configs/qemu-malta_defconfig index 004adac..9671e93 100644 --- a/arch/mips/configs/qemu-malta_defconfig +++ b/arch/mips/configs/qemu-malta_defconfig @@ -1,6 +1,7 @@ CONFIG_BUILTIN_DTB=y CONFIG_BUILTIN_DTB_NAME="qemu-malta" CONFIG_PBL_IMAGE=y +CONFIG_BAREBOX_MAX_IMAGE_SIZE=0x400000 CONFIG_STACK_SIZE=0x7000 CONFIG_EXPERIMENTAL=y CONFIG_BAUDRATE=38400 diff --git a/arch/x86/boot/boot_hdisk.S b/arch/x86/boot/boot_hdisk.S index 143336d..6f98197 100644 --- a/arch/x86/boot/boot_hdisk.S +++ b/arch/x86/boot/boot_hdisk.S @@ -164,7 +164,7 @@ .section .boot_data -notification_string: .asciz "UBOOT2 " +notification_string: .asciz "BAREBOX " chs_string: .asciz "CHS " jmp_string: .asciz "JMP " diff --git a/drivers/spi/mvebu_spi.c b/drivers/spi/mvebu_spi.c index 1d619e0..14ab396 100644 --- a/drivers/spi/mvebu_spi.c +++ b/drivers/spi/mvebu_spi.c @@ -31,8 +31,13 @@ #define IF_READ_READY BIT(1) #define IF_CS_ENABLE BIT(0) #define SPI_IF_CONFIG 0x04 + +#define IF_RXLSBF BIT(14) +#define IF_TXLSBF BIT(13) + #define IF_CLK_DIV(x) ((x) << 11) #define IF_CLK_DIV_MASK (0x7 << 11) + #define IF_FAST_READ BIT(10) #define IF_ADDRESS_LEN_4BYTE (3 << 8) #define IF_ADDRESS_LEN_3BYTE (2 << 8) @@ -43,8 +48,8 @@ #define IF_TRANSFER_2BYTE BIT(5) #define IF_CLK_PRESCALE_POW2 BIT(4) #define IF_CLK_PRESCALE(x) ((x) & 0x0f) -#define IF_CLK_PRE_PRESCALE(x) (((((x) & 0xc) << 1) | ((x) & 0x1)) << 4) -#define IF_CLK_PRESCALE_MASK (IF_CLK_PRESCALE(7) | IF_CLK_PRE_PRESCALE(7)) +#define IF_CLK_PRE_PRESCALE(x) (((((x) & 0x6) << 6) | ((x) & 0x1)) << 4) +#define IF_CLK_PRESCALE_MASK (IF_CLK_PRESCALE(0xf) | IF_CLK_PRE_PRESCALE(7)) #define SPI_DATA_OUT 0x08 #define SPI_DATA_IN 0x0c #define SPI_INT_CAUSE 0x10 @@ -128,22 +133,21 @@ #if defined(CONFIG_ARCH_ARMADA_370) || defined(CONFIG_ARCH_ARMADA_XP) static int armada_370_xp_spi_set_baudrate(struct mvebu_spi *p, u32 speed) { - u32 pscl, pdiv, rate, val; + u32 pscl, pdiv = 0, val; /* prescaler values: 1,2,3,...,15 */ pscl = DIV_ROUND_UP(clk_get_rate(p->clk), speed); /* additional prescaler divider: 1, 2, 4, 8, 16, 32, 64, 128 */ - pdiv = 0; rate = pscl; - while (rate > 15 && pdiv <= 7) { - rate /= 2; + while (pscl > 15 && pdiv <= 7) { + pscl = DIV_ROUND_UP(pscl, 2); pdiv++; } - dev_dbg(p->master.dev, "%s: clk = %lu, speed = %u, pscl = %d, pdiv = %d\n", + dev_dbg(p->master.dev, "%s: clk = %lu, speed = %u, pscl = %u, pdiv = %u\n", __func__, clk_get_rate(p->clk), speed, pscl, pdiv); - if (rate > 15 || pdiv > 7) + if (pscl > 15) return -EINVAL; val = readl(p->base + SPI_IF_CONFIG) & ~(IF_CLK_PRESCALE_MASK); @@ -193,6 +197,8 @@ static int mvebu_spi_set_mode(struct mvebu_spi *p, u8 mode) { + u32 val; + /* * From public datasheets of Orion SoCs, it is unclear * if the SPI controller supports setting CPOL/CPHA. @@ -203,12 +209,19 @@ * other mode than SPI_MODE0. */ - if ((mode & (SPI_CPOL|SPI_CPHA)) == SPI_MODE_0) - return 0; + if ((mode & (SPI_CPOL|SPI_CPHA)) != SPI_MODE_0) { + pr_err("%s: unsupported SPI mode %02x\n", __func__, mode); + return -EINVAL; + } - pr_err("%s: unsupported SPI mode %02x\n", __func__, mode); + val = readl(p->base + SPI_IF_CONFIG); + if (mode & SPI_LSB_FIRST) + val |= IF_RXLSBF | IF_TXLSBF; + else + val &= ~(IF_RXLSBF | IF_TXLSBF); + writel(val, p->base + SPI_IF_CONFIG); - return -EINVAL; + return 0; } static int mvebu_spi_setup(struct spi_device *spi) @@ -234,13 +247,11 @@ static inline int mvebu_spi_wait_for_read_ready(struct mvebu_spi *p) { - int timeout = 100; - while ((readl(p->base + SPI_IF_CTRL) & IF_READ_READY) == 0 && - timeout--) - udelay(1); - if (timeout < 0) - return -EIO; - return 0; + int ret; + + ret = wait_on_timeout(100 * USECOND, + readl(p->base + SPI_IF_CTRL) & IF_READ_READY); + return ret; } static int mvebu_spi_do_transfer(struct spi_device *spi, @@ -253,13 +264,19 @@ if (t->bits_per_word) ret = mvebu_spi_set_transfer_size(priv, spi->bits_per_word); - if (ret) + if (ret) { + dev_err(&spi->dev, "Failed to set transfer size (bpw = %u)\n", + (unsigned)spi->bits_per_word); return ret; + } if (t->speed_hz) ret = priv->set_baudrate(priv, t->speed_hz); - if (ret) + if (ret) { + dev_err(&spi->dev, "Failed to set baudrate to %u Hz\n", + (unsigned)t->speed_hz); return ret; + } inc = (priv->data16) ? 2 : 1; for (n = 0; n < t->len; n += inc) { @@ -279,12 +296,12 @@ return ret; } - data = readl(priv->base + SPI_DATA_IN); - - if (rxdata) + if (rxdata) { + data = readl(priv->base + SPI_DATA_IN); *rxdata++ = (data & 0xff); - if (rxdata && priv->data16) - *rxdata++ = (data >> 8) & 0xff; + if (priv->data16) + *rxdata++ = (data >> 8) & 0xff; + } } return 0; @@ -296,23 +313,31 @@ int ret; struct mvebu_spi *priv = priv_from_spi_device(spi); - ret = mvebu_spi_set_cs(priv, spi->chip_select, spi->mode, true); - if (ret) + ret = mvebu_spi_set_mode(priv, spi->mode); + if (ret) { + dev_err(&spi->dev, "Failed to set mode (0x%x)\n", (unsigned)spi->mode); return ret; + } + + ret = mvebu_spi_set_cs(priv, spi->chip_select, spi->mode, true); + if (ret) { + dev_err(&spi->dev, "Failed to set chip select\n"); + return ret; + } msg->actual_length = 0; list_for_each_entry(t, &msg->transfers, transfer_list) { ret = mvebu_spi_do_transfer(spi, t); if (ret) - break; + goto err_transfer; msg->actual_length += t->len; } - ret = mvebu_spi_set_cs(priv, spi->chip_select, spi->mode, false); - if (ret) - return ret; + return mvebu_spi_set_cs(priv, spi->chip_select, spi->mode, false); +err_transfer: + mvebu_spi_set_cs(priv, spi->chip_select, spi->mode, false); return ret; } diff --git a/scripts/kwbimage.c b/scripts/kwbimage.c index 448ac2a..5b84db3 100644 --- a/scripts/kwbimage.c +++ b/scripts/kwbimage.c @@ -347,6 +347,7 @@ printf(" -h: this help text\n"); printf(" Options specific to image creation:\n"); printf(" -p: path to payload image. Overrides the PAYLOAD line from kwbimage.cfg\n"); + printf(" -b: path to binary image. Overrides the BINARY line from kwbimage.cfg\n"); printf(" -m: boot media. Overrides the BOOT_FROM line from kwbimage.cfg\n"); printf(" -d: load address. Overrides the DEST_ADDR line from kwbimage.cfg\n"); printf(" -e: exec address. Overrides the EXEC_ADDR line from kwbimage.cfg\n"); @@ -490,7 +491,7 @@ } ret = fwrite(binary + (nargs + 1) * sizeof(unsigned int), - binsz - (nargs + 1) * sizeof(unsigned int), 1, + binsz - (nargs + 2) * sizeof(unsigned int), 1, binaryout); if (ret != 1) { fprintf(stderr, "Could not write to output file %s\n", @@ -523,7 +524,7 @@ int opthdrid; /* - * Verify the checkum. We have to substract the checksum + * Verify the checksum. We have to subtract the checksum * itself, because when the checksum is calculated, the * checksum field is 0. */ @@ -869,8 +870,8 @@ return NULL; } - headersz += s.st_size + - binarye->binary.nargs * sizeof(unsigned int); + headersz += ALIGN_SUP(s.st_size, 4) + + 12 + binarye->binary.nargs * sizeof(unsigned int); hasext = 1; } @@ -886,7 +887,7 @@ } /* payload size must be multiple of 32b */ - payloadsz = 4 * ((s.st_size + 3)/4); + payloadsz = ALIGN_SUP(s.st_size, 4); } /* The payload should be aligned on some reasonable @@ -951,8 +952,8 @@ fstat(fileno(bin), &s); binhdrsz = sizeof(struct opt_hdr_v1) + - (binarye->binary.nargs + 1) * sizeof(unsigned int) + - s.st_size; + (binarye->binary.nargs + 2) * sizeof(unsigned int) + + ALIGN_SUP(s.st_size, 4); hdr->headersz_lsb = binhdrsz & 0xFFFF; hdr->headersz_msb = (binhdrsz & 0xFFFF0000) >> 16; @@ -976,7 +977,7 @@ fclose(bin); - cur += s.st_size; + cur += ALIGN_SUP(s.st_size, 4); /* * For now, we don't support more than one binary @@ -1186,6 +1187,30 @@ return 0; } +static int image_override_binary(struct image_cfg_element *image_cfg, + int *cfgn, char *binary) +{ + struct image_cfg_element *e; + int cfgi = *cfgn; + + if (!binary) + return 0; + + e = image_find_option(image_cfg, *cfgn, IMAGE_CFG_BINARY); + if (e) { + e->binary.file = binary; + return 0; + } + + image_cfg[cfgi].type = IMAGE_CFG_BINARY; + image_cfg[cfgi].binary.file = binary; + image_cfg[cfgi].binary.nargs = 0; + cfgi++; + + *cfgn = cfgi; + return 0; +} + static int image_override_bootmedia(struct image_cfg_element *image_cfg, int *cfgn, const char *bootmedia) { @@ -1332,9 +1357,9 @@ } static int image_create(const char *input, const char *output, - const char *payload, const char *bootmedia, - uint32_t dstaddr, uint32_t execaddr, - int verbose) + const char *payload, char *binary, + const char *bootmedia, uint32_t dstaddr, + uint32_t execaddr, int verbose) { struct image_cfg_element *image_cfg; FILE *outputimg; @@ -1361,6 +1386,7 @@ } image_override_payload(image_cfg, &cfgn, payload); + image_override_binary(image_cfg, &cfgn, binary); image_override_bootmedia(image_cfg, &cfgn, bootmedia); image_override_dstaddr(image_cfg, &cfgn, dstaddr); image_override_execaddr(image_cfg, &cfgn, execaddr); @@ -1433,9 +1459,10 @@ int action = -1, opt, verbose = 0; const char *input = NULL, *output = NULL, *payload = NULL, *bootmedia = NULL; + char *binary = NULL; uint32_t execaddr = ADDR_INVALID, dstaddr = ADDR_INVALID; - while ((opt = getopt(argc, argv, "hxci:o:p:m:e:d:v")) != -1) { + while ((opt = getopt(argc, argv, "hxci:o:p:b:m:e:d:v")) != -1) { switch (opt) { case 'x': action = ACTION_EXTRACT; @@ -1452,6 +1479,9 @@ case 'p': payload = optarg; break; + case 'b': + binary = optarg; + break; case 'm': bootmedia = optarg; break; @@ -1502,7 +1532,7 @@ case ACTION_EXTRACT: return image_extract(input, output); case ACTION_CREATE: - return image_create(input, output, payload, + return image_create(input, output, payload, binary, bootmedia, dstaddr, execaddr, verbose); case ACTION_HELP: