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