blob: 43b28f8b86e4844fd8f74b296da91d58b459426d [file] [log] [blame]
Tom Rini83d290c2018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Masahiro Yamada784548e2017-02-14 01:24:26 +09002/*
3 * Copyright (C) 2015-2017 Socionext Inc.
4 * Author: Masahiro Yamada <yamada.masahiro@socionext.com>
Masahiro Yamada784548e2017-02-14 01:24:26 +09005 */
6
7#include <common.h>
Simon Glass09140112020-05-10 11:40:03 -06008#include <command.h>
Masahiro Yamada784548e2017-02-14 01:24:26 +09009#include <spl.h>
Masahiro Yamadadd74b942017-10-13 19:21:55 +090010#include <stdio.h>
Simon Glasseb41d8a2020-05-10 11:40:08 -060011#include <linux/bug.h>
Masahiro Yamadab521ea32019-07-10 20:07:34 +090012#include <linux/io.h>
Masahiro Yamada784548e2017-02-14 01:24:26 +090013#include <linux/log2.h>
14
15#include "../init.h"
16#include "../sbc/sbc-regs.h"
17#include "../sg-regs.h"
18#include "../soc-info.h"
19#include "boot-device.h"
20
21struct uniphier_boot_device_info {
22 unsigned int soc_id;
23 unsigned int boot_device_sel_shift;
24 const struct uniphier_boot_device *boot_device_table;
25 const unsigned int *boot_device_count;
Masahiro Yamadac3d8f1e2019-07-10 20:07:39 +090026 int (*boot_device_is_sd)(u32 pinmon);
Masahiro Yamada784548e2017-02-14 01:24:26 +090027 int (*boot_device_is_usb)(u32 pinmon);
28 unsigned int (*boot_device_fixup)(unsigned int mode);
Masahiro Yamada539d6e02019-07-10 20:07:38 +090029 int (*boot_is_swapped)(void);
Masahiro Yamadaef866f62019-07-10 20:07:33 +090030 bool have_internal_stm;
Masahiro Yamada784548e2017-02-14 01:24:26 +090031};
32
33static const struct uniphier_boot_device_info uniphier_boot_device_info[] = {
Masahiro Yamada784548e2017-02-14 01:24:26 +090034#if defined(CONFIG_ARCH_UNIPHIER_LD4)
35 {
36 .soc_id = UNIPHIER_LD4_ID,
37 .boot_device_sel_shift = 1,
38 .boot_device_table = uniphier_ld4_boot_device_table,
39 .boot_device_count = &uniphier_ld4_boot_device_count,
Masahiro Yamada539d6e02019-07-10 20:07:38 +090040 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
Masahiro Yamadaef866f62019-07-10 20:07:33 +090041 .have_internal_stm = true,
Masahiro Yamada784548e2017-02-14 01:24:26 +090042 },
43#endif
44#if defined(CONFIG_ARCH_UNIPHIER_PRO4)
45 {
46 .soc_id = UNIPHIER_PRO4_ID,
47 .boot_device_sel_shift = 1,
48 .boot_device_table = uniphier_ld4_boot_device_table,
49 .boot_device_count = &uniphier_ld4_boot_device_count,
Masahiro Yamada539d6e02019-07-10 20:07:38 +090050 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
Masahiro Yamadaef866f62019-07-10 20:07:33 +090051 .have_internal_stm = false,
Masahiro Yamada784548e2017-02-14 01:24:26 +090052 },
53#endif
54#if defined(CONFIG_ARCH_UNIPHIER_SLD8)
55 {
56 .soc_id = UNIPHIER_SLD8_ID,
57 .boot_device_sel_shift = 1,
58 .boot_device_table = uniphier_ld4_boot_device_table,
59 .boot_device_count = &uniphier_ld4_boot_device_count,
Masahiro Yamada539d6e02019-07-10 20:07:38 +090060 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
Masahiro Yamadaef866f62019-07-10 20:07:33 +090061 .have_internal_stm = true,
Masahiro Yamada784548e2017-02-14 01:24:26 +090062 },
63#endif
64#if defined(CONFIG_ARCH_UNIPHIER_PRO5)
65 {
66 .soc_id = UNIPHIER_PRO5_ID,
67 .boot_device_sel_shift = 1,
68 .boot_device_table = uniphier_pro5_boot_device_table,
69 .boot_device_count = &uniphier_pro5_boot_device_count,
Masahiro Yamada539d6e02019-07-10 20:07:38 +090070 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
Masahiro Yamadaef866f62019-07-10 20:07:33 +090071 .have_internal_stm = false,
Masahiro Yamada784548e2017-02-14 01:24:26 +090072 },
73#endif
74#if defined(CONFIG_ARCH_UNIPHIER_PXS2)
75 {
76 .soc_id = UNIPHIER_PXS2_ID,
77 .boot_device_sel_shift = 1,
78 .boot_device_table = uniphier_pxs2_boot_device_table,
79 .boot_device_count = &uniphier_pxs2_boot_device_count,
80 .boot_device_is_usb = uniphier_pxs2_boot_device_is_usb,
81 .boot_device_fixup = uniphier_pxs2_boot_device_fixup,
Masahiro Yamada539d6e02019-07-10 20:07:38 +090082 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
Masahiro Yamadaef866f62019-07-10 20:07:33 +090083 .have_internal_stm = false,
Masahiro Yamada784548e2017-02-14 01:24:26 +090084 },
85#endif
86#if defined(CONFIG_ARCH_UNIPHIER_LD6B)
87 {
88 .soc_id = UNIPHIER_LD6B_ID,
89 .boot_device_sel_shift = 1,
90 .boot_device_table = uniphier_pxs2_boot_device_table,
91 .boot_device_count = &uniphier_pxs2_boot_device_count,
92 .boot_device_is_usb = uniphier_pxs2_boot_device_is_usb,
93 .boot_device_fixup = uniphier_pxs2_boot_device_fixup,
Masahiro Yamada539d6e02019-07-10 20:07:38 +090094 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
Masahiro Yamadaef866f62019-07-10 20:07:33 +090095 .have_internal_stm = true, /* STM on A-chip */
Masahiro Yamada784548e2017-02-14 01:24:26 +090096 },
97#endif
98#if defined(CONFIG_ARCH_UNIPHIER_LD11)
99 {
100 .soc_id = UNIPHIER_LD11_ID,
101 .boot_device_sel_shift = 1,
102 .boot_device_table = uniphier_ld11_boot_device_table,
103 .boot_device_count = &uniphier_ld11_boot_device_count,
104 .boot_device_is_usb = uniphier_ld11_boot_device_is_usb,
Masahiro Yamada539d6e02019-07-10 20:07:38 +0900105 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
Masahiro Yamadaef866f62019-07-10 20:07:33 +0900106 .have_internal_stm = true,
Masahiro Yamada784548e2017-02-14 01:24:26 +0900107 },
108#endif
109#if defined(CONFIG_ARCH_UNIPHIER_LD20)
110 {
111 .soc_id = UNIPHIER_LD20_ID,
112 .boot_device_sel_shift = 1,
113 .boot_device_table = uniphier_ld11_boot_device_table,
114 .boot_device_count = &uniphier_ld11_boot_device_count,
115 .boot_device_is_usb = uniphier_ld20_boot_device_is_usb,
Masahiro Yamada539d6e02019-07-10 20:07:38 +0900116 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
Masahiro Yamadaef866f62019-07-10 20:07:33 +0900117 .have_internal_stm = true,
Masahiro Yamada784548e2017-02-14 01:24:26 +0900118 },
119#endif
Masahiro Yamada81afa9c2017-05-15 14:26:33 +0900120#if defined(CONFIG_ARCH_UNIPHIER_PXS3)
121 {
122 .soc_id = UNIPHIER_PXS3_ID,
123 .boot_device_sel_shift = 1,
124 .boot_device_table = uniphier_pxs3_boot_device_table,
125 .boot_device_count = &uniphier_pxs3_boot_device_count,
126 .boot_device_is_usb = uniphier_pxs3_boot_device_is_usb,
Masahiro Yamada539d6e02019-07-10 20:07:38 +0900127 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
Masahiro Yamadaef866f62019-07-10 20:07:33 +0900128 .have_internal_stm = false,
Masahiro Yamada81afa9c2017-05-15 14:26:33 +0900129 },
130#endif
Masahiro Yamada784548e2017-02-14 01:24:26 +0900131};
132UNIPHIER_DEFINE_SOCDATA_FUNC(uniphier_get_boot_device_info,
133 uniphier_boot_device_info)
134
135static unsigned int __uniphier_boot_device_raw(
136 const struct uniphier_boot_device_info *info)
137{
138 u32 pinmon;
139 unsigned int boot_sel;
140
Masahiro Yamada539d6e02019-07-10 20:07:38 +0900141 if (info->boot_is_swapped && info->boot_is_swapped())
Masahiro Yamada784548e2017-02-14 01:24:26 +0900142 return BOOT_DEVICE_NOR;
143
Masahiro Yamadad41b3582019-07-10 20:07:40 +0900144 pinmon = readl(sg_base + SG_PINMON0);
Masahiro Yamada784548e2017-02-14 01:24:26 +0900145
Masahiro Yamadac3d8f1e2019-07-10 20:07:39 +0900146 if (info->boot_device_is_sd && info->boot_device_is_sd(pinmon))
147 return BOOT_DEVICE_MMC2;
148
Masahiro Yamada784548e2017-02-14 01:24:26 +0900149 if (info->boot_device_is_usb && info->boot_device_is_usb(pinmon))
150 return BOOT_DEVICE_USB;
151
152 boot_sel = pinmon >> info->boot_device_sel_shift;
153
154 BUG_ON(!is_power_of_2(*info->boot_device_count));
155 boot_sel &= *info->boot_device_count - 1;
156
157 return info->boot_device_table[boot_sel].boot_device;
158}
159
160unsigned int uniphier_boot_device_raw(void)
161{
162 const struct uniphier_boot_device_info *info;
163
164 info = uniphier_get_boot_device_info();
165 if (!info) {
166 pr_err("unsupported SoC\n");
167 return BOOT_DEVICE_NONE;
168 }
169
170 return __uniphier_boot_device_raw(info);
171}
172
173u32 spl_boot_device(void)
174{
175 const struct uniphier_boot_device_info *info;
176 u32 raw_mode;
177
178 info = uniphier_get_boot_device_info();
179 if (!info) {
180 pr_err("unsupported SoC\n");
181 return BOOT_DEVICE_NONE;
182 }
183
184 raw_mode = __uniphier_boot_device_raw(info);
185
186 return info->boot_device_fixup ?
187 info->boot_device_fixup(raw_mode) : raw_mode;
188}
189
Masahiro Yamada63754842017-04-20 16:54:43 +0900190int uniphier_have_internal_stm(void)
191{
192 const struct uniphier_boot_device_info *info;
193
194 info = uniphier_get_boot_device_info();
195 if (!info) {
196 pr_err("unsupported SoC\n");
197 return -ENOTSUPP;
198 }
199
200 return info->have_internal_stm;
201}
202
203int uniphier_boot_from_backend(void)
204{
Masahiro Yamadad41b3582019-07-10 20:07:40 +0900205 return !!(readl(sg_base + SG_PINMON0) & BIT(27));
Masahiro Yamada63754842017-04-20 16:54:43 +0900206}
207
Masahiro Yamada784548e2017-02-14 01:24:26 +0900208#ifndef CONFIG_SPL_BUILD
209
Simon Glass09140112020-05-10 11:40:03 -0600210static int do_pinmon(struct cmd_tbl *cmdtp, int flag, int argc,
211 char *const argv[])
Masahiro Yamada784548e2017-02-14 01:24:26 +0900212{
213 const struct uniphier_boot_device_info *info;
214 u32 pinmon;
215 unsigned int boot_device_count, boot_sel;
216 int i;
217
218 info = uniphier_get_boot_device_info();
219 if (!info) {
220 pr_err("unsupported SoC\n");
221 return CMD_RET_FAILURE;
222 }
223
Masahiro Yamada63754842017-04-20 16:54:43 +0900224 if (uniphier_have_internal_stm())
225 printf("STB Micon: %s\n",
226 uniphier_boot_from_backend() ? "OFF" : "ON");
227
Masahiro Yamada539d6e02019-07-10 20:07:38 +0900228 if (info->boot_is_swapped)
229 printf("Boot Swap: %s\n",
230 info->boot_is_swapped() ? "ON" : "OFF");
Masahiro Yamada784548e2017-02-14 01:24:26 +0900231
Masahiro Yamadad41b3582019-07-10 20:07:40 +0900232 pinmon = readl(sg_base + SG_PINMON0);
Masahiro Yamada784548e2017-02-14 01:24:26 +0900233
Masahiro Yamadac3d8f1e2019-07-10 20:07:39 +0900234 if (info->boot_device_is_sd)
235 printf("SD Boot: %s\n",
236 info->boot_device_is_sd(pinmon) ? "ON" : "OFF");
237
Masahiro Yamada784548e2017-02-14 01:24:26 +0900238 if (info->boot_device_is_usb)
Masahiro Yamada63754842017-04-20 16:54:43 +0900239 printf("USB Boot: %s\n",
Masahiro Yamada784548e2017-02-14 01:24:26 +0900240 info->boot_device_is_usb(pinmon) ? "ON" : "OFF");
241
242 boot_device_count = *info->boot_device_count;
243
244 boot_sel = pinmon >> info->boot_device_sel_shift;
245 boot_sel &= boot_device_count - 1;
246
Masahiro Yamada63754842017-04-20 16:54:43 +0900247 printf("\nBoot Mode Sel:\n");
Masahiro Yamada784548e2017-02-14 01:24:26 +0900248 for (i = 0; i < boot_device_count; i++)
249 printf(" %c %02x %s\n", i == boot_sel ? '*' : ' ', i,
250 info->boot_device_table[i].desc);
251
252 return CMD_RET_SUCCESS;
253}
254
255U_BOOT_CMD(
256 pinmon, 1, 1, do_pinmon,
257 "pin monitor",
258 ""
259);
260
261#endif /* !CONFIG_SPL_BUILD */