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 ret = fdt_get_string(gd->fdt_blob, 0, "compatible", &compat); 43 if (ret) 44 return -EINVAL; 45 46 if (strncmp(compat, VENDOR_PREFIX, strlen(VENDOR_PREFIX))) 47 return -EINVAL; 48 49 compat += strlen(VENDOR_PREFIX); 50 51 strncat(dtb_name, DTB_FILE_PREFIX, buf_len); 52 buf_len -= strlen(DTB_FILE_PREFIX); 53 54 strncat(dtb_name, compat, buf_len); 55 buf_len -= strlen(compat); 56 57 strncat(dtb_name, ".dtb", buf_len); 58 59 setenv("fdt_file", dtb_name); 60 61 return 0; 62 } 63 64 int board_late_init(void) 65 { 66 puts("MODE: "); 67 68 switch (spl_boot_device_raw()) { 69 case BOOT_DEVICE_MMC1: 70 printf("eMMC Boot\n"); 71 setenv("bootmode", "emmcboot"); 72 break; 73 case BOOT_DEVICE_NAND: 74 printf("NAND Boot\n"); 75 setenv("bootmode", "nandboot"); 76 nand_denali_wp_disable(); 77 break; 78 case BOOT_DEVICE_NOR: 79 printf("NOR Boot\n"); 80 setenv("bootmode", "norboot"); 81 break; 82 case BOOT_DEVICE_USB: 83 printf("USB Boot\n"); 84 setenv("bootmode", "usbboot"); 85 break; 86 default: 87 printf("Unknown\n"); 88 break; 89 } 90 91 if (uniphier_set_fdt_file()) 92 printf("fdt_file environment was not set correctly\n"); 93 94 return 0; 95 } 96