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