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