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