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