• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2017, 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 
uniphier_ld11_is_usb_boot(uint32_t pinmon)19 static int uniphier_ld11_is_usb_boot(uint32_t pinmon)
20 {
21 	return !!(~pinmon & 0x00000080);
22 }
23 
uniphier_ld20_is_usb_boot(uint32_t pinmon)24 static int uniphier_ld20_is_usb_boot(uint32_t pinmon)
25 {
26 	return !!(~pinmon & 0x00000780);
27 }
28 
uniphier_pxs3_is_usb_boot(uint32_t pinmon)29 static int 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 
uniphier_ld11_get_boot_device(uint32_t pinmon)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 
uniphier_pxs3_get_boot_device(uint32_t pinmon)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 	int (*is_usb_boot)(uint32_t pinmon);
110 	unsigned int (*get_boot_device)(uint32_t pinmon);
111 };
112 
113 static const struct uniphier_boot_device_info uniphier_boot_device_info[] = {
114 	[UNIPHIER_SOC_LD11] = {
115 		.is_usb_boot = uniphier_ld11_is_usb_boot,
116 		.get_boot_device = uniphier_ld11_get_boot_device,
117 	},
118 	[UNIPHIER_SOC_LD20] = {
119 		.is_usb_boot = uniphier_ld20_is_usb_boot,
120 		.get_boot_device = uniphier_ld11_get_boot_device,
121 	},
122 	[UNIPHIER_SOC_PXS3] = {
123 		.is_usb_boot = uniphier_pxs3_is_usb_boot,
124 		.get_boot_device = uniphier_pxs3_get_boot_device,
125 	},
126 };
127 
uniphier_get_boot_device(unsigned int soc)128 unsigned int uniphier_get_boot_device(unsigned int soc)
129 {
130 	const struct uniphier_boot_device_info *info;
131 	uint32_t pinmon;
132 
133 	assert(soc < ARRAY_SIZE(uniphier_boot_device_info));
134 	info = &uniphier_boot_device_info[soc];
135 
136 	pinmon = mmio_read_32(UNIPHIER_PINMON0);
137 
138 	if (!(pinmon & BIT(29)))
139 		return UNIPHIER_BOOT_DEVICE_NOR;
140 
141 	if (info->is_usb_boot(pinmon))
142 		return UNIPHIER_BOOT_DEVICE_USB;
143 
144 	return info->get_boot_device(pinmon);
145 }
146 
147 static const bool uniphier_have_onchip_scp[] = {
148 	[UNIPHIER_SOC_LD11] = true,
149 	[UNIPHIER_SOC_LD20] = true,
150 	[UNIPHIER_SOC_PXS3] = false,
151 };
152 
uniphier_get_boot_master(unsigned int soc)153 unsigned int uniphier_get_boot_master(unsigned int soc)
154 {
155 	assert(soc < ARRAY_SIZE(uniphier_have_onchip_scp));
156 
157 	if (uniphier_have_onchip_scp[soc]) {
158 		if (mmio_read_32(UNIPHIER_PINMON0) & BIT(27))
159 			return UNIPHIER_BOOT_MASTER_THIS;
160 		else
161 			return UNIPHIER_BOOT_MASTER_SCP;
162 	} else {
163 		return UNIPHIER_BOOT_MASTER_EXT;
164 	}
165 }
166