183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
24c425570SMasahiro Yamada /*
340749d5aSMasahiro Yamada  * Copyright (C) 2014      Panasonic Corporation
440749d5aSMasahiro Yamada  * Copyright (C) 2015-2016 Socionext Inc.
540749d5aSMasahiro Yamada  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
64c425570SMasahiro Yamada  */
74c425570SMasahiro Yamada 
84c425570SMasahiro Yamada #include <common.h>
94c425570SMasahiro Yamada #include <spl.h>
10b08c8c48SMasahiro Yamada #include <linux/libfdt.h>
114c425570SMasahiro Yamada #include <nand.h>
12dd74b945SMasahiro Yamada #include <stdio.h>
13f6e7f07cSMasahiro Yamada #include <linux/io.h>
14dd74b945SMasahiro Yamada #include <linux/printk.h>
15a430fa06SMiquel Raynal #include <../drivers/mtd/nand/raw/denali.h>
164c425570SMasahiro Yamada 
17784548efSMasahiro Yamada #include "init.h"
18fec48163SMasahiro Yamada 
nand_denali_wp_disable(void)194c425570SMasahiro Yamada static void nand_denali_wp_disable(void)
204c425570SMasahiro Yamada {
214c425570SMasahiro Yamada #ifdef CONFIG_NAND_DENALI
224c425570SMasahiro Yamada 	/*
234c425570SMasahiro Yamada 	 * Since the boot rom enables the write protection for NAND boot mode,
244c425570SMasahiro Yamada 	 * it must be disabled somewhere for "nand write", "nand erase", etc.
254c425570SMasahiro Yamada 	 * The workaround is here to not disturb the Denali NAND controller
264c425570SMasahiro Yamada 	 * driver just for a really SoC-specific thing.
274c425570SMasahiro Yamada 	 */
284c425570SMasahiro Yamada 	void __iomem *denali_reg = (void __iomem *)CONFIG_SYS_NAND_REGS_BASE;
294c425570SMasahiro Yamada 
304c425570SMasahiro Yamada 	writel(WRITE_PROTECT__FLAG, denali_reg + WRITE_PROTECT);
314c425570SMasahiro Yamada #endif
324c425570SMasahiro Yamada }
334c425570SMasahiro Yamada 
uniphier_set_fdt_file(void)34881aa5a7SMasahiro Yamada static int uniphier_set_fdt_file(void)
358ea4f49aSMasahiro Yamada {
368ea4f49aSMasahiro Yamada 	DECLARE_GLOBAL_DATA_PTR;
37881aa5a7SMasahiro Yamada 	const char *compat;
38881aa5a7SMasahiro Yamada 	char dtb_name[256];
3940749d5aSMasahiro Yamada 	int buf_len = sizeof(dtb_name);
408ea4f49aSMasahiro Yamada 
418c09f1f4SMasahiro Yamada 	if (env_get("fdtfile"))
424565a74dSMasahiro Yamada 		return 0;	/* do nothing if it is already set */
434565a74dSMasahiro Yamada 
44b02e4044SSimon Glass 	compat = fdt_stringlist_get(gd->fdt_blob, 0, "compatible", 0, NULL);
45b02e4044SSimon Glass 	if (!compat)
46881aa5a7SMasahiro Yamada 		return -EINVAL;
47881aa5a7SMasahiro Yamada 
4840749d5aSMasahiro Yamada 	/* rip off the vendor prefix "socionext,"  */
4940749d5aSMasahiro Yamada 	compat = strchr(compat, ',');
5040749d5aSMasahiro Yamada 	if (!compat)
51881aa5a7SMasahiro Yamada 		return -EINVAL;
5240749d5aSMasahiro Yamada 	compat++;
53881aa5a7SMasahiro Yamada 
5440749d5aSMasahiro Yamada 	strncpy(dtb_name, compat, buf_len);
55881aa5a7SMasahiro Yamada 	buf_len -= strlen(compat);
56881aa5a7SMasahiro Yamada 
57881aa5a7SMasahiro Yamada 	strncat(dtb_name, ".dtb", buf_len);
58881aa5a7SMasahiro Yamada 
598c09f1f4SMasahiro Yamada 	return env_set("fdtfile", dtb_name);
608ea4f49aSMasahiro Yamada }
618ea4f49aSMasahiro Yamada 
board_late_init(void)624c425570SMasahiro Yamada int board_late_init(void)
634c425570SMasahiro Yamada {
644c425570SMasahiro Yamada 	puts("MODE:  ");
654c425570SMasahiro Yamada 
66784548efSMasahiro Yamada 	switch (uniphier_boot_device_raw()) {
674c425570SMasahiro Yamada 	case BOOT_DEVICE_MMC1:
6863754842SMasahiro Yamada 		printf("eMMC Boot");
69*6bc50a8fSMasahiro Yamada 		env_set("bootdev", "emmc");
704c425570SMasahiro Yamada 		break;
714c425570SMasahiro Yamada 	case BOOT_DEVICE_NAND:
7263754842SMasahiro Yamada 		printf("NAND Boot");
73*6bc50a8fSMasahiro Yamada 		env_set("bootdev", "nand");
744c425570SMasahiro Yamada 		nand_denali_wp_disable();
754c425570SMasahiro Yamada 		break;
764c425570SMasahiro Yamada 	case BOOT_DEVICE_NOR:
7763754842SMasahiro Yamada 		printf("NOR Boot");
78*6bc50a8fSMasahiro Yamada 		env_set("bootdev", "nor");
794c425570SMasahiro Yamada 		break;
80fec48163SMasahiro Yamada 	case BOOT_DEVICE_USB:
8163754842SMasahiro Yamada 		printf("USB Boot");
82*6bc50a8fSMasahiro Yamada 		env_set("bootdev", "usb");
83fec48163SMasahiro Yamada 		break;
844c425570SMasahiro Yamada 	default:
8563754842SMasahiro Yamada 		printf("Unknown");
86d90b9745SMasahiro Yamada 		break;
874c425570SMasahiro Yamada 	}
884c425570SMasahiro Yamada 
8963754842SMasahiro Yamada 	if (uniphier_have_internal_stm())
9063754842SMasahiro Yamada 		printf(" (STM: %s)",
9163754842SMasahiro Yamada 		       uniphier_boot_from_backend() ? "OFF" : "ON");
9263754842SMasahiro Yamada 
9363754842SMasahiro Yamada 	printf("\n");
9463754842SMasahiro Yamada 
95881aa5a7SMasahiro Yamada 	if (uniphier_set_fdt_file())
96dd74b945SMasahiro Yamada 		pr_warn("fdt_file environment was not set correctly\n");
978ea4f49aSMasahiro Yamada 
984c425570SMasahiro Yamada 	return 0;
994c425570SMasahiro Yamada }
100