1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2014      Panasonic Corporation
4  * Copyright (C) 2015-2016 Socionext Inc.
5  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
6  */
7 
8 #include <env.h>
9 #include <init.h>
10 #include <spl.h>
11 #include <asm/global_data.h>
12 #include <linux/libfdt.h>
13 #include <stdio.h>
14 #include <linux/printk.h>
15 
16 #include "init.h"
17 
uniphier_set_env_fdt_file(void)18 static void uniphier_set_env_fdt_file(void)
19 {
20 	DECLARE_GLOBAL_DATA_PTR;
21 	const char *compat;
22 	char dtb_name[256];
23 	int buf_len = sizeof(dtb_name);
24 	int ret;
25 
26 	if (env_get("fdtfile"))
27 		return;		/* do nothing if it is already set */
28 
29 	compat = fdt_stringlist_get(gd->fdt_blob, 0, "compatible", 0, NULL);
30 	if (!compat)
31 		goto fail;
32 
33 	/* rip off the vendor prefix "socionext,"  */
34 	compat = strchr(compat, ',');
35 	if (!compat)
36 		goto fail;
37 	compat++;
38 
39 	strncpy(dtb_name, compat, buf_len);
40 	buf_len -= strlen(compat);
41 
42 	strncat(dtb_name, ".dtb", buf_len);
43 
44 	ret = env_set("fdtfile", dtb_name);
45 	if (ret)
46 		goto fail;
47 
48 	return;
49 fail:
50 	pr_warn("\"fdt_file\" environment variable was not set correctly\n");
51 }
52 
uniphier_set_env_addr(const char * env,const char * offset_env)53 static void uniphier_set_env_addr(const char *env, const char *offset_env)
54 {
55 	DECLARE_GLOBAL_DATA_PTR;
56 	unsigned long offset = 0;
57 	const char *str;
58 	char *end;
59 	int ret;
60 
61 	if (env_get(env))
62 		return;		/* do nothing if it is already set */
63 
64 	if (offset_env) {
65 		str = env_get(offset_env);
66 		if (!str)
67 			goto fail;
68 
69 		offset = simple_strtoul(str, &end, 16);
70 		if (*end)
71 			goto fail;
72 	}
73 
74 	ret = env_set_hex(env, gd->ram_base + offset);
75 	if (ret)
76 		goto fail;
77 
78 	return;
79 
80 fail:
81 	pr_warn("\"%s\" environment variable was not set correctly\n", env);
82 }
83 
board_late_init(void)84 int board_late_init(void)
85 {
86 	puts("MODE:  ");
87 
88 	switch (uniphier_boot_device_raw()) {
89 	case BOOT_DEVICE_MMC1:
90 		printf("eMMC Boot");
91 		env_set("bootdev", "emmc");
92 		break;
93 	case BOOT_DEVICE_MMC2:
94 		printf("SD Boot");
95 		env_set("bootdev", "sd");
96 		break;
97 	case BOOT_DEVICE_NAND:
98 		printf("NAND Boot");
99 		env_set("bootdev", "nand");
100 		break;
101 	case BOOT_DEVICE_NOR:
102 		printf("NOR Boot");
103 		env_set("bootdev", "nor");
104 		break;
105 	case BOOT_DEVICE_USB:
106 		printf("USB Boot");
107 		env_set("bootdev", "usb");
108 		break;
109 	default:
110 		printf("Unknown");
111 		break;
112 	}
113 
114 	if (uniphier_have_internal_stm())
115 		printf(" (STM: %s)",
116 		       uniphier_boot_from_backend() ? "OFF" : "ON");
117 
118 	printf("\n");
119 
120 	uniphier_set_env_fdt_file();
121 
122 	uniphier_set_env_addr("dram_base", NULL);
123 
124 	uniphier_set_env_addr("loadaddr", "loadaddr_offset");
125 
126 	uniphier_set_env_addr("kernel_addr_r", "kernel_addr_r_offset");
127 	uniphier_set_env_addr("ramdisk_addr_r", "ramdisk_addr_r_offset");
128 	uniphier_set_env_addr("fdt_addr_r", "fdt_addr_r_offset");
129 
130 	return 0;
131 }
132