xref: /rk3399_ARM-atf/plat/socionext/uniphier/uniphier_boot_device.c (revision 2cb260053d49cb4e925b46afd2f511639dd64b70)
1 /*
2  * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 #include <stdbool.h>
9 #include <stddef.h>
10 
11 #include <lib/mmio.h>
12 #include <lib/utils_def.h>
13 
14 #include "uniphier.h"
15 
16 #define UNIPHIER_PINMON0		0x5f900100
17 #define UNIPHIER_PINMON2		0x5f900108
18 
19 static bool uniphier_ld11_is_usb_boot(uint32_t pinmon)
20 {
21 	return !!(~pinmon & 0x00000080);
22 }
23 
24 static bool uniphier_ld20_is_usb_boot(uint32_t pinmon)
25 {
26 	return !!(~pinmon & 0x00000780);
27 }
28 
29 static bool uniphier_pxs3_is_usb_boot(uint32_t pinmon)
30 {
31 	uint32_t pinmon2 = mmio_read_32(UNIPHIER_PINMON2);
32 
33 	return !!(pinmon2 & BIT(31));
34 }
35 
36 static const unsigned int uniphier_ld11_boot_device_table[] = {
37 	UNIPHIER_BOOT_DEVICE_NAND,
38 	UNIPHIER_BOOT_DEVICE_NAND,
39 	UNIPHIER_BOOT_DEVICE_NAND,
40 	UNIPHIER_BOOT_DEVICE_NAND,
41 	UNIPHIER_BOOT_DEVICE_NAND,
42 	UNIPHIER_BOOT_DEVICE_NAND,
43 	UNIPHIER_BOOT_DEVICE_NAND,
44 	UNIPHIER_BOOT_DEVICE_NAND,
45 	UNIPHIER_BOOT_DEVICE_NAND,
46 	UNIPHIER_BOOT_DEVICE_NAND,
47 	UNIPHIER_BOOT_DEVICE_NAND,
48 	UNIPHIER_BOOT_DEVICE_NAND,
49 	UNIPHIER_BOOT_DEVICE_NAND,
50 	UNIPHIER_BOOT_DEVICE_NAND,
51 	UNIPHIER_BOOT_DEVICE_NAND,
52 	UNIPHIER_BOOT_DEVICE_NAND,
53 	UNIPHIER_BOOT_DEVICE_NAND,
54 	UNIPHIER_BOOT_DEVICE_NAND,
55 	UNIPHIER_BOOT_DEVICE_NAND,
56 	UNIPHIER_BOOT_DEVICE_NAND,
57 	UNIPHIER_BOOT_DEVICE_NAND,
58 	UNIPHIER_BOOT_DEVICE_NAND,
59 	UNIPHIER_BOOT_DEVICE_NAND,
60 	UNIPHIER_BOOT_DEVICE_NAND,
61 	UNIPHIER_BOOT_DEVICE_EMMC,
62 	UNIPHIER_BOOT_DEVICE_EMMC,
63 	UNIPHIER_BOOT_DEVICE_EMMC,
64 	UNIPHIER_BOOT_DEVICE_EMMC,
65 	UNIPHIER_BOOT_DEVICE_EMMC,
66 	UNIPHIER_BOOT_DEVICE_EMMC,
67 	UNIPHIER_BOOT_DEVICE_EMMC,
68 	UNIPHIER_BOOT_DEVICE_NOR,
69 };
70 
71 static unsigned int uniphier_ld11_get_boot_device(uint32_t pinmon)
72 {
73 	unsigned int boot_sel = (pinmon >> 1) & 0x1f;
74 
75 	assert(boot_sel < ARRAY_SIZE(uniphier_ld11_boot_device_table));
76 
77 	return uniphier_ld11_boot_device_table[boot_sel];
78 }
79 
80 static const unsigned int uniphier_pxs3_boot_device_table[] = {
81 	UNIPHIER_BOOT_DEVICE_NAND,
82 	UNIPHIER_BOOT_DEVICE_NAND,
83 	UNIPHIER_BOOT_DEVICE_NAND,
84 	UNIPHIER_BOOT_DEVICE_NAND,
85 	UNIPHIER_BOOT_DEVICE_NAND,
86 	UNIPHIER_BOOT_DEVICE_NAND,
87 	UNIPHIER_BOOT_DEVICE_NAND,
88 	UNIPHIER_BOOT_DEVICE_NAND,
89 	UNIPHIER_BOOT_DEVICE_EMMC,
90 	UNIPHIER_BOOT_DEVICE_EMMC,
91 	UNIPHIER_BOOT_DEVICE_EMMC,
92 	UNIPHIER_BOOT_DEVICE_EMMC,
93 	UNIPHIER_BOOT_DEVICE_EMMC,
94 	UNIPHIER_BOOT_DEVICE_EMMC,
95 	UNIPHIER_BOOT_DEVICE_NAND,
96 	UNIPHIER_BOOT_DEVICE_NAND,
97 };
98 
99 static unsigned int uniphier_pxs3_get_boot_device(uint32_t pinmon)
100 {
101 	unsigned int boot_sel = (pinmon >> 1) & 0xf;
102 
103 	assert(boot_sel < ARRAY_SIZE(uniphier_pxs3_boot_device_table));
104 
105 	return uniphier_pxs3_boot_device_table[boot_sel];
106 }
107 
108 struct uniphier_boot_device_info {
109 	bool have_boot_swap;
110 	bool (*is_sd_boot)(uint32_t pinmon);
111 	bool (*is_usb_boot)(uint32_t pinmon);
112 	unsigned int (*get_boot_device)(uint32_t pinmon);
113 };
114 
115 static const struct uniphier_boot_device_info uniphier_boot_device_info[] = {
116 	[UNIPHIER_SOC_LD11] = {
117 		.have_boot_swap = true,
118 		.is_usb_boot = uniphier_ld11_is_usb_boot,
119 		.get_boot_device = uniphier_ld11_get_boot_device,
120 	},
121 	[UNIPHIER_SOC_LD20] = {
122 		.have_boot_swap = true,
123 		.is_usb_boot = uniphier_ld20_is_usb_boot,
124 		.get_boot_device = uniphier_ld11_get_boot_device,
125 	},
126 	[UNIPHIER_SOC_PXS3] = {
127 		.have_boot_swap = true,
128 		.is_usb_boot = uniphier_pxs3_is_usb_boot,
129 		.get_boot_device = uniphier_pxs3_get_boot_device,
130 	},
131 };
132 
133 unsigned int uniphier_get_boot_device(unsigned int soc)
134 {
135 	const struct uniphier_boot_device_info *info;
136 	uint32_t pinmon;
137 
138 	assert(soc < ARRAY_SIZE(uniphier_boot_device_info));
139 	info = &uniphier_boot_device_info[soc];
140 
141 	pinmon = mmio_read_32(UNIPHIER_PINMON0);
142 
143 	if (info->have_boot_swap && !(pinmon & BIT(29)))
144 		return UNIPHIER_BOOT_DEVICE_NOR;
145 
146 	if (info->is_sd_boot && info->is_sd_boot(pinmon))
147 		return UNIPHIER_BOOT_DEVICE_SD;
148 
149 	if (info->is_usb_boot && info->is_usb_boot(pinmon))
150 		return UNIPHIER_BOOT_DEVICE_USB;
151 
152 	return info->get_boot_device(pinmon);
153 }
154 
155 static const bool uniphier_have_onchip_scp[] = {
156 	[UNIPHIER_SOC_LD11] = true,
157 	[UNIPHIER_SOC_LD20] = true,
158 	[UNIPHIER_SOC_PXS3] = false,
159 };
160 
161 unsigned int uniphier_get_boot_master(unsigned int soc)
162 {
163 	assert(soc < ARRAY_SIZE(uniphier_have_onchip_scp));
164 
165 	if (uniphier_have_onchip_scp[soc]) {
166 		if (mmio_read_32(UNIPHIER_PINMON0) & BIT(27))
167 			return UNIPHIER_BOOT_MASTER_THIS;
168 		else
169 			return UNIPHIER_BOOT_MASTER_SCP;
170 	} else {
171 		return UNIPHIER_BOOT_MASTER_EXT;
172 	}
173 }
174