diff options
-rw-r--r-- | arch/arm/mach-kirkwood/Kconfig | 2 | ||||
-rw-r--r-- | arch/arm/mach-kirkwood/Makefile | 1 | ||||
-rw-r--r-- | arch/arm/mach-kirkwood/cpu.c | 3 | ||||
-rw-r--r-- | arch/arm/mach-kirkwood/lowlevel.S | 12 | ||||
-rw-r--r-- | arch/arm/mach-mvebu/Kconfig | 10 | ||||
-rw-r--r-- | configs/n2350_defconfig | 3 | ||||
-rw-r--r-- | configs/nsa310s_defconfig | 4 | ||||
-rw-r--r-- | doc/kwboot.1 | 2 | ||||
-rw-r--r-- | drivers/ddr/marvell/a38x/ddr3_init.h | 1 | ||||
-rw-r--r-- | drivers/ddr/marvell/a38x/seq_exec.h | 64 | ||||
-rw-r--r-- | tools/kwbimage.c | 10 | ||||
-rw-r--r-- | tools/kwboot.c | 42 |
12 files changed, 84 insertions, 70 deletions
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig index b19ed2c6b3..54027ccb0e 100644 --- a/arch/arm/mach-kirkwood/Kconfig +++ b/arch/arm/mach-kirkwood/Kconfig @@ -5,9 +5,11 @@ config FEROCEON_88FR131 config KW88F6192 bool + select ARCH_VERY_EARLY_INIT config KW88F6281 bool + select ARCH_VERY_EARLY_INIT config SHEEVA_88SV131 bool diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index 3b2eef8d54..0fb5a2326f 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile @@ -6,6 +6,7 @@ obj-y = cpu.o obj-y += cache.o +obj-y += lowlevel.o obj-y += mpp.o # cpu.o and cache.o contain CP15 instructions which cannot be run in diff --git a/arch/arm/mach-kirkwood/cpu.c b/arch/arm/mach-kirkwood/cpu.c index df3e8f1178..2b493b36c2 100644 --- a/arch/arm/mach-kirkwood/cpu.c +++ b/arch/arm/mach-kirkwood/cpu.c @@ -189,9 +189,6 @@ int arch_cpu_init(void) struct kwcpu_registers *cpureg = (struct kwcpu_registers *)KW_CPU_REG_BASE; - /* Linux expects the internal registers to be at 0xf1000000 */ - writel(KW_REGS_PHY_BASE, KW_OFFSET_REG); - /* Enable and invalidate L2 cache in write through mode */ writel(readl(&cpureg->l2_cfg) | 0x18, &cpureg->l2_cfg); invalidate_l2_cache(); diff --git a/arch/arm/mach-kirkwood/lowlevel.S b/arch/arm/mach-kirkwood/lowlevel.S new file mode 100644 index 0000000000..6810384954 --- /dev/null +++ b/arch/arm/mach-kirkwood/lowlevel.S @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +#include <config.h> +#include <linux/linkage.h> + +ENTRY(arch_very_early_init) + /* Move internal registers from KW_OFFSET_REG to KW_REGS_PHY_BASE */ + ldr r0, =KW_REGS_PHY_BASE + ldr r1, =KW_OFFSET_REG + str r0, [r1] + bx lr +ENDPROC(arch_very_early_init) diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index fb3cff43f7..1f0dbef1c6 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig @@ -423,6 +423,16 @@ config SECURED_MODE_CSK_INDEX default 0 depends on SECURED_MODE_IMAGE +config SF_DEFAULT_SPEED + int "Default speed for SPI flash in Hz" + default 10000000 + depends on MVEBU_SPL_BOOT_DEVICE_SPI + +config SF_DEFAULT_MODE + hex "Default mode for SPI flash" + default 0x0 + depends on MVEBU_SPL_BOOT_DEVICE_SPI + source "board/solidrun/clearfog/Kconfig" source "board/kobol/helios4/Kconfig" diff --git a/configs/n2350_defconfig b/configs/n2350_defconfig index b85ef0dfeb..247533ebb8 100644 --- a/configs/n2350_defconfig +++ b/configs/n2350_defconfig @@ -69,6 +69,9 @@ CONFIG_SYS_64BIT_LBA=y CONFIG_DM_I2C=y CONFIG_SYS_I2C_MVTWSI=y CONFIG_MTD=y +CONFIG_MTD_RAW_NAND=y +CONFIG_NAND_PXA3XX=y +CONFIG_SYS_NAND_ONFI_DETECTION=y CONFIG_SF_DEFAULT_SPEED=50000000 CONFIG_SPI_FLASH_MACRONIX=y CONFIG_SPI_FLASH_STMICRO=y diff --git a/configs/nsa310s_defconfig b/configs/nsa310s_defconfig index 76839e62dd..b936ae1b25 100644 --- a/configs/nsa310s_defconfig +++ b/configs/nsa310s_defconfig @@ -15,8 +15,11 @@ CONFIG_ENV_SIZE=0x20000 CONFIG_ENV_OFFSET=0xE0000 CONFIG_DEFAULT_DEVICE_TREE="kirkwood-nsa310s" CONFIG_SYS_PROMPT="NSA310s> " +CONFIG_DEBUG_UART_BASE=0xf1012000 +CONFIG_DEBUG_UART_CLOCK=166666667 CONFIG_IDENT_STRING="\nZyXEL NSA310S/320S 1/2-Bay Power Media Server" CONFIG_SYS_LOAD_ADDR=0x800000 +CONFIG_DEBUG_UART=y CONFIG_DISTRO_DEFAULTS=y CONFIG_BOOTDELAY=3 CONFIG_USE_PREBOOT=y @@ -50,6 +53,7 @@ CONFIG_MTD_RAW_NAND=y CONFIG_PHY_MARVELL=y CONFIG_MVGBE=y CONFIG_MII=y +CONFIG_DEBUG_UART_SHIFT=2 CONFIG_USB=y CONFIG_USB_EHCI_HCD=y CONFIG_UBIFS_SILENCE_MSG=y diff --git a/doc/kwboot.1 b/doc/kwboot.1 index 5cda3b4d88..32d324f055 100644 --- a/doc/kwboot.1 +++ b/doc/kwboot.1 @@ -69,7 +69,7 @@ To get a BootROM help, type this command followed by ENTER key: .IP Armada 38x BootROM has a bug which cause that BootROM's standard output -is turned off on UART when SPI-NOR contains valid boot image. Nevertheless +is turned off on UART when default boot source location contains valid boot image. Nevertheless BootROM's standard input and BootROM's terminal echo are active and working fine. To workaround this BootROM bug with standard output, it is possible to manually overwrite BootROM variables stored in SRAM which BootROM use diff --git a/drivers/ddr/marvell/a38x/ddr3_init.h b/drivers/ddr/marvell/a38x/ddr3_init.h index ba9f7881d5..6854bb49de 100644 --- a/drivers/ddr/marvell/a38x/ddr3_init.h +++ b/drivers/ddr/marvell/a38x/ddr3_init.h @@ -9,7 +9,6 @@ #include "ddr_ml_wrapper.h" #include "mv_ddr_plat.h" -#include "seq_exec.h" #include "ddr3_logging_def.h" #include "ddr3_training_hw_algo.h" #include "ddr3_training_ip.h" diff --git a/drivers/ddr/marvell/a38x/seq_exec.h b/drivers/ddr/marvell/a38x/seq_exec.h deleted file mode 100644 index fe0cb8f75d..0000000000 --- a/drivers/ddr/marvell/a38x/seq_exec.h +++ /dev/null @@ -1,64 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) Marvell International Ltd. and its affiliates - */ - -#ifndef _SEQ_EXEC_H -#define _SEQ_EXEC_H - -#define NA 0xff -#define DEFAULT_PARAM 0 -#define MV_BOARD_TCLK_ERROR 0xffffffff - -#define NO_DATA 0xffffffff -#define MAX_DATA_ARRAY 5 -#define FIRST_CELL 0 - -/* Operation types */ -enum mv_op { - WRITE_OP, - DELAY_OP, - POLL_OP, -}; - -/* Operation parameters */ -struct op_params { - u32 unit_base_reg; - u32 unit_offset; - u32 mask; - u32 data[MAX_DATA_ARRAY]; /* data array */ - u8 wait_time; /* msec */ - u16 num_of_loops; /* for polling only */ -}; - -/* - * Sequence parameters. Each sequence contains: - * 1. Sequence id. - * 2. Sequence size (total amount of operations during the sequence) - * 3. a series of operations. operations can be write, poll or delay - * 4. index in the data array (the entry where the relevant data sits) - */ -struct cfg_seq { - struct op_params *op_params_ptr; - u8 cfg_seq_size; - u8 data_arr_idx; -}; - -extern struct cfg_seq serdes_seq_db[]; - -/* - * A generic function type for executing an operation (write, poll or delay) - */ -typedef int (*op_execute_func_ptr)(u32 serdes_num, struct op_params *params, - u32 data_arr_idx); - -/* Specific functions for executing each operation */ -int write_op_execute(u32 serdes_num, struct op_params *params, - u32 data_arr_idx); -int delay_op_execute(u32 serdes_num, struct op_params *params, - u32 data_arr_idx); -int poll_op_execute(u32 serdes_num, struct op_params *params, u32 data_arr_idx); -enum mv_op get_cfg_seq_op(struct op_params *params); -int mv_seq_exec(u32 serdes_num, u32 seq_id); - -#endif /*_SEQ_EXEC_H*/ diff --git a/tools/kwbimage.c b/tools/kwbimage.c index 309657a563..177084adf8 100644 --- a/tools/kwbimage.c +++ b/tools/kwbimage.c @@ -1231,6 +1231,16 @@ static size_t image_headersz_v1(int *hasext) if (count > 0) headersz += sizeof(struct register_set_hdr_v1) + 8 * count + 4; + /* + * For all images except UART, headersz stored in header itself should + * contains header size without padding. For UART image BootROM rounds + * down headersz to multiply of 128 bytes. Therefore align UART headersz + * to multiply of 128 bytes to ensure that remaining UART header bytes + * are not ignored by BootROM. + */ + if (image_get_bootfrom() == IBR_HDR_UART_ID) + headersz = ALIGN(headersz, 128); + return headersz; } diff --git a/tools/kwboot.c b/tools/kwboot.c index 7c666486f3..348a3203d6 100644 --- a/tools/kwboot.c +++ b/tools/kwboot.c @@ -61,7 +61,9 @@ * SPI-NOR or parallel-NOR. Despite the type name it really can be stored on * parallel-NOR and cannot be stored on other SPI devices, like SPI-NAND. * So it should have been named NOR image, not SPI image. This image type - * supports XIP - Execute In Place directly from NOR memory. + * supports XIP - Execute In Place directly from NOR memory. Destination + * address of the XIP image is set to 0xFFFFFFFF and execute address to the + * absolute offset in bytes from the beginning of NOR memory. * * - IBR_HDR_NAND_ID (0x8B): * NAND image can be stored either at any 2 MB aligned offset in the first @@ -78,6 +80,17 @@ * * - IBR_HDR_UART_ID (0x69): * UART image can be transfered via xmodem protocol over first UART. + * Unlike all other image types, header size stored in the image must be + * multiply of the 128 bytes (for all other image types it can be any size) + * and data part of the image does not have to contain 32-bit checksum + * (all other image types must have valid 32-bit checksum in its data part). + * And data size stored in the image is ignored. A38x BootROM determinates + * size of the data part implicitly by the end of the xmodem transfer. + * A38x BootROM has a bug which cause that BootROM loads data part of UART + * image into RAM target address increased by one byte when source address + * and header size stored in the image header are not same. So UART image + * should be constructed in a way that there is no gap between header and + * data part. * * - IBR_HDR_I2C_ID (0x4D): * It is unknown for what kind of storage is used this image. It is not @@ -1455,6 +1468,8 @@ kwboot_xmodem(int tty, const void *_img, size_t size, int baudrate) * followed by the header. So align header size to xmodem block size. */ hdrsz += (KWBOOT_XM_BLKSZ - hdrsz % KWBOOT_XM_BLKSZ) % KWBOOT_XM_BLKSZ; + if (hdrsz > size) + hdrsz = size; pnum = 1; @@ -2079,6 +2094,8 @@ kwboot_img_patch(void *img, size_t *size, int baudrate) goto err; } kwboot_img_grow_data_right(img, size, sizeof(uint32_t)); + /* Update the 32-bit data checksum */ + *kwboot_img_csum32_ptr(img) = kwboot_img_csum32(img); } if (!kwboot_img_has_ddr_init(img) && @@ -2168,6 +2185,29 @@ kwboot_img_patch(void *img, size_t *size, int baudrate) kwboot_printv("Aligning image header to Xmodem block size\n"); kwboot_img_grow_hdr(img, size, grow); + hdrsz += grow; + + /* + * kwbimage v1 contains header size field and for UART type it + * must be set to the aligned xmodem header size because BootROM + * rounds header size down to xmodem block size. + */ + if (kwbimage_version(img) == 1) { + hdr->headersz_msb = hdrsz >> 16; + hdr->headersz_lsb = cpu_to_le16(hdrsz & 0xffff); + } + } + + /* Header size and source address must be same for UART type due to A38x BootROM bug */ + if (hdrsz != le32_to_cpu(hdr->srcaddr)) { + if (is_secure) { + fprintf(stderr, "Cannot align image with secure header\n"); + goto err; + } + + kwboot_printv("Removing gap between image header and data\n"); + memmove(img + hdrsz, img + le32_to_cpu(hdr->srcaddr), le32_to_cpu(hdr->blocksize)); + hdr->srcaddr = cpu_to_le32(hdrsz); } hdr->checksum = kwboot_hdr_csum8(hdr) - csum; |