summaryrefslogtreecommitdiffstats
path: root/arch/arm/boards/enclustra-aa1/lowlevel.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/boards/enclustra-aa1/lowlevel.c')
-rw-r--r--arch/arm/boards/enclustra-aa1/lowlevel.c120
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);
+}