blob: 78ca8ef06c10f7ccb8f9e76643c11ddb8beae25a [file] [log] [blame]
Masahiro Yamada574388c2016-09-03 11:37:40 +09001/*
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 <mmio.h>
9#include <stdbool.h>
10#include <stddef.h>
11#include <utils_def.h>
12
13#include "uniphier.h"
14
15#define UNIPHIER_PINMON0 0x5f900100
16#define UNIPHIER_PINMON2 0x5f900108
17
18static int uniphier_ld11_is_usb_boot(uint32_t pinmon)
19{
20 return !!(~pinmon & 0x00000080);
21}
22
23static int uniphier_ld20_is_usb_boot(uint32_t pinmon)
24{
25 return !!(~pinmon & 0x00000780);
26}
27
28static int uniphier_pxs3_is_usb_boot(uint32_t pinmon)
29{
30 uint32_t pinmon2 = mmio_read_32(UNIPHIER_PINMON2);
31
32 return !!(pinmon2 & BIT(31));
33}
34
35static const unsigned int uniphier_ld11_boot_device_table[] = {
36 UNIPHIER_BOOT_DEVICE_NAND,
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_EMMC,
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_NOR,
68};
69
70static unsigned int uniphier_ld11_get_boot_device(uint32_t pinmon)
71{
72 unsigned int boot_sel = (pinmon >> 1) & 0x1f;
73
74 assert(boot_sel < ARRAY_SIZE(uniphier_ld11_boot_device_table));
75
76 return uniphier_ld11_boot_device_table[boot_sel];
77}
78
79static const unsigned int uniphier_pxs3_boot_device_table[] = {
80 UNIPHIER_BOOT_DEVICE_NAND,
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_EMMC,
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_NAND,
95 UNIPHIER_BOOT_DEVICE_NAND,
96};
97
98static unsigned int uniphier_pxs3_get_boot_device(uint32_t pinmon)
99{
100 unsigned int boot_sel = (pinmon >> 1) & 0xf;
101
102 assert(boot_sel < ARRAY_SIZE(uniphier_pxs3_boot_device_table));
103
104 return uniphier_pxs3_boot_device_table[boot_sel];
105}
106
107struct uniphier_boot_device_info {
108 int (*is_usb_boot)(uint32_t pinmon);
109 unsigned int (*get_boot_device)(uint32_t pinmon);
110};
111
112static const struct uniphier_boot_device_info uniphier_boot_device_info[] = {
113 [UNIPHIER_SOC_LD11] = {
114 .is_usb_boot = uniphier_ld11_is_usb_boot,
115 .get_boot_device = uniphier_ld11_get_boot_device,
116 },
117 [UNIPHIER_SOC_LD20] = {
118 .is_usb_boot = uniphier_ld20_is_usb_boot,
119 .get_boot_device = uniphier_ld11_get_boot_device,
120 },
121 [UNIPHIER_SOC_PXS3] = {
122 .is_usb_boot = uniphier_pxs3_is_usb_boot,
123 .get_boot_device = uniphier_pxs3_get_boot_device,
124 },
125};
126
127unsigned int uniphier_get_boot_device(unsigned int soc)
128{
129 const struct uniphier_boot_device_info *info;
130 uint32_t pinmon;
131
132 assert(soc < ARRAY_SIZE(uniphier_boot_device_info));
133 info = &uniphier_boot_device_info[soc];
134
135 pinmon = mmio_read_32(UNIPHIER_PINMON0);
136
137 if (!(pinmon & BIT(29)))
138 return UNIPHIER_BOOT_DEVICE_NOR;
139
140 if (info->is_usb_boot(pinmon))
141 return UNIPHIER_BOOT_DEVICE_USB;
142
143 return info->get_boot_device(pinmon);
144}
145
146static const bool uniphier_have_onchip_scp[] = {
147 [UNIPHIER_SOC_LD11] = true,
148 [UNIPHIER_SOC_LD20] = true,
149 [UNIPHIER_SOC_PXS3] = false,
150};
151
152unsigned int uniphier_get_boot_master(unsigned int soc)
153{
154 assert(soc < ARRAY_SIZE(uniphier_have_onchip_scp));
155
156 if (uniphier_have_onchip_scp[soc]) {
157 if (mmio_read_32(UNIPHIER_PINMON0) & BIT(27))
158 return UNIPHIER_BOOT_MASTER_THIS;
159 else
160 return UNIPHIER_BOOT_MASTER_SCP;
161 } else {
162 return UNIPHIER_BOOT_MASTER_EXT;
163 }
164}