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