]> Git Repo - J-u-boot.git/blob - arch/arm/mach-uniphier/boot-device/boot-device.c
Merge tag 'u-boot-stm32-20190712' of https://gitlab.denx.de/u-boot/custodians/u-boot-stm
[J-u-boot.git] / arch / arm / mach-uniphier / boot-device / boot-device.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2015-2017 Socionext Inc.
4  *   Author: Masahiro Yamada <[email protected]>
5  */
6
7 #include <common.h>
8 #include <spl.h>
9 #include <stdio.h>
10 #include <linux/io.h>
11 #include <linux/log2.h>
12
13 #include "../init.h"
14 #include "../sbc/sbc-regs.h"
15 #include "../sg-regs.h"
16 #include "../soc-info.h"
17 #include "boot-device.h"
18
19 struct uniphier_boot_device_info {
20         unsigned int soc_id;
21         unsigned int boot_device_sel_shift;
22         const struct uniphier_boot_device *boot_device_table;
23         const unsigned int *boot_device_count;
24         int (*boot_device_is_sd)(u32 pinmon);
25         int (*boot_device_is_usb)(u32 pinmon);
26         unsigned int (*boot_device_fixup)(unsigned int mode);
27         int (*boot_is_swapped)(void);
28         bool have_internal_stm;
29 };
30
31 static const struct uniphier_boot_device_info uniphier_boot_device_info[] = {
32 #if defined(CONFIG_ARCH_UNIPHIER_LD4)
33         {
34                 .soc_id = UNIPHIER_LD4_ID,
35                 .boot_device_sel_shift = 1,
36                 .boot_device_table = uniphier_ld4_boot_device_table,
37                 .boot_device_count = &uniphier_ld4_boot_device_count,
38                 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
39                 .have_internal_stm = true,
40         },
41 #endif
42 #if defined(CONFIG_ARCH_UNIPHIER_PRO4)
43         {
44                 .soc_id = UNIPHIER_PRO4_ID,
45                 .boot_device_sel_shift = 1,
46                 .boot_device_table = uniphier_ld4_boot_device_table,
47                 .boot_device_count = &uniphier_ld4_boot_device_count,
48                 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
49                 .have_internal_stm = false,
50         },
51 #endif
52 #if defined(CONFIG_ARCH_UNIPHIER_SLD8)
53         {
54                 .soc_id = UNIPHIER_SLD8_ID,
55                 .boot_device_sel_shift = 1,
56                 .boot_device_table = uniphier_ld4_boot_device_table,
57                 .boot_device_count = &uniphier_ld4_boot_device_count,
58                 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
59                 .have_internal_stm = true,
60         },
61 #endif
62 #if defined(CONFIG_ARCH_UNIPHIER_PRO5)
63         {
64                 .soc_id = UNIPHIER_PRO5_ID,
65                 .boot_device_sel_shift = 1,
66                 .boot_device_table = uniphier_pro5_boot_device_table,
67                 .boot_device_count = &uniphier_pro5_boot_device_count,
68                 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
69                 .have_internal_stm = false,
70         },
71 #endif
72 #if defined(CONFIG_ARCH_UNIPHIER_PXS2)
73         {
74                 .soc_id = UNIPHIER_PXS2_ID,
75                 .boot_device_sel_shift = 1,
76                 .boot_device_table = uniphier_pxs2_boot_device_table,
77                 .boot_device_count = &uniphier_pxs2_boot_device_count,
78                 .boot_device_is_usb = uniphier_pxs2_boot_device_is_usb,
79                 .boot_device_fixup = uniphier_pxs2_boot_device_fixup,
80                 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
81                 .have_internal_stm = false,
82         },
83 #endif
84 #if defined(CONFIG_ARCH_UNIPHIER_LD6B)
85         {
86                 .soc_id = UNIPHIER_LD6B_ID,
87                 .boot_device_sel_shift = 1,
88                 .boot_device_table = uniphier_pxs2_boot_device_table,
89                 .boot_device_count = &uniphier_pxs2_boot_device_count,
90                 .boot_device_is_usb = uniphier_pxs2_boot_device_is_usb,
91                 .boot_device_fixup = uniphier_pxs2_boot_device_fixup,
92                 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
93                 .have_internal_stm = true,      /* STM on A-chip */
94         },
95 #endif
96 #if defined(CONFIG_ARCH_UNIPHIER_LD11)
97         {
98                 .soc_id = UNIPHIER_LD11_ID,
99                 .boot_device_sel_shift = 1,
100                 .boot_device_table = uniphier_ld11_boot_device_table,
101                 .boot_device_count = &uniphier_ld11_boot_device_count,
102                 .boot_device_is_usb = uniphier_ld11_boot_device_is_usb,
103                 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
104                 .have_internal_stm = true,
105         },
106 #endif
107 #if defined(CONFIG_ARCH_UNIPHIER_LD20)
108         {
109                 .soc_id = UNIPHIER_LD20_ID,
110                 .boot_device_sel_shift = 1,
111                 .boot_device_table = uniphier_ld11_boot_device_table,
112                 .boot_device_count = &uniphier_ld11_boot_device_count,
113                 .boot_device_is_usb = uniphier_ld20_boot_device_is_usb,
114                 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
115                 .have_internal_stm = true,
116         },
117 #endif
118 #if defined(CONFIG_ARCH_UNIPHIER_PXS3)
119         {
120                 .soc_id = UNIPHIER_PXS3_ID,
121                 .boot_device_sel_shift = 1,
122                 .boot_device_table = uniphier_pxs3_boot_device_table,
123                 .boot_device_count = &uniphier_pxs3_boot_device_count,
124                 .boot_device_is_usb = uniphier_pxs3_boot_device_is_usb,
125                 .boot_is_swapped = uniphier_sbc_boot_is_swapped,
126                 .have_internal_stm = false,
127         },
128 #endif
129 };
130 UNIPHIER_DEFINE_SOCDATA_FUNC(uniphier_get_boot_device_info,
131                              uniphier_boot_device_info)
132
133 static unsigned int __uniphier_boot_device_raw(
134                                 const struct uniphier_boot_device_info *info)
135 {
136         u32 pinmon;
137         unsigned int boot_sel;
138
139         if (info->boot_is_swapped && info->boot_is_swapped())
140                 return BOOT_DEVICE_NOR;
141
142         pinmon = readl(sg_base + SG_PINMON0);
143
144         if (info->boot_device_is_sd && info->boot_device_is_sd(pinmon))
145                 return BOOT_DEVICE_MMC2;
146
147         if (info->boot_device_is_usb && info->boot_device_is_usb(pinmon))
148                 return BOOT_DEVICE_USB;
149
150         boot_sel = pinmon >> info->boot_device_sel_shift;
151
152         BUG_ON(!is_power_of_2(*info->boot_device_count));
153         boot_sel &= *info->boot_device_count - 1;
154
155         return info->boot_device_table[boot_sel].boot_device;
156 }
157
158 unsigned int uniphier_boot_device_raw(void)
159 {
160         const struct uniphier_boot_device_info *info;
161
162         info = uniphier_get_boot_device_info();
163         if (!info) {
164                 pr_err("unsupported SoC\n");
165                 return BOOT_DEVICE_NONE;
166         }
167
168         return __uniphier_boot_device_raw(info);
169 }
170
171 u32 spl_boot_device(void)
172 {
173         const struct uniphier_boot_device_info *info;
174         u32 raw_mode;
175
176         info = uniphier_get_boot_device_info();
177         if (!info) {
178                 pr_err("unsupported SoC\n");
179                 return BOOT_DEVICE_NONE;
180         }
181
182         raw_mode = __uniphier_boot_device_raw(info);
183
184         return info->boot_device_fixup ?
185                                 info->boot_device_fixup(raw_mode) : raw_mode;
186 }
187
188 int uniphier_have_internal_stm(void)
189 {
190         const struct uniphier_boot_device_info *info;
191
192         info = uniphier_get_boot_device_info();
193         if (!info) {
194                 pr_err("unsupported SoC\n");
195                 return -ENOTSUPP;
196         }
197
198         return info->have_internal_stm;
199 }
200
201 int uniphier_boot_from_backend(void)
202 {
203         return !!(readl(sg_base + SG_PINMON0) & BIT(27));
204 }
205
206 #ifndef CONFIG_SPL_BUILD
207
208 static int do_pinmon(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
209 {
210         const struct uniphier_boot_device_info *info;
211         u32 pinmon;
212         unsigned int boot_device_count, boot_sel;
213         int i;
214
215         info = uniphier_get_boot_device_info();
216         if (!info) {
217                 pr_err("unsupported SoC\n");
218                 return CMD_RET_FAILURE;
219         }
220
221         if (uniphier_have_internal_stm())
222                 printf("STB Micon: %s\n",
223                        uniphier_boot_from_backend() ? "OFF" : "ON");
224
225         if (info->boot_is_swapped)
226                 printf("Boot Swap: %s\n",
227                        info->boot_is_swapped() ? "ON" : "OFF");
228
229         pinmon = readl(sg_base + SG_PINMON0);
230
231         if (info->boot_device_is_sd)
232                 printf("SD Boot:  %s\n",
233                        info->boot_device_is_sd(pinmon) ? "ON" : "OFF");
234
235         if (info->boot_device_is_usb)
236                 printf("USB Boot:  %s\n",
237                        info->boot_device_is_usb(pinmon) ? "ON" : "OFF");
238
239         boot_device_count = *info->boot_device_count;
240
241         boot_sel = pinmon >> info->boot_device_sel_shift;
242         boot_sel &= boot_device_count - 1;
243
244         printf("\nBoot Mode Sel:\n");
245         for (i = 0; i < boot_device_count; i++)
246                 printf(" %c %02x %s\n", i == boot_sel ? '*' : ' ', i,
247                        info->boot_device_table[i].desc);
248
249         return CMD_RET_SUCCESS;
250 }
251
252 U_BOOT_CMD(
253         pinmon, 1,      1,      do_pinmon,
254         "pin monitor",
255         ""
256 );
257
258 #endif /* !CONFIG_SPL_BUILD */
This page took 0.043442 seconds and 4 git commands to generate.