diff options
-rw-r--r-- | MAINTAINERS | 1 | ||||
-rw-r--r-- | arch/arc/Kconfig | 5 | ||||
-rw-r--r-- | arch/arc/cpu/u-boot.lds | 19 | ||||
-rw-r--r-- | arch/arc/dts/Makefile | 1 | ||||
-rw-r--r-- | arch/arc/dts/emdk.dts | 33 | ||||
-rw-r--r-- | arch/arc/lib/cache.c | 12 | ||||
-rw-r--r-- | arch/arc/lib/relocate.c | 76 | ||||
-rw-r--r-- | arch/arc/lib/reset.c | 14 | ||||
-rw-r--r-- | board/synopsys/emdk/Kconfig | 12 | ||||
-rw-r--r-- | board/synopsys/emdk/MAINTAINERS | 5 | ||||
-rw-r--r-- | board/synopsys/emdk/Makefile | 7 | ||||
-rw-r--r-- | board/synopsys/emdk/emdk.c | 92 | ||||
-rw-r--r-- | configs/emdk_defconfig | 31 | ||||
-rw-r--r-- | include/configs/emdk.h | 40 |
14 files changed, 308 insertions, 40 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 0289d9d5ad..f5ff57e87d 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -60,6 +60,7 @@ S: Maintained L: uboot-snps-arc@synopsys.com T: git git://git.denx.de/u-boot-arc.git F: arch/arc/ +F: board/synopsys/ ARC HSDK CGU CLOCK M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index aee15d5353..6f139d5bdc 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -150,6 +150,10 @@ config TARGET_AXS101 config TARGET_AXS103 bool "Support Synopsys Designware SDP board AXS103" +config TARGET_EMDK + bool "Synopsys EM Development kit" + select CPU_ARCEM6 + config TARGET_HSDK bool "Support Synpsys HS DevelopmentKit board" @@ -158,6 +162,7 @@ endchoice source "board/abilis/tb100/Kconfig" source "board/synopsys/Kconfig" source "board/synopsys/axs10x/Kconfig" +source "board/synopsys/emdk/Kconfig" source "board/synopsys/hsdk/Kconfig" endmenu diff --git a/arch/arc/cpu/u-boot.lds b/arch/arc/cpu/u-boot.lds index 73c642ed6b..e12145c768 100644 --- a/arch/arc/cpu/u-boot.lds +++ b/arch/arc/cpu/u-boot.lds @@ -5,28 +5,29 @@ #include <config.h> -OUTPUT_FORMAT("elf32-littlearc", "elf32-littlearc", "elf32-littlearc") +OUTPUT_FORMAT("elf32-littlearc", "elf32-bigarc", "elf32-littlearc") OUTPUT_ARCH(arc) ENTRY(_start) SECTIONS { . = CONFIG_SYS_TEXT_BASE; __image_copy_start = .; - __text_start = .; - .text : { - arch/arc/lib/start.o (.text*) - *(.text*) - } - __text_end = .; - . = ALIGN(1024); __ivt_start = .; .ivt : { - *(.ivt) + KEEP(*(.ivt)) } __ivt_end = .; + . = ALIGN(1024); + __text_start = .; + .text : { + arch/arc/lib/start.o (.text*) + *(.text*) + } + __text_end = .; + . = ALIGN(4); .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) diff --git a/arch/arc/dts/Makefile b/arch/arc/dts/Makefile index 6eccec97da..491a4f40bb 100644 --- a/arch/arc/dts/Makefile +++ b/arch/arc/dts/Makefile @@ -4,6 +4,7 @@ dtb-$(CONFIG_TARGET_AXS101) += axs101.dtb dtb-$(CONFIG_TARGET_AXS103) += axs103.dtb dtb-$(CONFIG_TARGET_NSIM) += nsim.dtb dtb-$(CONFIG_TARGET_TB100) += abilis_tb100.dtb +dtb-$(CONFIG_TARGET_EMDK) += emdk.dtb dtb-$(CONFIG_TARGET_HSDK) += hsdk.dtb targets += $(dtb-y) diff --git a/arch/arc/dts/emdk.dts b/arch/arc/dts/emdk.dts new file mode 100644 index 0000000000..5e853e3a72 --- /dev/null +++ b/arch/arc/dts/emdk.dts @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Synopsys, Inc. All rights reserved. + */ +/dts-v1/; + +#include "skeleton.dtsi" + +/ { + #address-cells = <1>; + #size-cells = <1>; + + aliases { + console = &uart0; + }; + + cpu_card { + core_clk: core_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <40000000>; + u-boot,dm-pre-reloc; + }; + }; + + uart0: serial0@f0004000 { + compatible = "snps,dw-apb-uart"; + clock-frequency = <100000000>; + reg = <0xf0004000 0x1000>; + reg-shift = <2>; + reg-io-width = <4>; + }; +}; diff --git a/arch/arc/lib/cache.c b/arch/arc/lib/cache.c index 6f52877643..8c1cb6e800 100644 --- a/arch/arc/lib/cache.c +++ b/arch/arc/lib/cache.c @@ -432,9 +432,16 @@ void read_decode_cache_bcr(void) int dc_line_sz = 0, ic_line_sz = 0; union bcr_di_cache ibcr, dbcr; + /* + * We don't care much about I$ line length really as there're + * no per-line ops on I$ instead we only do full invalidation of it + * on occasion of relocation and right before jumping to the OS. + * Still we check insane config with zero-encoded line length in + * presense of version field in I$ BCR. Just in case. + */ ibcr.word = read_aux_reg(ARC_BCR_IC_BUILD); if (ibcr.fields.ver) { - gd->arch.l1_line_sz = ic_line_sz = 8 << ibcr.fields.line_len; + ic_line_sz = 8 << ibcr.fields.line_len; if (!ic_line_sz) panic("Instruction exists but line length is 0\n"); } @@ -445,9 +452,6 @@ void read_decode_cache_bcr(void) if (!dc_line_sz) panic("Data cache exists but line length is 0\n"); } - - if (ic_line_sz && dc_line_sz && (ic_line_sz != dc_line_sz)) - panic("Instruction and data cache line lengths differ\n"); } void cache_init(void) diff --git a/arch/arc/lib/relocate.c b/arch/arc/lib/relocate.c index a3b7428d85..4ffba84eeb 100644 --- a/arch/arc/lib/relocate.c +++ b/arch/arc/lib/relocate.c @@ -8,7 +8,9 @@ #include <asm-generic/sections.h> extern ulong __image_copy_start; +extern ulong __ivt_start; extern ulong __ivt_end; +extern ulong __text_end; DECLARE_GLOBAL_DATA_PTR; @@ -48,7 +50,7 @@ int do_elf_reloc_fixups(void) debug("Section .rela.dyn is located at %08x-%08x\n", (unsigned int)re_src, (unsigned int)re_end); - Elf32_Addr *offset_ptr_rom, *last_offset = NULL; + Elf32_Addr *offset_ptr_rom; Elf32_Addr *offset_ptr_ram; do { @@ -57,15 +59,28 @@ int do_elf_reloc_fixups(void) /* Check that the location of the relocation is in .text */ if (offset_ptr_rom >= (Elf32_Addr *)&__image_copy_start && - offset_ptr_rom > last_offset) { - unsigned int val; + offset_ptr_rom < (Elf32_Addr *)&__image_copy_end) { + unsigned int val, do_swap = 0; /* Switch to the in-RAM version */ offset_ptr_ram = (Elf32_Addr *)((ulong)offset_ptr_rom + gd->reloc_off); - debug("Patching value @ %08x (relocated to %08x)\n", +#ifdef __LITTLE_ENDIAN__ + /* If location in ".text" section swap value */ + if (((u32)offset_ptr_rom >= (u32)&__text_start && + (u32)offset_ptr_rom <= (u32)&__text_end) +#if defined(__ARC700__) || defined(__ARC600__) + || ((u32)offset_ptr_rom >= (u32)&__ivt_start && + (u32)offset_ptr_rom <= (u32)&__ivt_end) +#endif + ) + do_swap = 1; +#endif + + debug("Patching value @ %08x (relocated to %08x)%s\n", (unsigned int)offset_ptr_rom, - (unsigned int)offset_ptr_ram); + (unsigned int)offset_ptr_ram, + do_swap ? ", middle-endian encoded" : ""); /* * Use "memcpy" because target location might be @@ -75,28 +90,45 @@ int do_elf_reloc_fixups(void) */ memcpy(&val, offset_ptr_ram, sizeof(int)); -#ifdef __LITTLE_ENDIAN__ - /* If location in ".text" section swap value */ - if ((unsigned int)offset_ptr_rom < - (unsigned int)&__ivt_end) + if (do_swap) val = (val << 16) | (val >> 16); -#endif /* Check that the target points into executable */ - if (val >= (unsigned int)&__image_copy_start && val <= - (unsigned int)&__image_copy_end) { - val += gd->reloc_off; -#ifdef __LITTLE_ENDIAN__ - /* If location in ".text" section swap value */ - if ((unsigned int)offset_ptr_rom < - (unsigned int)&__ivt_end) - val = (val << 16) | (val >> 16); -#endif - memcpy(offset_ptr_ram, &val, sizeof(int)); + if (val < (unsigned int)&__image_copy_start || + val > (unsigned int)&__image_copy_end) { + /* TODO: Use panic() instead of debug() + * + * For some reason GCC might generate + * fake relocation even for LD/SC of constant + * inderectly. See an example below: + * ----------------------->8-------------------- + * static int setup_mon_len(void) + * { + * gd->mon_len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE; + * return 0; + * } + * ----------------------->8-------------------- + * + * And that's what we get in the binary: + * ----------------------->8-------------------- + * 10005cb4 <setup_mon_len>: + * 10005cb4: 193c 3f80 0003 2f80 st 0x32f80,[r25,60] + * 10005cb8: R_ARC_RELATIVE *ABS*-0x10000000 + * 10005cbc: 7fe0 j_s.d [blink] + * 10005cbe: 700c mov_s r0,0 + * ----------------------->8-------------------- + */ + debug("Relocation target %08x points outside of image\n", + val); } - } - last_offset = offset_ptr_rom; + val += gd->reloc_off; + + if (do_swap) + val = (val << 16) | (val >> 16); + + memcpy(offset_ptr_ram, &val, sizeof(int)); + } } while (++re_src < re_end); return 0; diff --git a/arch/arc/lib/reset.c b/arch/arc/lib/reset.c index 40fb0f1fbd..02e08df48d 100644 --- a/arch/arc/lib/reset.c +++ b/arch/arc/lib/reset.c @@ -6,13 +6,17 @@ #include <command.h> #include <common.h> +__weak void reset_cpu(ulong addr) +{ + /* Stop debug session here */ + __builtin_arc_brk(); +} + int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - printf("Put your restart handler here\n"); + printf("Resetting the board...\n"); + + reset_cpu(0); -#ifdef DEBUG - /* Stop debug session here */ - __asm__("brk"); -#endif return 0; } diff --git a/board/synopsys/emdk/Kconfig b/board/synopsys/emdk/Kconfig new file mode 100644 index 0000000000..a9b834dbfd --- /dev/null +++ b/board/synopsys/emdk/Kconfig @@ -0,0 +1,12 @@ +if TARGET_EMDK + +config SYS_BOARD + default "emdk" + +config SYS_VENDOR + default "synopsys" + +config SYS_CONFIG_NAME + default "emdk" + +endif diff --git a/board/synopsys/emdk/MAINTAINERS b/board/synopsys/emdk/MAINTAINERS new file mode 100644 index 0000000000..605e338445 --- /dev/null +++ b/board/synopsys/emdk/MAINTAINERS @@ -0,0 +1,5 @@ +EM DEVELOPMENT KIT BOARD +M: Alexey Brodkin <abrodkin@synopsys.com> +S: Maintained +F: board/synopsys/emdk/ +F: configs/emdk_defconfig diff --git a/board/synopsys/emdk/Makefile b/board/synopsys/emdk/Makefile new file mode 100644 index 0000000000..4926c4e307 --- /dev/null +++ b/board/synopsys/emdk/Makefile @@ -0,0 +1,7 @@ +# +# Copyright (C) 2018 Synopsys, Inc. All rights reserved. +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += emdk.o diff --git a/board/synopsys/emdk/emdk.c b/board/synopsys/emdk/emdk.c new file mode 100644 index 0000000000..bbb946a700 --- /dev/null +++ b/board/synopsys/emdk/emdk.c @@ -0,0 +1,92 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 Synopsys, Inc. All rights reserved. + */ + +#include <common.h> +#include <dwmmc.h> +#include <malloc.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define ARC_PERIPHERAL_BASE 0xF0000000 +#define SDIO_BASE (ARC_PERIPHERAL_BASE + 0x10000) + +int board_mmc_init(bd_t *bis) +{ + struct dwmci_host *host = NULL; + + host = malloc(sizeof(struct dwmci_host)); + if (!host) { + printf("dwmci_host malloc fail!\n"); + return 1; + } + + memset(host, 0, sizeof(struct dwmci_host)); + host->name = "Synopsys Mobile storage"; + host->ioaddr = (void *)SDIO_BASE; + host->buswidth = 4; + host->dev_index = 0; + host->bus_hz = 50000000; + + add_dwmci(host, host->bus_hz / 2, 400000); + + return 0; +} + +#define CREG_BASE 0xF0001000 +#define CREG_BOOT_OFFSET 0 +#define CREG_BOOT_WP_OFFSET 8 + +#define CGU_BASE 0xF0000000 +#define CGU_IP_SW_RESET 0x0FF0 + +void reset_cpu(ulong addr) +{ + writel(1, (u32 *)(CGU_BASE + CGU_IP_SW_RESET)); + while (1) + ; /* loop forever till reset */ +} + +static int do_emdk_rom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + u32 creg_boot = readl((u32 *)(CREG_BASE + CREG_BOOT_OFFSET)); + + if (!strcmp(argv[1], "unlock")) + creg_boot &= ~BIT(CREG_BOOT_WP_OFFSET); + else if (!strcmp(argv[1], "lock")) + creg_boot |= BIT(CREG_BOOT_WP_OFFSET); + else + return CMD_RET_USAGE; + + writel(creg_boot, (u32 *)(CREG_BASE + CREG_BOOT_OFFSET)); + + return CMD_RET_SUCCESS; +} + +cmd_tbl_t cmd_emdk[] = { + U_BOOT_CMD_MKENT(rom, 2, 0, do_emdk_rom, "", ""), +}; + +static int do_emdk(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) +{ + cmd_tbl_t *c; + + c = find_cmd_tbl(argv[1], cmd_emdk, ARRAY_SIZE(cmd_emdk)); + + /* Strip off leading 'emdk' command */ + argc--; + argv++; + + if (c == NULL || argc > c->maxargs) + return CMD_RET_USAGE; + + return c->cmd(cmdtp, flag, argc, argv); +} + +U_BOOT_CMD( + emdk, CONFIG_SYS_MAXARGS, 0, do_emdk, + "Synopsys EMDK specific commands", + "rom unlock - Unlock non-volatile memory for writing\n" + "emdk rom lock - Lock non-volatile memory to prevent writing\n" +); diff --git a/configs/emdk_defconfig b/configs/emdk_defconfig new file mode 100644 index 0000000000..e3bccd234f --- /dev/null +++ b/configs/emdk_defconfig @@ -0,0 +1,31 @@ +CONFIG_ARC=y +CONFIG_ISA_ARCV2=y +CONFIG_CPU_ARCEM6=y +CONFIG_TARGET_EMDK=y +CONFIG_SYS_TEXT_BASE=0x00000000 +CONFIG_SYS_CLK_FREQ=40000000 +CONFIG_DEFAULT_DEVICE_TREE="emdk" +# CONFIG_ARCH_FIXUP_FDT_MEMORY is not set +CONFIG_VERSION_VARIABLE=y +CONFIG_HUSH_PARSER=y +CONFIG_SYS_PROMPT="emdk# " +# CONFIG_CMD_BOOTD is not set +# CONFIG_CMD_ELF is not set +# CONFIG_CMD_XIMG is not set +CONFIG_CMD_MMC=y +CONFIG_CMD_CACHE=y +CONFIG_CMD_FAT=y +CONFIG_OF_CONTROL=y +CONFIG_OF_EMBED=y +CONFIG_ENV_IS_IN_FAT=y +CONFIG_ENV_FAT_INTERFACE="mmc" +CONFIG_ENV_FAT_DEVICE_AND_PART="0:1" +# CONFIG_NET is not set +CONFIG_DM=y +CONFIG_MMC=y +CONFIG_MMC_DW=y +CONFIG_DM_SERIAL=y +CONFIG_SYS_NS16550=y +CONFIG_FS_FAT_MAX_CLUSTSIZE=4096 +CONFIG_USE_PRIVATE_LIBGCC=y +CONFIG_PANIC_HANG=y diff --git a/include/configs/emdk.h b/include/configs/emdk.h new file mode 100644 index 0000000000..dca13e2fff --- /dev/null +++ b/include/configs/emdk.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2018 Synopsys, Inc. All rights reserved. + */ + +#ifndef _CONFIG_EMDK_H_ +#define _CONFIG_EMDK_H_ + +#include <linux/sizes.h> + +#define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE + +#define CONFIG_SYS_SDRAM_BASE 0x10000000 +#define CONFIG_SYS_SDRAM_SIZE SZ_8M + +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + SZ_1M) + +#define CONFIG_SYS_MALLOC_LEN SZ_64K +#define CONFIG_SYS_LOAD_ADDR CONFIG_SYS_SDRAM_BASE + +/* Required by DW MMC driver */ +#define CONFIG_BOUNCE_BUFFER + +/* + * Environment + */ +#define CONFIG_ENV_SIZE SZ_4K +#define CONFIG_BOOTFILE "app.bin" +#define CONFIG_LOADADDR CONFIG_SYS_LOAD_ADDR + +#define CONFIG_EXTRA_ENV_SETTINGS \ + "upgrade_image=u-boot.bin\0" \ + "upgrade=emdk rom unlock && " \ + "fatload mmc 0 ${loadaddr} ${upgrade_image} && " \ + "cp.b ${loadaddr} 0 ${filesize} && " \ + "dcache flush && " \ + "emdk rom lock\0" + +#endif /* _CONFIG_EMDK_H_ */ + |