1 /* 2 * Copyright (C) 2014-2015 Masahiro Yamada <yamada.masahiro@socionext.com> 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <spl.h> 9 #include <libfdt.h> 10 #include <nand.h> 11 #include <linux/io.h> 12 #include <../drivers/mtd/nand/denali.h> 13 14 #include "boot-mode/boot-device.h" 15 16 static void nand_denali_wp_disable(void) 17 { 18 #ifdef CONFIG_NAND_DENALI 19 /* 20 * Since the boot rom enables the write protection for NAND boot mode, 21 * it must be disabled somewhere for "nand write", "nand erase", etc. 22 * The workaround is here to not disturb the Denali NAND controller 23 * driver just for a really SoC-specific thing. 24 */ 25 void __iomem *denali_reg = (void __iomem *)CONFIG_SYS_NAND_REGS_BASE; 26 27 writel(WRITE_PROTECT__FLAG, denali_reg + WRITE_PROTECT); 28 #endif 29 } 30 31 #define VENDOR_PREFIX "socionext," 32 #define DTB_FILE_PREFIX "uniphier-" 33 34 static int uniphier_set_fdt_file(void) 35 { 36 DECLARE_GLOBAL_DATA_PTR; 37 const char *compat; 38 char dtb_name[256]; 39 int buf_len = 256; 40 int ret; 41 42 if (getenv("fdt_file")) 43 return 0; /* do nothing if it is already set */ 44 45 ret = fdt_get_string(gd->fdt_blob, 0, "compatible", &compat); 46 if (ret) 47 return -EINVAL; 48 49 if (strncmp(compat, VENDOR_PREFIX, strlen(VENDOR_PREFIX))) 50 return -EINVAL; 51 52 compat += strlen(VENDOR_PREFIX); 53 54 strncat(dtb_name, DTB_FILE_PREFIX, buf_len); 55 buf_len -= strlen(DTB_FILE_PREFIX); 56 57 strncat(dtb_name, compat, buf_len); 58 buf_len -= strlen(compat); 59 60 strncat(dtb_name, ".dtb", buf_len); 61 62 return setenv("fdt_file", dtb_name); 63 } 64 65 int board_late_init(void) 66 { 67 puts("MODE: "); 68 69 switch (spl_boot_device_raw()) { 70 case BOOT_DEVICE_MMC1: 71 printf("eMMC Boot\n"); 72 setenv("bootmode", "emmcboot"); 73 break; 74 case BOOT_DEVICE_NAND: 75 printf("NAND Boot\n"); 76 setenv("bootmode", "nandboot"); 77 nand_denali_wp_disable(); 78 break; 79 case BOOT_DEVICE_NOR: 80 printf("NOR Boot\n"); 81 setenv("bootmode", "norboot"); 82 break; 83 case BOOT_DEVICE_USB: 84 printf("USB Boot\n"); 85 setenv("bootmode", "usbboot"); 86 break; 87 default: 88 printf("Unknown\n"); 89 break; 90 } 91 92 if (uniphier_set_fdt_file()) 93 printf("fdt_file environment was not set correctly\n"); 94 95 return 0; 96 } 97