]> git.sur5r.net Git - u-boot/blobdiff - board/liebherr/display5/spl.c
display5: ddr: Enable support for DDR3 auto calibration
[u-boot] / board / liebherr / display5 / spl.c
index 0a36e656c011b9ef847d1d6a7e13eeba9746efb6..0c0172e201091714ab89db78cf2c712d61e19469 100644 (file)
@@ -1,13 +1,12 @@
+// SPDX-License-Identifier: GPL-2.0+
 /*
  * Copyright (C) 2017 DENX Software Engineering
  * Lukasz Majewski, DENX Software Engineering, lukma@denx.de
- *
- * SPDX-License-Identifier:    GPL-2.0+
  */
 
 #include <common.h>
 #include <spl.h>
-#include <libfdt.h>
+#include <linux/libfdt.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/mx6-ddr.h>
 #include <asm/arch/imx-regs.h>
 #include "asm/arch/iomux.h"
 #include <asm/mach-imx/iomux-v3.h>
+#include <asm/gpio.h>
 #include <environment.h>
 #include <fsl_esdhc.h>
 #include <netdev.h>
+#include <bootcount.h>
+#include <watchdog.h>
 #include "common.h"
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -115,6 +117,49 @@ static void ccgr_init(void)
        writel(0x000003FF, &ccm->CCGR6);
 }
 
+#ifdef CONFIG_MX6_DDRCAL
+static void spl_dram_print_cal(struct mx6_ddr_sysinfo const *sysinfo)
+{
+       struct mx6_mmdc_calibration calibration = {0};
+
+       mmdc_read_calibration(sysinfo, &calibration);
+
+       debug(".p0_mpdgctrl0\t= 0x%08X\n", calibration.p0_mpdgctrl0);
+       debug(".p0_mpdgctrl1\t= 0x%08X\n", calibration.p0_mpdgctrl1);
+       debug(".p0_mprddlctl\t= 0x%08X\n", calibration.p0_mprddlctl);
+       debug(".p0_mpwrdlctl\t= 0x%08X\n", calibration.p0_mpwrdlctl);
+       debug(".p0_mpwldectrl0\t= 0x%08X\n", calibration.p0_mpwldectrl0);
+       debug(".p0_mpwldectrl1\t= 0x%08X\n", calibration.p0_mpwldectrl1);
+       debug(".p1_mpdgctrl0\t= 0x%08X\n", calibration.p1_mpdgctrl0);
+       debug(".p1_mpdgctrl1\t= 0x%08X\n", calibration.p1_mpdgctrl1);
+       debug(".p1_mprddlctl\t= 0x%08X\n", calibration.p1_mprddlctl);
+       debug(".p1_mpwrdlctl\t= 0x%08X\n", calibration.p1_mpwrdlctl);
+       debug(".p1_mpwldectrl0\t= 0x%08X\n", calibration.p1_mpwldectrl0);
+       debug(".p1_mpwldectrl1\t= 0x%08X\n", calibration.p1_mpwldectrl1);
+}
+
+static void spl_dram_perform_cal(struct mx6_ddr_sysinfo const *sysinfo)
+{
+       int ret;
+
+       /* Perform DDR DRAM calibration */
+       udelay(100);
+       ret = mmdc_do_write_level_calibration(sysinfo);
+       if (ret) {
+               printf("DDR: Write level calibration error [%d]\n", ret);
+               return;
+       }
+
+       ret = mmdc_do_dqs_calibration(sysinfo);
+       if (ret) {
+               printf("DDR: DQS calibration error [%d]\n", ret);
+               return;
+       }
+
+       spl_dram_print_cal(sysinfo);
+}
+#endif /* CONFIG_MX6_DDRCAL */
+
 static void spl_dram_init(void)
 {
        struct mx6_ddr_sysinfo sysinfo = {
@@ -141,6 +186,10 @@ static void spl_dram_init(void)
 
        mx6dq_dram_iocfg(64, &mx6_ddr_ioregs, &mx6_grp_ioregs);
        mx6_dram_cfg(&sysinfo, &mx6_4x256mx16_mmdc_calib, &mt41k128m16jt_125);
+
+#ifdef CONFIG_MX6_DDRCAL
+       spl_dram_perform_cal(&sysinfo);
+#endif
 }
 
 #ifdef CONFIG_SPL_SPI_SUPPORT
@@ -194,10 +243,28 @@ void board_init_f(ulong dummy)
        /* Clear the BSS. */
        memset(__bss_start, 0, __bss_end - __bss_start);
 
+       displ5_set_iomux_misc_spl();
+
+       /* Initialize and reset WDT in SPL */
+       hw_watchdog_init();
+       WATCHDOG_RESET();
+
        /* load/boot image from boot device */
        board_init_r(NULL, 0);
 }
 
+#define EM_PAD IMX_GPIO_NR(3, 29)
+int board_check_emergency_pad(void)
+{
+       int ret;
+
+       ret = gpio_direction_input(EM_PAD);
+       if (ret)
+               return ret;
+
+       return !gpio_get_value(EM_PAD);
+}
+
 void board_boot_order(u32 *spl_boot_list)
 {
        /* Default boot sequence SPI -> MMC */
@@ -206,15 +273,22 @@ void board_boot_order(u32 *spl_boot_list)
        spl_boot_list[2] = BOOT_DEVICE_UART;
        spl_boot_list[3] = BOOT_DEVICE_NONE;
 
+       /*
+        * In case of emergency PAD pressed, we always boot
+        * to proper u-boot and perform recovery tasks there.
+        */
+       if (board_check_emergency_pad())
+               return;
+
 #ifdef CONFIG_SPL_ENV_SUPPORT
        /* 'fastboot' */
        const char *s;
 
-       env_init();
-       env_load();
+       if (env_init() || env_load())
+               return;
 
        s = env_get("BOOT_FROM");
-       if (s && strcmp(s, "ACTIVE") == 0) {
+       if (s && !bootcount_error() && strcmp(s, "ACTIVE") == 0) {
                spl_boot_list[0] = BOOT_DEVICE_MMC1;
                spl_boot_list[1] = spl_boot_device();
        }