]>
Commit | Line | Data |
---|---|---|
a13110a9 KG |
1 | /* |
2 | * (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH | |
3 | * | |
4 | * SPDX-License-Identifier: GPL-2.0+ | |
5 | */ | |
fb740646 | 6 | |
a13110a9 KG |
7 | #include <common.h> |
8 | #include <dm.h> | |
e92e5803 | 9 | #include <misc.h> |
a13110a9 KG |
10 | #include <dm/pinctrl.h> |
11 | #include <dm/uclass-internal.h> | |
9415b9a7 | 12 | #include <asm/setup.h> |
a13110a9 KG |
13 | #include <asm/arch/periph.h> |
14 | #include <power/regulator.h> | |
fb740646 | 15 | #include <spl.h> |
e92e5803 PT |
16 | #include <u-boot/sha256.h> |
17 | ||
a13110a9 KG |
18 | DECLARE_GLOBAL_DATA_PTR; |
19 | ||
20 | int board_init(void) | |
21 | { | |
a13110a9 KG |
22 | int ret; |
23 | ||
24 | /* | |
0b5e7aab PT |
25 | * We need to call into regulators_enable_boot_on() again, as the call |
26 | * during SPL may have not included all regulators. | |
a13110a9 | 27 | */ |
0b5e7aab | 28 | ret = regulators_enable_boot_on(false); |
a13110a9 | 29 | if (ret) |
0b5e7aab | 30 | debug("%s: Cannot enable boot on regulator\n", __func__); |
a13110a9 | 31 | |
a13110a9 KG |
32 | return 0; |
33 | } | |
34 | ||
fb740646 PT |
35 | void spl_board_init(void) |
36 | { | |
482cf223 PT |
37 | int ret; |
38 | ||
39 | /* | |
40 | * Turning the eMMC and SPI back on (if disabled via the Qseven | |
41 | * BIOS_ENABLE) signal is done through a always-on regulator). | |
42 | */ | |
43 | ret = regulators_enable_boot_on(false); | |
44 | if (ret) | |
45 | debug("%s: Cannot enable boot on regulator\n", __func__); | |
46 | ||
fb740646 PT |
47 | preloader_console_init(); |
48 | } | |
49 | ||
8adc9d18 KG |
50 | static void setup_macaddr(void) |
51 | { | |
52 | #if CONFIG_IS_ENABLED(CMD_NET) | |
53 | int ret; | |
00caae6d | 54 | const char *cpuid = env_get("cpuid#"); |
8adc9d18 KG |
55 | u8 hash[SHA256_SUM_LEN]; |
56 | int size = sizeof(hash); | |
57 | u8 mac_addr[6]; | |
58 | ||
59 | /* Only generate a MAC address, if none is set in the environment */ | |
00caae6d | 60 | if (env_get("ethaddr")) |
8adc9d18 KG |
61 | return; |
62 | ||
63 | if (!cpuid) { | |
64 | debug("%s: could not retrieve 'cpuid#'\n", __func__); | |
65 | return; | |
66 | } | |
67 | ||
68 | ret = hash_block("sha256", (void *)cpuid, strlen(cpuid), hash, &size); | |
69 | if (ret) { | |
70 | debug("%s: failed to calculate SHA256\n", __func__); | |
71 | return; | |
72 | } | |
73 | ||
74 | /* Copy 6 bytes of the hash to base the MAC address on */ | |
75 | memcpy(mac_addr, hash, 6); | |
76 | ||
77 | /* Make this a valid MAC address and set it */ | |
78 | mac_addr[0] &= 0xfe; /* clear multicast bit */ | |
79 | mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */ | |
fd1e959e | 80 | eth_env_set_enetaddr("ethaddr", mac_addr); |
8adc9d18 | 81 | #endif |
8adc9d18 KG |
82 | } |
83 | ||
9415b9a7 PT |
84 | static void setup_serial(void) |
85 | { | |
86 | #if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE) | |
26722335 KY |
87 | const u32 cpuid_offset = 0x7; |
88 | const u32 cpuid_length = 0x10; | |
89 | ||
9415b9a7 PT |
90 | struct udevice *dev; |
91 | int ret, i; | |
26722335 KY |
92 | u8 cpuid[cpuid_length]; |
93 | u8 low[cpuid_length/2], high[cpuid_length/2]; | |
94 | char cpuid_str[cpuid_length * 2 + 1]; | |
9415b9a7 | 95 | u64 serialno; |
60d7c509 | 96 | char serialno_str[17]; |
9415b9a7 | 97 | |
8adc9d18 KG |
98 | /* retrieve the device */ |
99 | ret = uclass_get_device_by_driver(UCLASS_MISC, | |
100 | DM_GET_DRIVER(rockchip_efuse), &dev); | |
9415b9a7 PT |
101 | if (ret) { |
102 | debug("%s: could not find efuse device\n", __func__); | |
103 | return; | |
104 | } | |
105 | ||
106 | /* read the cpu_id range from the efuses */ | |
26722335 | 107 | ret = misc_read(dev, cpuid_offset, &cpuid, sizeof(cpuid)); |
9415b9a7 PT |
108 | if (ret) { |
109 | debug("%s: reading cpuid from the efuses failed\n", | |
110 | __func__); | |
111 | return; | |
112 | } | |
113 | ||
114 | memset(cpuid_str, 0, sizeof(cpuid_str)); | |
115 | for (i = 0; i < 16; i++) | |
116 | sprintf(&cpuid_str[i * 2], "%02x", cpuid[i]); | |
117 | ||
118 | debug("cpuid: %s\n", cpuid_str); | |
119 | ||
120 | /* | |
121 | * Mix the cpuid bytes using the same rules as in | |
122 | * ${linux}/drivers/soc/rockchip/rockchip-cpuinfo.c | |
123 | */ | |
124 | for (i = 0; i < 8; i++) { | |
125 | low[i] = cpuid[1 + (i << 1)]; | |
126 | high[i] = cpuid[i << 1]; | |
127 | } | |
128 | ||
129 | serialno = crc32_no_comp(0, low, 8); | |
130 | serialno |= (u64)crc32_no_comp(serialno, high, 8) << 32; | |
131 | snprintf(serialno_str, sizeof(serialno_str), "%llx", serialno); | |
132 | ||
382bee57 SG |
133 | env_set("cpuid#", cpuid_str); |
134 | env_set("serial#", serialno_str); | |
9415b9a7 | 135 | #endif |
9415b9a7 PT |
136 | } |
137 | ||
138 | int misc_init_r(void) | |
139 | { | |
140 | setup_serial(); | |
8adc9d18 | 141 | setup_macaddr(); |
9415b9a7 PT |
142 | |
143 | return 0; | |
144 | } | |
145 | ||
146 | #ifdef CONFIG_SERIAL_TAG | |
147 | void get_board_serial(struct tag_serialnr *serialnr) | |
148 | { | |
149 | char *serial_string; | |
150 | u64 serial = 0; | |
151 | ||
00caae6d | 152 | serial_string = env_get("serial#"); |
9415b9a7 PT |
153 | |
154 | if (serial_string) | |
155 | serial = simple_strtoull(serial_string, NULL, 16); | |
156 | ||
157 | serialnr->high = (u32)(serial >> 32); | |
158 | serialnr->low = (u32)(serial & 0xffffffff); | |
159 | } | |
160 | #endif |