diff options
Diffstat (limited to 'roms/u-boot/arch/arm/mach-zynq')
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/Kconfig | 76 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/Makefile | 16 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/clk.c | 108 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/cpu.c | 145 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/ddrc.c | 49 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/include/mach/clk.h | 22 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/include/mach/gpio.h | 10 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/include/mach/hardware.h | 133 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/include/mach/ps7_init_gpl.h | 47 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/include/mach/sys_proto.h | 22 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/lowlevel_init.S | 25 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/ps7_spl_init.c | 147 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/slcr.c | 199 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/spl.c | 87 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/timer.c | 113 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/u-boot-spl.lds | 64 | ||||
-rw-r--r-- | roms/u-boot/arch/arm/mach-zynq/u-boot.lds | 139 |
17 files changed, 1402 insertions, 0 deletions
diff --git a/roms/u-boot/arch/arm/mach-zynq/Kconfig b/roms/u-boot/arch/arm/mach-zynq/Kconfig new file mode 100644 index 000000000..e54310383 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/Kconfig @@ -0,0 +1,76 @@ +if ARCH_ZYNQ + +config SPL_LDSCRIPT + default "arch/arm/mach-zynq/u-boot-spl.lds" + +config SPL_FS_FAT + default y + +config SPL_LIBCOMMON_SUPPORT + default y + +config SPL_LIBDISK_SUPPORT + default y + +config SPL_LIBGENERIC_SUPPORT + default y + +config SPL_MMC_SUPPORT + default y if MMC_SDHCI_ZYNQ + +config SPL_SERIAL_SUPPORT + default y + +config SPL_SPI_FLASH_SUPPORT + default y if ZYNQ_QSPI + +config SPL_SPI_SUPPORT + default y if ZYNQ_QSPI + +config ZYNQ_DDRC_INIT + bool "Zynq DDRC initialization" + default y + help + This option used to perform DDR specific initialization + if required. There might be cases like ddr less where we + want to skip ddr init and this option is useful for it. + +config SYS_BOARD + string "Board name" + default "zynq" + +config SYS_VENDOR + string "Vendor name" + default "xilinx" + +config SYS_SOC + default "zynq" + +config SYS_CONFIG_NAME + string "Board configuration name" + default "zynq-common" + help + This option contains information about board configuration name. + Based on this option include/configs/<CONFIG_SYS_CONFIG_NAME>.h header + will be used for board configuration. + +config SYS_MALLOC_F_LEN + default 0x800 + +config SYS_MALLOC_LEN + default 0x1400000 + +config BOOT_INIT_FILE + string "boot.bin init register filename" + default "" + help + Add register writes to boot.bin format (max 256 pairs). + Expect a table of register-value pairs, e.g. "0x12345678 0x4321" + +config ZYNQ_SDHCI_MAX_FREQ + default 52000000 + +source "board/xilinx/Kconfig" +source "board/xilinx/zynq/Kconfig" + +endif diff --git a/roms/u-boot/arch/arm/mach-zynq/Makefile b/roms/u-boot/arch/arm/mach-zynq/Makefile new file mode 100644 index 000000000..8737f434d --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/Makefile @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# (C) Copyright 2008 +# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + +obj-y := timer.o +obj-y += cpu.o +obj-y += ddrc.o +obj-y += slcr.o +obj-y += clk.o +obj-y += lowlevel_init.o +AFLAGS_lowlevel_init.o := -mfpu=neon +obj-$(CONFIG_SPL_BUILD) += spl.o ps7_spl_init.o diff --git a/roms/u-boot/arch/arm/mach-zynq/clk.c b/roms/u-boot/arch/arm/mach-zynq/clk.c new file mode 100644 index 000000000..27f6bf218 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/clk.c @@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2013 Soren Brinkmann <soren.brinkmann@xilinx.com> + * Copyright (C) 2013 Xilinx, Inc. All rights reserved. + */ +#include <clk.h> +#include <common.h> +#include <dm.h> +#include <init.h> +#include <malloc.h> +#include <asm/arch/clk.h> +#include <asm/global_data.h> + +DECLARE_GLOBAL_DATA_PTR; + +static const char * const clk_names[clk_max] = { + "armpll", "ddrpll", "iopll", + "cpu_6or4x", "cpu_3or2x", "cpu_2x", "cpu_1x", + "ddr2x", "ddr3x", "dci", + "lqspi", "smc", "pcap", "gem0", "gem1", + "fclk0", "fclk1", "fclk2", "fclk3", "can0", "can1", + "sdio0", "sdio1", "uart0", "uart1", "spi0", "spi1", "dma", + "usb0_aper", "usb1_aper", "gem0_aper", "gem1_aper", + "sdio0_aper", "sdio1_aper", "spi0_aper", "spi1_aper", + "can0_aper", "can1_aper", "i2c0_aper", "i2c1_aper", + "uart0_aper", "uart1_aper", "gpio_aper", "lqspi_aper", + "smc_aper", "swdt", "dbg_trc", "dbg_apb" +}; + +/** + * set_cpu_clk_info() - Setup clock information + * + * This function is called from common code after relocation and sets up the + * clock information. + */ +int set_cpu_clk_info(void) +{ + struct clk clk; + struct udevice *dev; + ulong rate; + int i, ret; + + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(zynq_clk), &dev); + if (ret) + return ret; + + for (i = 0; i < 2; i++) { + clk.id = i ? ddr3x_clk : cpu_6or4x_clk; + ret = clk_request(dev, &clk); + if (ret < 0) + return ret; + + rate = clk_get_rate(&clk) / 1000000; + if (i) + gd->bd->bi_ddr_freq = rate; + else + gd->bd->bi_arm_freq = rate; + + clk_free(&clk); + } + gd->bd->bi_dsp_freq = 0; + + return 0; +} + +/** + * soc_clk_dump() - Print clock frequencies + * Returns zero on success + * + * Implementation for the clk dump command. + */ +int soc_clk_dump(void) +{ + struct udevice *dev; + int i, ret; + + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(zynq_clk), &dev); + if (ret) + return ret; + + printf("clk\t\tfrequency\n"); + for (i = 0; i < clk_max; i++) { + const char *name = clk_names[i]; + if (name) { + struct clk clk; + unsigned long rate; + + clk.id = i; + ret = clk_request(dev, &clk); + if (ret < 0) + return ret; + + rate = clk_get_rate(&clk); + + clk_free(&clk); + + if ((rate == (unsigned long)-ENOSYS) || + (rate == (unsigned long)-ENXIO)) + printf("%10s%20s\n", name, "unknown"); + else + printf("%10s%20lu\n", name, rate); + } + } + + return 0; +} diff --git a/roms/u-boot/arch/arm/mach-zynq/cpu.c b/roms/u-boot/arch/arm/mach-zynq/cpu.c new file mode 100644 index 000000000..69b818f24 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/cpu.c @@ -0,0 +1,145 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2012 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2012 Xilinx, Inc. All rights reserved. + */ +#include <common.h> +#include <cpu_func.h> +#include <init.h> +#include <zynqpl.h> +#include <asm/cache.h> +#include <asm/io.h> +#include <asm/arch/clk.h> +#include <asm/arch/hardware.h> +#include <asm/arch/ps7_init_gpl.h> +#include <asm/arch/sys_proto.h> + +#define ZYNQ_SILICON_VER_MASK 0xF0000000 +#define ZYNQ_SILICON_VER_SHIFT 28 + +#if CONFIG_IS_ENABLED(FPGA) +xilinx_desc fpga = { + .family = xilinx_zynq, + .iface = devcfg, + .operations = &zynq_op, +}; +#endif + +static const struct { + u8 idcode; +#if defined(CONFIG_FPGA) + u32 fpga_size; +#endif + char *devicename; +} zynq_fpga_descs[] = { + ZYNQ_DESC(7Z007S), + ZYNQ_DESC(7Z010), + ZYNQ_DESC(7Z012S), + ZYNQ_DESC(7Z014S), + ZYNQ_DESC(7Z015), + ZYNQ_DESC(7Z020), + ZYNQ_DESC(7Z030), + ZYNQ_DESC(7Z035), + ZYNQ_DESC(7Z045), + ZYNQ_DESC(7Z100), + { /* Sentinel */ }, +}; + +int arch_cpu_init(void) +{ + zynq_slcr_unlock(); +#ifndef CONFIG_SPL_BUILD + /* Device config APB, unlock the PCAP */ + writel(0x757BDF0D, &devcfg_base->unlock); + writel(0xFFFFFFFF, &devcfg_base->rom_shadow); + +#if (CONFIG_SYS_SDRAM_BASE == 0) + /* remap DDR to zero, FILTERSTART */ + writel(0, &scu_base->filter_start); + + /* OCM_CFG, Mask out the ROM, map ram into upper addresses */ + writel(0x1F, &slcr_base->ocm_cfg); + /* FPGA_RST_CTRL, clear resets on AXI fabric ports */ + writel(0x0, &slcr_base->fpga_rst_ctrl); + /* Set urgent bits with register */ + writel(0x0, &slcr_base->ddr_urgent_sel); + /* Urgent write, ports S2/S3 */ + writel(0xC, &slcr_base->ddr_urgent); +#endif +#endif + zynq_slcr_lock(); + + return 0; +} + +unsigned int zynq_get_silicon_version(void) +{ + return (readl(&devcfg_base->mctrl) & ZYNQ_SILICON_VER_MASK) + >> ZYNQ_SILICON_VER_SHIFT; +} + +void reset_cpu(void) +{ + zynq_slcr_cpu_reset(); + while (1) + ; +} + +#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} +#endif + +static int __maybe_unused cpu_desc_id(void) +{ + u32 idcode; + u8 i; + + idcode = zynq_slcr_get_idcode(); + for (i = 0; zynq_fpga_descs[i].idcode; i++) { + if (zynq_fpga_descs[i].idcode == idcode) + return i; + } + + return -ENODEV; +} + +#if defined(CONFIG_ARCH_EARLY_INIT_R) +int arch_early_init_r(void) +{ +#if CONFIG_IS_ENABLED(FPGA) + int cpu_id = cpu_desc_id(); + + if (cpu_id < 0) + return 0; + + fpga.size = zynq_fpga_descs[cpu_id].fpga_size; + fpga.name = zynq_fpga_descs[cpu_id].devicename; + fpga_init(); + fpga_add(fpga_xilinx, &fpga); +#endif + return 0; +} +#endif + +#ifdef CONFIG_DISPLAY_CPUINFO +int print_cpuinfo(void) +{ + u32 version; + int cpu_id = cpu_desc_id(); + + if (cpu_id < 0) + return 0; + + version = zynq_get_silicon_version() << 1; + if (version > (PCW_SILICON_VERSION_3 << 1)) + version += 1; + + printf("CPU: Zynq %s\n", zynq_fpga_descs[cpu_id].devicename); + printf("Silicon: v%d.%d\n", version >> 1, version & 1); + return 0; +} +#endif diff --git a/roms/u-boot/arch/arm/mach-zynq/ddrc.c b/roms/u-boot/arch/arm/mach-zynq/ddrc.c new file mode 100644 index 000000000..28988ef95 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/ddrc.c @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2012 - 2013 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2012 - 2017 Xilinx, Inc. All rights reserved. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/hardware.h> + +#ifndef CONFIG_ZYNQ_DDRC_INIT +void zynq_ddrc_init(void) {} +#else +/* Control regsiter bitfield definitions */ +#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_MASK 0xC +#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_SHIFT 2 +#define ZYNQ_DDRC_CTRLREG_BUSWIDTH_16BIT 1 + +/* ECC scrub regsiter definitions */ +#define ZYNQ_DDRC_ECC_SCRUBREG_ECC_MODE_MASK 0x7 +#define ZYNQ_DDRC_ECC_SCRUBREG_ECCMODE_SECDED 0x4 + +void zynq_ddrc_init(void) +{ + u32 width, ecctype; + + width = readl(&ddrc_base->ddrc_ctrl); + width = (width & ZYNQ_DDRC_CTRLREG_BUSWIDTH_MASK) >> + ZYNQ_DDRC_CTRLREG_BUSWIDTH_SHIFT; + ecctype = (readl(&ddrc_base->ecc_scrub) & + ZYNQ_DDRC_ECC_SCRUBREG_ECC_MODE_MASK); + + /* ECC is enabled when memory is in 16bit mode and it is enabled */ + if ((ecctype == ZYNQ_DDRC_ECC_SCRUBREG_ECCMODE_SECDED) && + (width == ZYNQ_DDRC_CTRLREG_BUSWIDTH_16BIT)) { + puts("ECC enabled "); + /* + * Clear the first 1MB because it is not initialized from + * first stage bootloader. To get ECC to work all memory has + * been initialized by writing any value. + */ + /* cppcheck-suppress nullPointer */ + memset((void *)0, 0, 1 * 1024 * 1024); + } else { + puts("ECC disabled "); + } +} +#endif diff --git a/roms/u-boot/arch/arm/mach-zynq/include/mach/clk.h b/roms/u-boot/arch/arm/mach-zynq/include/mach/clk.h new file mode 100644 index 000000000..4fff9f452 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/include/mach/clk.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2013 Xilinx Inc. + */ + +#ifndef _ZYNQ_CLK_H_ +#define _ZYNQ_CLK_H_ + +enum zynq_clk { + armpll_clk, ddrpll_clk, iopll_clk, + cpu_6or4x_clk, cpu_3or2x_clk, cpu_2x_clk, cpu_1x_clk, + ddr2x_clk, ddr3x_clk, dci_clk, + lqspi_clk, smc_clk, pcap_clk, gem0_clk, gem1_clk, + fclk0_clk, fclk1_clk, fclk2_clk, fclk3_clk, can0_clk, can1_clk, + sdio0_clk, sdio1_clk, uart0_clk, uart1_clk, spi0_clk, spi1_clk, dma_clk, + usb0_aper_clk, usb1_aper_clk, gem0_aper_clk, gem1_aper_clk, + sdio0_aper_clk, sdio1_aper_clk, spi0_aper_clk, spi1_aper_clk, + can0_aper_clk, can1_aper_clk, i2c0_aper_clk, i2c1_aper_clk, + uart0_aper_clk, uart1_aper_clk, gpio_aper_clk, lqspi_aper_clk, + smc_aper_clk, swdt_clk, dbg_trc_clk, dbg_apb_clk, clk_max}; + +#endif diff --git a/roms/u-boot/arch/arm/mach-zynq/include/mach/gpio.h b/roms/u-boot/arch/arm/mach-zynq/include/mach/gpio.h new file mode 100644 index 000000000..6143e2456 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/include/mach/gpio.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2013 Xilinx, Inc. + * Copyright (c) 2015 DAVE Embedded Systems + */ + +#ifndef _ZYNQ_GPIO_H +#define _ZYNQ_GPIO_H + +#endif /* _ZYNQ_GPIO_H */ diff --git a/roms/u-boot/arch/arm/mach-zynq/include/mach/hardware.h b/roms/u-boot/arch/arm/mach-zynq/include/mach/hardware.h new file mode 100644 index 000000000..89eb565c9 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/include/mach/hardware.h @@ -0,0 +1,133 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2013 Xilinx Inc. + */ + +#ifndef _ASM_ARCH_HARDWARE_H +#define _ASM_ARCH_HARDWARE_H + +#define ZYNQ_SYS_CTRL_BASEADDR 0xF8000000 +#define ZYNQ_DEV_CFG_APB_BASEADDR 0xF8007000 +#define ZYNQ_SCU_BASEADDR 0xF8F00000 +#define ZYNQ_DDRC_BASEADDR 0xF8006000 +#define ZYNQ_EFUSE_BASEADDR 0xF800D000 +#define ZYNQ_OCM_BASEADDR 0xFFFC0000 + +/* Bootmode setting values */ +#define ZYNQ_BM_MASK 0x7 +#define ZYNQ_BM_QSPI 0x1 +#define ZYNQ_BM_NOR 0x2 +#define ZYNQ_BM_NAND 0x4 +#define ZYNQ_BM_SD 0x5 +#define ZYNQ_BM_JTAG 0x0 + +/* Reflect slcr offsets */ +struct slcr_regs { + u32 scl; /* 0x0 */ + u32 slcr_lock; /* 0x4 */ + u32 slcr_unlock; /* 0x8 */ + u32 reserved0_1[61]; + u32 arm_pll_ctrl; /* 0x100 */ + u32 ddr_pll_ctrl; /* 0x104 */ + u32 io_pll_ctrl; /* 0x108 */ + u32 reserved0_2[5]; + u32 arm_clk_ctrl; /* 0x120 */ + u32 ddr_clk_ctrl; /* 0x124 */ + u32 dci_clk_ctrl; /* 0x128 */ + u32 aper_clk_ctrl; /* 0x12c */ + u32 reserved0_3[2]; + u32 gem0_rclk_ctrl; /* 0x138 */ + u32 gem1_rclk_ctrl; /* 0x13c */ + u32 gem0_clk_ctrl; /* 0x140 */ + u32 gem1_clk_ctrl; /* 0x144 */ + u32 smc_clk_ctrl; /* 0x148 */ + u32 lqspi_clk_ctrl; /* 0x14c */ + u32 sdio_clk_ctrl; /* 0x150 */ + u32 uart_clk_ctrl; /* 0x154 */ + u32 spi_clk_ctrl; /* 0x158 */ + u32 can_clk_ctrl; /* 0x15c */ + u32 can_mioclk_ctrl; /* 0x160 */ + u32 dbg_clk_ctrl; /* 0x164 */ + u32 pcap_clk_ctrl; /* 0x168 */ + u32 reserved0_4[1]; + u32 fpga0_clk_ctrl; /* 0x170 */ + u32 reserved0_5[3]; + u32 fpga1_clk_ctrl; /* 0x180 */ + u32 reserved0_6[3]; + u32 fpga2_clk_ctrl; /* 0x190 */ + u32 reserved0_7[3]; + u32 fpga3_clk_ctrl; /* 0x1a0 */ + u32 reserved0_8[8]; + u32 clk_621_true; /* 0x1c4 */ + u32 reserved1[14]; + u32 pss_rst_ctrl; /* 0x200 */ + u32 reserved2[15]; + u32 fpga_rst_ctrl; /* 0x240 */ + u32 reserved3[5]; + u32 reboot_status; /* 0x258 */ + u32 boot_mode; /* 0x25c */ + u32 reserved4[116]; + u32 trust_zone; /* 0x430 */ /* FIXME */ + u32 reserved5_1[63]; + u32 pss_idcode; /* 0x530 */ + u32 reserved5_2[51]; + u32 ddr_urgent; /* 0x600 */ + u32 reserved6[6]; + u32 ddr_urgent_sel; /* 0x61c */ + u32 reserved7[56]; + u32 mio_pin[54]; /* 0x700 - 0x7D4 */ + u32 reserved8[74]; + u32 lvl_shftr_en; /* 0x900 */ + u32 reserved9[3]; + u32 ocm_cfg; /* 0x910 */ +}; + +#define slcr_base ((struct slcr_regs *)ZYNQ_SYS_CTRL_BASEADDR) + +struct devcfg_regs { + u32 ctrl; /* 0x0 */ + u32 lock; /* 0x4 */ + u32 cfg; /* 0x8 */ + u32 int_sts; /* 0xc */ + u32 int_mask; /* 0x10 */ + u32 status; /* 0x14 */ + u32 dma_src_addr; /* 0x18 */ + u32 dma_dst_addr; /* 0x1c */ + u32 dma_src_len; /* 0x20 */ + u32 dma_dst_len; /* 0x24 */ + u32 rom_shadow; /* 0x28 */ + u32 reserved1[2]; + u32 unlock; /* 0x34 */ + u32 reserved2[18]; + u32 mctrl; /* 0x80 */ + u32 reserved3; + u32 write_count; /* 0x88 */ + u32 read_count; /* 0x8c */ +}; + +#define devcfg_base ((struct devcfg_regs *)ZYNQ_DEV_CFG_APB_BASEADDR) + +struct scu_regs { + u32 reserved1[16]; + u32 filter_start; /* 0x40 */ + u32 filter_end; /* 0x44 */ +}; + +#define scu_base ((struct scu_regs *)ZYNQ_SCU_BASEADDR) + +struct ddrc_regs { + u32 ddrc_ctrl; /* 0x0 */ + u32 reserved[60]; + u32 ecc_scrub; /* 0xF4 */ +}; +#define ddrc_base ((struct ddrc_regs *)ZYNQ_DDRC_BASEADDR) + +struct efuse_reg { + u32 reserved1[4]; + u32 status; + u32 reserved2[3]; +}; + +#define efuse_base ((struct efuse_reg *)ZYNQ_EFUSE_BASEADDR) + +#endif /* _ASM_ARCH_HARDWARE_H */ diff --git a/roms/u-boot/arch/arm/mach-zynq/include/mach/ps7_init_gpl.h b/roms/u-boot/arch/arm/mach-zynq/include/mach/ps7_init_gpl.h new file mode 100644 index 000000000..bd46a9b31 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/include/mach/ps7_init_gpl.h @@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * (c) Copyright 2010-2014 Xilinx, Inc. All rights reserved. + * (c) Copyright 2016 Topic Embedded Products. + */ + +#ifndef _ASM_ARCH_PS7_INIT_GPL_H +#define _ASM_ARCH_PS7_INIT_GPL_H + +/* Opcode exit is 0 all the time */ +#define OPCODE_EXIT 0U +#define OPCODE_MASKWRITE 0U +#define OPCODE_MASKPOLL 1U +#define OPCODE_MASKDELAY 2U +#define OPCODE_WRITE 3U +#define OPCODE_ADDRESS_MASK (~3U) + +/* Sentinel */ +#define EMIT_EXIT() OPCODE_EXIT +/* Opcode is in lower 2 bits of address, address is always 4-byte aligned */ +#define EMIT_MASKWRITE(addr, mask, val) OPCODE_MASKWRITE | addr, mask, val +#define EMIT_MASKPOLL(addr, mask) OPCODE_MASKPOLL | addr, mask +#define EMIT_MASKDELAY(addr, mask) OPCODE_MASKDELAY | addr, mask +#define EMIT_WRITE(addr, val) OPCODE_WRITE | addr, val + +/* Returns codes of ps7_init* */ +#define PS7_INIT_SUCCESS (0) +#define PS7_INIT_CORRUPT (1) +#define PS7_INIT_TIMEOUT (2) +#define PS7_POLL_FAILED_DDR_INIT (3) +#define PS7_POLL_FAILED_DMA (4) +#define PS7_POLL_FAILED_PLL (5) + +#define PCW_SILICON_VERSION_1 0 +#define PCW_SILICON_VERSION_2 1 +#define PCW_SILICON_VERSION_3 2 + +/* Called by spl.c */ +int ps7_init(void); +int ps7_post_config(void); + +/* Defined in ps7_init_common.c */ +int ps7_config(unsigned long *ps7_config_init); + +unsigned long ps7GetSiliconVersion(void); + +#endif /* _ASM_ARCH_PS7_INIT_GPL_H */ diff --git a/roms/u-boot/arch/arm/mach-zynq/include/mach/sys_proto.h b/roms/u-boot/arch/arm/mach-zynq/include/mach/sys_proto.h new file mode 100644 index 000000000..1dc16d479 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/include/mach/sys_proto.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2013 Xilinx Inc. + */ + +#ifndef _SYS_PROTO_H_ +#define _SYS_PROTO_H_ + +extern void zynq_slcr_lock(void); +extern void zynq_slcr_unlock(void); +extern void zynq_slcr_cpu_reset(void); +extern void zynq_slcr_devcfg_disable(void); +extern void zynq_slcr_devcfg_enable(void); +extern u32 zynq_slcr_get_boot_mode(void); +extern u32 zynq_slcr_get_idcode(void); +extern int zynq_slcr_get_mio_pin_status(const char *periph); +extern void zynq_ddrc_init(void); +extern unsigned int zynq_get_silicon_version(void); + +int zynq_board_read_rom_ethaddr(unsigned char *ethaddr); + +#endif /* _SYS_PROTO_H_ */ diff --git a/roms/u-boot/arch/arm/mach-zynq/lowlevel_init.S b/roms/u-boot/arch/arm/mach-zynq/lowlevel_init.S new file mode 100644 index 000000000..ed7329d9a --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/lowlevel_init.S @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2013 - 2015 Xilinx, Inc. All rights reserved. + */ + +#include <asm-offsets.h> +#include <config.h> +#include <linux/linkage.h> + +ENTRY(lowlevel_init) + + /* Enable the the VFP */ + mrc p15, 0, r1, c1, c0, 2 + orr r1, r1, #(0x3 << 20) + orr r1, r1, #(0x3 << 20) + mcr p15, 0, r1, c1, c0, 2 + isb + fmrx r1, FPEXC + orr r1,r1, #(1<<30) + fmxr FPEXC, r1 + + /* Move back to caller */ + mov pc, lr + +ENDPROC(lowlevel_init) diff --git a/roms/u-boot/arch/arm/mach-zynq/ps7_spl_init.c b/roms/u-boot/arch/arm/mach-zynq/ps7_spl_init.c new file mode 100644 index 000000000..4c38724d4 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/ps7_spl_init.c @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (c) Copyright 2010-2017 Xilinx, Inc. All rights reserved. + * (c) Copyright 2016 Topic Embedded Products. + */ + +#include <asm/io.h> +#include <asm/spl.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/ps7_init_gpl.h> + +__weak int ps7_init(void) +{ + /* + * This function is overridden by the one in + * board/xilinx/zynq/(platform)/ps7_init_gpl.c, if it exists. + */ + return 0; +} + +__weak int ps7_post_config(void) +{ + /* + * This function is overridden by the one in + * board/xilinx/zynq/(platform)/ps7_init_gpl.c, if it exists. + */ + return 0; +} + +/* For delay calculation using global registers*/ +#define SCU_GLOBAL_TIMER_COUNT_L32 0xF8F00200 +#define SCU_GLOBAL_TIMER_COUNT_U32 0xF8F00204 +#define SCU_GLOBAL_TIMER_CONTROL 0xF8F00208 +#define SCU_GLOBAL_TIMER_AUTO_INC 0xF8F00218 +#define APU_FREQ 666666666 + +#define PS7_MASK_POLL_TIME 100000000 + +/* IO accessors. No memory barriers desired. */ +static inline void iowrite(unsigned long val, unsigned long addr) +{ + __raw_writel(val, addr); +} + +static inline unsigned long ioread(unsigned long addr) +{ + return __raw_readl(addr); +} + +/* start timer */ +static void perf_start_clock(void) +{ + iowrite((1 << 0) | /* Timer Enable */ + (1 << 3) | /* Auto-increment */ + (0 << 8), /* Pre-scale */ + SCU_GLOBAL_TIMER_CONTROL); +} + +/* Compute mask for given delay in miliseconds*/ +static unsigned long get_number_of_cycles_for_delay(unsigned long delay) +{ + return (APU_FREQ / (2 * 1000)) * delay; +} + +/* stop timer */ +static void perf_disable_clock(void) +{ + iowrite(0, SCU_GLOBAL_TIMER_CONTROL); +} + +/* stop timer and reset timer count regs */ +static void perf_reset_clock(void) +{ + perf_disable_clock(); + iowrite(0, SCU_GLOBAL_TIMER_COUNT_L32); + iowrite(0, SCU_GLOBAL_TIMER_COUNT_U32); +} + +static void perf_reset_and_start_timer(void) +{ + perf_reset_clock(); + perf_start_clock(); +} + +int __weak ps7_config(unsigned long *ps7_config_init) +{ + unsigned long *ptr = ps7_config_init; + unsigned long opcode; + unsigned long addr; + unsigned long val; + unsigned long mask; + unsigned int numargs; + int i; + unsigned long delay; + + for (;;) { + opcode = ptr[0]; + if (opcode == OPCODE_EXIT) + return PS7_INIT_SUCCESS; + addr = (opcode & OPCODE_ADDRESS_MASK); + + switch (opcode & ~OPCODE_ADDRESS_MASK) { + case OPCODE_MASKWRITE: + numargs = 3; + mask = ptr[1]; + val = ptr[2]; + iowrite((ioread(addr) & ~mask) | (val & mask), addr); + break; + + case OPCODE_WRITE: + numargs = 2; + val = ptr[1]; + iowrite(val, addr); + break; + + case OPCODE_MASKPOLL: + numargs = 2; + mask = ptr[1]; + i = 0; + while (!(ioread(addr) & mask)) { + if (i == PS7_MASK_POLL_TIME) + return PS7_INIT_TIMEOUT; + i++; + } + break; + + case OPCODE_MASKDELAY: + numargs = 2; + mask = ptr[1]; + delay = get_number_of_cycles_for_delay(mask); + perf_reset_and_start_timer(); + while (ioread(addr) < delay) + ; + break; + + default: + return PS7_INIT_CORRUPT; + } + + ptr += numargs; + } +} + +unsigned long __weak __maybe_unused ps7GetSiliconVersion(void) +{ + return zynq_get_silicon_version(); +} diff --git a/roms/u-boot/arch/arm/mach-zynq/slcr.c b/roms/u-boot/arch/arm/mach-zynq/slcr.c new file mode 100644 index 000000000..5d9f4d23f --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/slcr.c @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2013 - 2017 Xilinx Inc. + */ + +#include <common.h> +#include <asm/io.h> +#include <malloc.h> +#include <asm/arch/hardware.h> +#include <asm/arch/sys_proto.h> + +#define SLCR_LOCK_MAGIC 0x767B +#define SLCR_UNLOCK_MAGIC 0xDF0D + +#define SLCR_NAND_L2_SEL 0x10 +#define SLCR_NAND_L2_SEL_MASK 0x1F + +#define SLCR_USB_L1_SEL 0x04 + +#define SLCR_IDCODE_MASK 0x1F000 +#define SLCR_IDCODE_SHIFT 12 + +/* + * zynq_slcr_mio_get_status - Get the status of MIO peripheral. + * + * @peri_name: Name of the peripheral for checking MIO status + * @get_pins: Pointer to array of get pin for this peripheral + * @num_pins: Number of pins for this peripheral + * @mask: Mask value + * @check_val: Required check value to get the status of periph + */ +struct zynq_slcr_mio_get_status { + const char *peri_name; + const int *get_pins; + int num_pins; + u32 mask; + u32 check_val; +}; + +static const int nand8_pins[] = { + 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 +}; + +static const int nand16_pins[] = { + 16, 17, 18, 19, 20, 21, 22, 23 +}; + +static const int usb0_pins[] = { + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39 +}; + +static const int usb1_pins[] = { + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 +}; + +static const struct zynq_slcr_mio_get_status mio_periphs[] = { + { + "nand8", + nand8_pins, + ARRAY_SIZE(nand8_pins), + SLCR_NAND_L2_SEL_MASK, + SLCR_NAND_L2_SEL, + }, + { + "nand16", + nand16_pins, + ARRAY_SIZE(nand16_pins), + SLCR_NAND_L2_SEL_MASK, + SLCR_NAND_L2_SEL, + }, + { + "usb0", + usb0_pins, + ARRAY_SIZE(usb0_pins), + SLCR_USB_L1_SEL, + SLCR_USB_L1_SEL, + }, + { + "usb1", + usb1_pins, + ARRAY_SIZE(usb1_pins), + SLCR_USB_L1_SEL, + SLCR_USB_L1_SEL, + }, +}; + +static int slcr_lock = 1; /* 1 means locked, 0 means unlocked */ + +void zynq_slcr_lock(void) +{ + if (!slcr_lock) { + writel(SLCR_LOCK_MAGIC, &slcr_base->slcr_lock); + slcr_lock = 1; + } +} + +void zynq_slcr_unlock(void) +{ + if (slcr_lock) { + writel(SLCR_UNLOCK_MAGIC, &slcr_base->slcr_unlock); + slcr_lock = 0; + } +} + +/* Reset the entire system */ +void zynq_slcr_cpu_reset(void) +{ + /* + * Unlock the SLCR then reset the system. + * Note that this seems to require raw i/o + * functions or there's a lockup? + */ + zynq_slcr_unlock(); + + /* + * Clear 0x0F000000 bits of reboot status register to workaround + * the FSBL not loading the bitstream after soft-reboot + * This is a temporary solution until we know more. + */ + clrbits_le32(&slcr_base->reboot_status, 0xF000000); + + writel(1, &slcr_base->pss_rst_ctrl); +} + +void zynq_slcr_devcfg_disable(void) +{ + u32 reg_val; + + zynq_slcr_unlock(); + + /* Disable AXI interface by asserting FPGA resets */ + writel(0xF, &slcr_base->fpga_rst_ctrl); + + /* Disable Level shifters before setting PS-PL */ + reg_val = readl(&slcr_base->lvl_shftr_en); + reg_val &= ~0xF; + writel(reg_val, &slcr_base->lvl_shftr_en); + + /* Set Level Shifters DT618760 */ + writel(0xA, &slcr_base->lvl_shftr_en); + + zynq_slcr_lock(); +} + +void zynq_slcr_devcfg_enable(void) +{ + zynq_slcr_unlock(); + + /* Set Level Shifters DT618760 */ + writel(0xF, &slcr_base->lvl_shftr_en); + + /* Enable AXI interface by de-asserting FPGA resets */ + writel(0x0, &slcr_base->fpga_rst_ctrl); + + zynq_slcr_lock(); +} + +u32 zynq_slcr_get_boot_mode(void) +{ + /* Get the bootmode register value */ + return readl(&slcr_base->boot_mode); +} + +u32 zynq_slcr_get_idcode(void) +{ + return (readl(&slcr_base->pss_idcode) & SLCR_IDCODE_MASK) >> + SLCR_IDCODE_SHIFT; +} + +/* + * zynq_slcr_get_mio_pin_status - Get the MIO pin status of peripheral. + * + * @periph: Name of the peripheral + * + * Returns count to indicate the number of pins configured for the + * given @periph. + */ +int zynq_slcr_get_mio_pin_status(const char *periph) +{ + const struct zynq_slcr_mio_get_status *mio_ptr; + int val, j; + int mio = 0; + u32 i; + + for (i = 0; i < ARRAY_SIZE(mio_periphs); i++) { + if (strcmp(periph, mio_periphs[i].peri_name) == 0) { + mio_ptr = &mio_periphs[i]; + for (j = 0; j < mio_ptr->num_pins; j++) { + val = readl(&slcr_base->mio_pin + [mio_ptr->get_pins[j]]); + if ((val & mio_ptr->mask) == mio_ptr->check_val) + mio++; + } + break; + } + } + + return mio; +} diff --git a/roms/u-boot/arch/arm/mach-zynq/spl.c b/roms/u-boot/arch/arm/mach-zynq/spl.c new file mode 100644 index 000000000..d09141c3b --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/spl.c @@ -0,0 +1,87 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2014 - 2017 Xilinx, Inc. Michal Simek + */ +#include <common.h> +#include <debug_uart.h> +#include <hang.h> +#include <image.h> +#include <init.h> +#include <log.h> +#include <spl.h> + +#include <asm/io.h> +#include <asm/spl.h> +#include <asm/arch/hardware.h> +#include <asm/arch/sys_proto.h> +#include <asm/arch/ps7_init_gpl.h> + +void board_init_f(ulong dummy) +{ + ps7_init(); + + arch_cpu_init(); + +#ifdef CONFIG_DEBUG_UART + /* Uart debug for sure */ + debug_uart_init(); + puts("Debug uart enabled\n"); /* or printch() */ +#endif +} + +#ifdef CONFIG_SPL_BOARD_INIT +void spl_board_init(void) +{ + preloader_console_init(); +#if defined(CONFIG_ARCH_EARLY_INIT_R) && defined(CONFIG_SPL_FPGA) + arch_early_init_r(); +#endif + board_init(); +} +#endif + +u32 spl_boot_device(void) +{ + u32 mode; + + switch ((zynq_slcr_get_boot_mode()) & ZYNQ_BM_MASK) { +#ifdef CONFIG_SPL_SPI_SUPPORT + case ZYNQ_BM_QSPI: + mode = BOOT_DEVICE_SPI; + break; +#endif + case ZYNQ_BM_NAND: + mode = BOOT_DEVICE_NAND; + break; + case ZYNQ_BM_NOR: + mode = BOOT_DEVICE_NOR; + break; +#ifdef CONFIG_SPL_MMC_SUPPORT + case ZYNQ_BM_SD: + mode = BOOT_DEVICE_MMC1; + break; +#endif + case ZYNQ_BM_JTAG: + mode = BOOT_DEVICE_RAM; + break; + default: + puts("Unsupported boot mode selected\n"); + hang(); + } + + return mode; +} + +#ifdef CONFIG_SPL_OS_BOOT +int spl_start_uboot(void) +{ + /* boot linux */ + return 0; +} +#endif + +void spl_board_prepare_for_boot(void) +{ + ps7_post_config(); + debug("SPL bye\n"); +} diff --git a/roms/u-boot/arch/arm/mach-zynq/timer.c b/roms/u-boot/arch/arm/mach-zynq/timer.c new file mode 100644 index 000000000..a51822a53 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/timer.c @@ -0,0 +1,113 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017 Weidmüller Interface GmbH & Co. KG + * Stefan Herbrechtsmeier <stefan.herbrechtsmeier@weidmueller.com> + * + * Copyright (C) 2012 Michal Simek <monstr@monstr.eu> + * Copyright (C) 2011-2017 Xilinx, Inc. All rights reserved. + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de> + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. <philippe.robin@arm.com> + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de> + * + * (C) Copyright 2003 + * Texas Instruments <www.ti.com> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger <mgroeger@sysgo.de> + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Alex Zuepke <azu@sysgo.de> + */ + +#include <clk.h> +#include <common.h> +#include <div64.h> +#include <dm.h> +#include <init.h> +#include <time.h> +#include <malloc.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <asm/arch/hardware.h> +#include <asm/arch/clk.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct scu_timer { + u32 load; /* Timer Load Register */ + u32 counter; /* Timer Counter Register */ + u32 control; /* Timer Control Register */ +}; + +static struct scu_timer *timer_base = + (struct scu_timer *)ZYNQ_SCUTIMER_BASEADDR; + +#define SCUTIMER_CONTROL_PRESCALER_MASK 0x0000FF00 /* Prescaler */ +#define SCUTIMER_CONTROL_PRESCALER_SHIFT 8 +#define SCUTIMER_CONTROL_AUTO_RELOAD_MASK 0x00000002 /* Auto-reload */ +#define SCUTIMER_CONTROL_ENABLE_MASK 0x00000001 /* Timer enable */ + +#define TIMER_LOAD_VAL 0xFFFFFFFF +#define TIMER_PRESCALE 255 + +int timer_init(void) +{ + const u32 emask = SCUTIMER_CONTROL_AUTO_RELOAD_MASK | + (TIMER_PRESCALE << SCUTIMER_CONTROL_PRESCALER_SHIFT) | + SCUTIMER_CONTROL_ENABLE_MASK; + + struct udevice *dev; + struct clk clk; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_CLK, + DM_DRIVER_GET(zynq_clk), &dev); + if (ret) + return ret; + + clk.id = cpu_6or4x_clk; + ret = clk_request(dev, &clk); + if (ret < 0) + return ret; + + gd->cpu_clk = clk_get_rate(&clk); + + clk_free(&clk); + + gd->arch.timer_rate_hz = (gd->cpu_clk / 2) / (TIMER_PRESCALE + 1); + + /* Load the timer counter register */ + writel(0xFFFFFFFF, &timer_base->load); + + /* + * Start the A9Timer device + * Enable Auto reload mode, Clear prescaler control bits + * Set prescaler value, Enable the decrementer + */ + clrsetbits_le32(&timer_base->control, SCUTIMER_CONTROL_PRESCALER_MASK, + emask); + + /* Reset time */ + gd->arch.lastinc = readl(&timer_base->counter) / + (gd->arch.timer_rate_hz / CONFIG_SYS_HZ); + gd->arch.tbl = 0; + + return 0; +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return gd->arch.timer_rate_hz; +} diff --git a/roms/u-boot/arch/arm/mach-zynq/u-boot-spl.lds b/roms/u-boot/arch/arm/mach-zynq/u-boot-spl.lds new file mode 100644 index 000000000..106d2e390 --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/u-boot-spl.lds @@ -0,0 +1,64 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2014 Xilinx, Inc. Michal Simek + * Copyright (c) 2004-2008 Texas Instruments + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + */ + +MEMORY { .sram : ORIGIN = IMAGE_TEXT_BASE,\ + LENGTH = IMAGE_MAX_SIZE } +MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \ + LENGTH = CONFIG_SPL_BSS_MAX_SIZE } + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = ALIGN(4); + .text : + { + __image_copy_start = .; + *(.vectors) + CPUDIR/start.o (.text*) + *(.text*) + } > .sram + + . = ALIGN(4); + .rodata : { + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) + } > .sram + + . = ALIGN(4); + .data : { + *(.data*) + } > .sram + + . = ALIGN(4); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } > .sram + + . = ALIGN(4); + + _image_binary_end = .; + + _end = .; + + /* Move BSS section to RAM because of FAT */ + .bss (NOLOAD) : { + __bss_start = .; + *(.bss*) + . = ALIGN(4); + __bss_end = .; + } > .sdram + + /DISCARD/ : { *(.dynsym) } + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } +} diff --git a/roms/u-boot/arch/arm/mach-zynq/u-boot.lds b/roms/u-boot/arch/arm/mach-zynq/u-boot.lds new file mode 100644 index 000000000..91c32e89e --- /dev/null +++ b/roms/u-boot/arch/arm/mach-zynq/u-boot.lds @@ -0,0 +1,139 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2004-2008 Texas Instruments + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de> + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0x00000000; + + . = ALIGN(4); + .text : + { + *(.__image_copy_start) + *(.vectors) + CPUDIR/start.o (.text*) + } + + /* This needs to come before *(.text*) */ + .__efi_runtime_start : { + *(.__efi_runtime_start) + } + + .efi_runtime : { + *(.text.efi_runtime*) + *(.rodata.efi_runtime*) + *(.data.efi_runtime*) + } + + .__efi_runtime_stop : { + *(.__efi_runtime_stop) + } + + .text_rest : + { + *(.text*) + } + + . = ALIGN(4); + .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) } + + . = ALIGN(4); + .data : { + *(.data*) + } + + . = ALIGN(4); + + . = .; + + . = ALIGN(4); + .u_boot_list : { + KEEP(*(SORT(.u_boot_list*))); + } + + . = ALIGN(4); + + .efi_runtime_rel_start : + { + *(.__efi_runtime_rel_start) + } + + .efi_runtime_rel : { + *(.rel*.efi_runtime) + *(.rel*.efi_runtime.*) + } + + .efi_runtime_rel_stop : + { + *(.__efi_runtime_rel_stop) + } + + . = ALIGN(4); + .image_copy_end : + { + *(.__image_copy_end) + } + + .rel_dyn_start : + { + *(.__rel_dyn_start) + } + + .rel.dyn : { + *(.rel*) + } + + .rel_dyn_end : + { + *(.__rel_dyn_end) + } + + .end : + { + *(.__end) + } + + _image_binary_end = .; + +/* + * Compiler-generated __bss_start and __bss_end, see arch/arm/lib/bss.c + * __bss_base and __bss_limit are for linker only (overlay ordering) + */ + + .bss_start __rel_dyn_start (OVERLAY) : { + KEEP(*(.__bss_start)); + __bss_base = .; + } + + .bss __bss_base (OVERLAY) : { + *(.bss*) + . = ALIGN(4); + __bss_limit = .; + } + + .bss_end __bss_limit (OVERLAY) : { + KEEP(*(.__bss_end)); + } + + /* + * Zynq needs to discard these sections because the user + * is expected to pass this image on to tools for boot.bin + * generation that require them to be dropped. + */ + /DISCARD/ : { *(.dynsym) } + /DISCARD/ : { *(.dynbss*) } + /DISCARD/ : { *(.dynstr*) } + /DISCARD/ : { *(.dynamic*) } + /DISCARD/ : { *(.plt*) } + /DISCARD/ : { *(.interp*) } + /DISCARD/ : { *(.gnu*) } + /DISCARD/ : { *(.ARM.exidx*) } + /DISCARD/ : { *(.gnu.linkonce.armexidx.*) } +} |