summaryrefslogtreecommitdiffstats
path: root/arch/arm/boards/ls1028ardb/lowlevel.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/boards/ls1028ardb/lowlevel.c')
-rw-r--r--arch/arm/boards/ls1028ardb/lowlevel.c142
1 files changed, 142 insertions, 0 deletions
diff --git a/arch/arm/boards/ls1028ardb/lowlevel.c b/arch/arm/boards/ls1028ardb/lowlevel.c
new file mode 100644
index 0000000000..00db0b1cf8
--- /dev/null
+++ b/arch/arm/boards/ls1028ardb/lowlevel.c
@@ -0,0 +1,142 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#include <common.h>
+#include <debug_ll.h>
+#include <ddr_spd.h>
+#include <image-metadata.h>
+#include <platform_data/mmc-esdhc-imx.h>
+#include <soc/fsl/fsl_ddr_sdram.h>
+#include <soc/fsl/immap_lsch2.h>
+#include <asm/barebox-arm-head.h>
+#include <asm/barebox-arm.h>
+#include <asm/syscounter.h>
+#include <asm/cache.h>
+#include <mach/layerscape/lowlevel.h>
+#include <mach/layerscape/xload.h>
+#include <mach/layerscape/errata.h>
+#include <mach/layerscape/layerscape.h>
+#include <linux/bitfield.h>
+
+static struct fsl_ddr_controller ddrc = {
+ .memctl_opts.ddrtype = SDRAM_TYPE_DDR4,
+ .base = IOMEM(LSCH2_DDR_ADDR),
+ .ddr_freq = 1600000000,
+ .erratum_A009942 = 1,
+ .erratum_A009663 = 1,
+ .chip_selects_per_ctrl = 4,
+ .fsl_ddr_config_reg = {
+ .cs[0].bnds = 0x000000ff,
+ .cs[0].config = 0x80040422,
+ .cs[0].config_2 = 0,
+ .cs[1].bnds = 0,
+ .cs[1].config = 0,
+ .cs[1].config_2 = 0,
+
+ .timing_cfg_3 = 0x01111000,
+ .timing_cfg_0 = 0xd0550018,
+ .timing_cfg_1 = 0xFAFC0C42,
+ .timing_cfg_2 = 0x0048c114,
+ .ddr_sdram_cfg = 0xe50c000c,
+ .ddr_sdram_cfg_2 = 0x00401110,
+ .ddr_sdram_mode = 0x01010230,
+ .ddr_sdram_mode_2 = 0x0,
+
+ .ddr_sdram_md_cntl = 0x0600001f,
+ .ddr_sdram_interval = 0x18600618,
+ .ddr_data_init = 0xdeadbeef,
+
+ .ddr_sdram_clk_cntl = 0x02000000,
+ .ddr_init_addr = 0,
+ .ddr_init_ext_addr = 0,
+
+ .timing_cfg_4 = 0x00000002,
+ .timing_cfg_5 = 0x07401400,
+ .timing_cfg_6 = 0x0,
+ .timing_cfg_7 = 0x23300000,
+
+ .ddr_zq_cntl = 0x8A090705,
+ .ddr_wrlvl_cntl = 0x86550607,
+ .ddr_sr_cntr = 0,
+ .ddr_sdram_rcw_1 = 0,
+ .ddr_sdram_rcw_2 = 0,
+ .ddr_wrlvl_cntl_2 = 0x0708080A,
+ .ddr_wrlvl_cntl_3 = 0x0A0B0C09,
+
+ .ddr_sdram_mode_9 = 0x00000400,
+ .ddr_sdram_mode_10 = 0x04000000,
+
+ .timing_cfg_8 = 0x06115600,
+
+ .dq_map_0 = 0x5b65b658,
+ .dq_map_1 = 0xd96d8000,
+ .dq_map_2 = 0,
+ .dq_map_3 = 0x01600000,
+
+ .ddr_cdr1 = 0x80040000,
+ .ddr_cdr2 = 0x000000C1
+ },
+};
+
+extern char __dtb_z_fsl_ls1028a_rdb_start[];
+
+#define MEM_PLL_RAT GENMASK(15, 10)
+
+static unsigned long get_ddr_freq(void)
+{
+ unsigned long freq = 100000000;
+ u32 rcwsr1 = readl(0x1e00100);
+ u32 mult;
+
+ mult = FIELD_GET(MEM_PLL_RAT, rcwsr1);
+
+ return freq * mult;
+}
+
+struct dram_regions_info dram_info = {
+ .num_dram_regions = 2,
+ .total_dram_size = SZ_4G,
+ .region = {
+ {
+ .addr = LS1028A_DDR_SDRAM_BASE,
+ .size = SZ_2G,
+ }, {
+ .addr = LS1028A_DDR_SDRAM_HIGHMEM_BASE,
+ .size = SZ_2G,
+ },
+ },
+};
+
+static noinline __noreturn void ls1028ardb_r_entry(unsigned long memsize)
+{
+ unsigned long membase = LS1028A_DDR_SDRAM_BASE;
+
+ if (get_pc() >= membase)
+ barebox_arm_entry(membase, SZ_2G - LS1028A_TFA_RESERVED_SIZE,
+ __dtb_z_fsl_ls1028a_rdb_start);
+
+ arm_cpu_lowlevel_init();
+ ls1028a_init_lowlevel();
+ ddrc.ddr_freq = get_ddr_freq();
+
+ fsl_ddr_set_memctl_regs(&ddrc, 0, true);
+
+ ls1028a_tzc400_init(SZ_4G);
+
+ ls1028a_errata_post_ddr();
+
+ ls1028a_esdhc1_start_image(&dram_info);
+
+ hang();
+}
+
+void ls1028ardb_entry(unsigned long r0, unsigned long r1, unsigned long r2);
+
+__noreturn void ls1028ardb_entry(unsigned long r0, unsigned long r1, unsigned long r2)
+{
+ ls1028a_uart_setup(IOMEM(LSCH2_NS16550_COM1));
+
+ relocate_to_current_adr();
+ setup_c();
+
+ ls1028ardb_r_entry(r0);
+}