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
162d431df8SMasahiro Yamada #define UNIPHIER_PINMON0 0x0
172d431df8SMasahiro Yamada #define UNIPHIER_PINMON2 0x8
182d431df8SMasahiro Yamada
192d431df8SMasahiro Yamada static const uintptr_t uniphier_pinmon_base[] = {
202d431df8SMasahiro Yamada [UNIPHIER_SOC_LD11] = 0x5f900100,
212d431df8SMasahiro Yamada [UNIPHIER_SOC_LD20] = 0x5f900100,
222d431df8SMasahiro Yamada [UNIPHIER_SOC_PXS3] = 0x5f900100,
232d431df8SMasahiro Yamada };
24d8e919c7SMasahiro Yamada
uniphier_ld11_is_usb_boot(uint32_t pinmon)2543bbac27SMasahiro Yamada static bool uniphier_ld11_is_usb_boot(uint32_t pinmon)
26d8e919c7SMasahiro Yamada {
27d8e919c7SMasahiro Yamada return !!(~pinmon & 0x00000080);
28d8e919c7SMasahiro Yamada }
29d8e919c7SMasahiro Yamada
uniphier_ld20_is_usb_boot(uint32_t pinmon)3043bbac27SMasahiro Yamada static bool uniphier_ld20_is_usb_boot(uint32_t pinmon)
31d8e919c7SMasahiro Yamada {
32d8e919c7SMasahiro Yamada return !!(~pinmon & 0x00000780);
33d8e919c7SMasahiro Yamada }
34d8e919c7SMasahiro Yamada
uniphier_pxs3_is_usb_boot(uint32_t pinmon)3543bbac27SMasahiro Yamada static bool uniphier_pxs3_is_usb_boot(uint32_t pinmon)
36d8e919c7SMasahiro Yamada {
372d431df8SMasahiro Yamada uintptr_t pinmon_base = uniphier_pinmon_base[UNIPHIER_SOC_PXS3];
382d431df8SMasahiro Yamada uint32_t pinmon2 = mmio_read_32(pinmon_base + UNIPHIER_PINMON2);
39d8e919c7SMasahiro Yamada
40d8e919c7SMasahiro Yamada return !!(pinmon2 & BIT(31));
41d8e919c7SMasahiro Yamada }
42d8e919c7SMasahiro Yamada
43d8e919c7SMasahiro Yamada static const unsigned int uniphier_ld11_boot_device_table[] = {
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_NAND,
62d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NAND,
63d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NAND,
64d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NAND,
65d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NAND,
66d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NAND,
67d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NAND,
68d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_EMMC,
69d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_EMMC,
70d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_EMMC,
71d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_EMMC,
72d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_EMMC,
73d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_EMMC,
74d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_EMMC,
75d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NOR,
76d8e919c7SMasahiro Yamada };
77d8e919c7SMasahiro Yamada
uniphier_ld11_get_boot_device(uint32_t pinmon)78d8e919c7SMasahiro Yamada static unsigned int uniphier_ld11_get_boot_device(uint32_t pinmon)
79d8e919c7SMasahiro Yamada {
80d8e919c7SMasahiro Yamada unsigned int boot_sel = (pinmon >> 1) & 0x1f;
81d8e919c7SMasahiro Yamada
82d8e919c7SMasahiro Yamada assert(boot_sel < ARRAY_SIZE(uniphier_ld11_boot_device_table));
83d8e919c7SMasahiro Yamada
84d8e919c7SMasahiro Yamada return uniphier_ld11_boot_device_table[boot_sel];
85d8e919c7SMasahiro Yamada }
86d8e919c7SMasahiro Yamada
87d8e919c7SMasahiro Yamada static const unsigned int uniphier_pxs3_boot_device_table[] = {
88d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NAND,
89d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NAND,
90d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NAND,
91d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NAND,
92d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NAND,
93d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NAND,
94d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NAND,
95d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NAND,
96d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_EMMC,
97d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_EMMC,
98d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_EMMC,
99d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_EMMC,
100d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_EMMC,
101d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_EMMC,
102d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NAND,
103d8e919c7SMasahiro Yamada UNIPHIER_BOOT_DEVICE_NAND,
104d8e919c7SMasahiro Yamada };
105d8e919c7SMasahiro Yamada
uniphier_pxs3_get_boot_device(uint32_t pinmon)106d8e919c7SMasahiro Yamada static unsigned int uniphier_pxs3_get_boot_device(uint32_t pinmon)
107d8e919c7SMasahiro Yamada {
108d8e919c7SMasahiro Yamada unsigned int boot_sel = (pinmon >> 1) & 0xf;
109d8e919c7SMasahiro Yamada
110d8e919c7SMasahiro Yamada assert(boot_sel < ARRAY_SIZE(uniphier_pxs3_boot_device_table));
111d8e919c7SMasahiro Yamada
112d8e919c7SMasahiro Yamada return uniphier_pxs3_boot_device_table[boot_sel];
113d8e919c7SMasahiro Yamada }
114d8e919c7SMasahiro Yamada
115d8e919c7SMasahiro Yamada struct uniphier_boot_device_info {
116*2cb26005SMasahiro Yamada bool have_boot_swap;
117*2cb26005SMasahiro Yamada bool (*is_sd_boot)(uint32_t pinmon);
11843bbac27SMasahiro Yamada bool (*is_usb_boot)(uint32_t pinmon);
119d8e919c7SMasahiro Yamada unsigned int (*get_boot_device)(uint32_t pinmon);
120d8e919c7SMasahiro Yamada };
121d8e919c7SMasahiro Yamada
122d8e919c7SMasahiro Yamada static const struct uniphier_boot_device_info uniphier_boot_device_info[] = {
123d8e919c7SMasahiro Yamada [UNIPHIER_SOC_LD11] = {
124*2cb26005SMasahiro Yamada .have_boot_swap = true,
125d8e919c7SMasahiro Yamada .is_usb_boot = uniphier_ld11_is_usb_boot,
126d8e919c7SMasahiro Yamada .get_boot_device = uniphier_ld11_get_boot_device,
127d8e919c7SMasahiro Yamada },
128d8e919c7SMasahiro Yamada [UNIPHIER_SOC_LD20] = {
129*2cb26005SMasahiro Yamada .have_boot_swap = true,
130d8e919c7SMasahiro Yamada .is_usb_boot = uniphier_ld20_is_usb_boot,
131d8e919c7SMasahiro Yamada .get_boot_device = uniphier_ld11_get_boot_device,
132d8e919c7SMasahiro Yamada },
133d8e919c7SMasahiro Yamada [UNIPHIER_SOC_PXS3] = {
134*2cb26005SMasahiro Yamada .have_boot_swap = true,
135d8e919c7SMasahiro Yamada .is_usb_boot = uniphier_pxs3_is_usb_boot,
136d8e919c7SMasahiro Yamada .get_boot_device = uniphier_pxs3_get_boot_device,
137d8e919c7SMasahiro Yamada },
138d8e919c7SMasahiro Yamada };
139d8e919c7SMasahiro Yamada
uniphier_get_boot_device(unsigned int soc)140d8e919c7SMasahiro Yamada unsigned int uniphier_get_boot_device(unsigned int soc)
141d8e919c7SMasahiro Yamada {
142d8e919c7SMasahiro Yamada const struct uniphier_boot_device_info *info;
1432d431df8SMasahiro Yamada uintptr_t pinmon_base;
144d8e919c7SMasahiro Yamada uint32_t pinmon;
145d8e919c7SMasahiro Yamada
146d8e919c7SMasahiro Yamada assert(soc < ARRAY_SIZE(uniphier_boot_device_info));
147d8e919c7SMasahiro Yamada info = &uniphier_boot_device_info[soc];
148d8e919c7SMasahiro Yamada
1492d431df8SMasahiro Yamada assert(soc < ARRAY_SIZE(uniphier_boot_device_info));
1502d431df8SMasahiro Yamada pinmon_base = uniphier_pinmon_base[soc];
1512d431df8SMasahiro Yamada
1522d431df8SMasahiro Yamada pinmon = mmio_read_32(pinmon_base + UNIPHIER_PINMON0);
153d8e919c7SMasahiro Yamada
154*2cb26005SMasahiro Yamada if (info->have_boot_swap && !(pinmon & BIT(29)))
155d8e919c7SMasahiro Yamada return UNIPHIER_BOOT_DEVICE_NOR;
156d8e919c7SMasahiro Yamada
157*2cb26005SMasahiro Yamada if (info->is_sd_boot && info->is_sd_boot(pinmon))
158*2cb26005SMasahiro Yamada return UNIPHIER_BOOT_DEVICE_SD;
159*2cb26005SMasahiro Yamada
160*2cb26005SMasahiro Yamada if (info->is_usb_boot && info->is_usb_boot(pinmon))
161d8e919c7SMasahiro Yamada return UNIPHIER_BOOT_DEVICE_USB;
162d8e919c7SMasahiro Yamada
163d8e919c7SMasahiro Yamada return info->get_boot_device(pinmon);
164d8e919c7SMasahiro Yamada }
165d8e919c7SMasahiro Yamada
166d8e919c7SMasahiro Yamada static const bool uniphier_have_onchip_scp[] = {
167d8e919c7SMasahiro Yamada [UNIPHIER_SOC_LD11] = true,
168d8e919c7SMasahiro Yamada [UNIPHIER_SOC_LD20] = true,
169d8e919c7SMasahiro Yamada [UNIPHIER_SOC_PXS3] = false,
170d8e919c7SMasahiro Yamada };
171d8e919c7SMasahiro Yamada
uniphier_get_boot_master(unsigned int soc)172d8e919c7SMasahiro Yamada unsigned int uniphier_get_boot_master(unsigned int soc)
173d8e919c7SMasahiro Yamada {
174d8e919c7SMasahiro Yamada assert(soc < ARRAY_SIZE(uniphier_have_onchip_scp));
175d8e919c7SMasahiro Yamada
176d8e919c7SMasahiro Yamada if (uniphier_have_onchip_scp[soc]) {
1772d431df8SMasahiro Yamada uintptr_t pinmon_base;
1782d431df8SMasahiro Yamada
1792d431df8SMasahiro Yamada assert(soc < ARRAY_SIZE(uniphier_boot_device_info));
1802d431df8SMasahiro Yamada pinmon_base = uniphier_pinmon_base[soc];
1812d431df8SMasahiro Yamada
1822d431df8SMasahiro Yamada if (mmio_read_32(pinmon_base + UNIPHIER_PINMON0) & BIT(27))
183d8e919c7SMasahiro Yamada return UNIPHIER_BOOT_MASTER_THIS;
184d8e919c7SMasahiro Yamada else
185d8e919c7SMasahiro Yamada return UNIPHIER_BOOT_MASTER_SCP;
186d8e919c7SMasahiro Yamada } else {
187d8e919c7SMasahiro Yamada return UNIPHIER_BOOT_MASTER_EXT;
188d8e919c7SMasahiro Yamada }
189d8e919c7SMasahiro Yamada }
190