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