diff options
Diffstat (limited to 'arch/arm/boards/enclustra-aa1/lowlevel.c')
-rw-r--r-- | arch/arm/boards/enclustra-aa1/lowlevel.c | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/arch/arm/boards/enclustra-aa1/lowlevel.c b/arch/arm/boards/enclustra-aa1/lowlevel.c new file mode 100644 index 0000000000..9f2d66a6bc --- /dev/null +++ b/arch/arm/boards/enclustra-aa1/lowlevel.c @@ -0,0 +1,120 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include <common.h> +#include <linux/sizes.h> +#include <io.h> +#include <memory.h> +#include <asm/barebox-arm.h> +#include <asm/cache.h> +#include <asm/sections.h> +#include <asm/unaligned.h> +#include <debug_ll.h> +#include <pbl.h> +#include <mach/arria10-sdram.h> +#include <mach/arria10-regs.h> +#include <mach/arria10-reset-manager.h> +#include <mach/arria10-clock-manager.h> +#include <mach/arria10-pinmux.h> +#include <mach/arria10-fpga.h> +#include "pll-config-arria10.c" +#include "pinmux-config-arria10.c" +#include <mach/generic.h> + +#define BAREBOX_PART 0 +// the bitstream is located in the second partition in the partition table +#define BITSTREAM_PART 1 +#define BAREBOX1_OFFSET SZ_1M +#define BAREBOX2_OFFSET (BAREBOX1_OFFSET + SZ_1M) +// Offset from the start of the second partition on the eMMC. +#define BITSTREAM1_OFFSET 0x0 +#define BITSTREAM2_OFFSET (BITSTREAM1_OFFSET + SZ_32M) + +extern char __dtb_z_socfpga_arria10_mercury_aa1_start[]; + +#define ARRIA10_STACKTOP (ARRIA10_OCRAM_ADDR + SZ_256K) + +ENTRY_FUNCTION_WITHSTACK(start_socfpga_aa1_xload, ARRIA10_STACKTOP, r0, r1, r2) +{ + int pbl_index = 0; + int barebox = 0; + int bitstream = 0; + + arm_cpu_lowlevel_init(); + + relocate_to_current_adr(); + + setup_c(); + + arria10_init(&mainpll_cfg, &perpll_cfg, pinmux); + + arria10_prepare_mmc(BAREBOX_PART, BITSTREAM_PART); + + pbl_index = readl(ARRIA10_SYSMGR_ROM_INITSWLASTLD); + + /* Allow booting from both PBL0 and PBL1 to allow atomic updates. + * Bitstreams redundant too and expected to reside in the second + * partition. + * There is a fixed relation between the PBL/barebox instance and its + * bitstream location (offset) that requires to update them together */ + switch (pbl_index) { + case 0: + barebox = BAREBOX1_OFFSET; + bitstream = BITSTREAM1_OFFSET; + break; + case 1: + barebox = BAREBOX2_OFFSET; + bitstream = BITSTREAM2_OFFSET; + break; + case 2: + case 3: + /* Left blank for future extension */ + break; + default: + /* If we get an undefined pbl index, use the first and hope for the best. + * We could bail out, but user wouldn't see anything on the console + * and wouldn't know what happend anyway. */ + barebox = BAREBOX1_OFFSET; + bitstream = BITSTREAM1_OFFSET; + break; + } + + arria10_load_fpga(bitstream, SZ_32M); + + arria10_finish_io(&mainpll_cfg, &perpll_cfg, pinmux); + + arria10_ddr_calibration_sequence(); + + arria10_start_image(barebox); +} + +ENTRY_FUNCTION(start_socfpga_aa1, r0, r1, r2) +{ + void *fdt; + + fdt = __dtb_z_socfpga_arria10_mercury_aa1_start + get_runtime_offset(); + + barebox_arm_entry(0x0, SZ_2G, fdt); +} + +ENTRY_FUNCTION_WITHSTACK(start_socfpga_aa1_bringup, ARRIA10_STACKTOP, r0, r1, r2) +{ + void *fdt; + + arm_cpu_lowlevel_init(); + + relocate_to_current_adr(); + setup_c(); + + arria10_init(&mainpll_cfg, &perpll_cfg, pinmux); + + /* wait for fpga_usermode */ + a10_wait_for_usermode(0x1000000); + + arria10_finish_io(&mainpll_cfg, &perpll_cfg, pinmux); + + arria10_ddr_calibration_sequence(); + + fdt = __dtb_z_socfpga_arria10_mercury_aa1_start + get_runtime_offset(); + + barebox_arm_entry(0x0, SZ_2G, fdt); +} |