]>
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 | */ | |
6 | #include <common.h> | |
7 | #include <dm.h> | |
e92e5803 PT |
8 | #include <misc.h> |
9 | #include <ram.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> | |
e92e5803 PT |
15 | #include <u-boot/sha256.h> |
16 | ||
a13110a9 KG |
17 | DECLARE_GLOBAL_DATA_PTR; |
18 | ||
19 | int board_init(void) | |
20 | { | |
21 | struct udevice *pinctrl, *regulator; | |
22 | int ret; | |
23 | ||
24 | /* | |
25 | * The PWM does not have decicated interrupt number in dts and can | |
26 | * not get periph_id by pinctrl framework, so let's init them here. | |
27 | * The PWM2 and PWM3 are for pwm regulators. | |
28 | */ | |
29 | ret = uclass_get_device(UCLASS_PINCTRL, 0, &pinctrl); | |
30 | if (ret) { | |
31 | debug("%s: Cannot find pinctrl device\n", __func__); | |
32 | goto out; | |
33 | } | |
34 | ||
35 | ret = pinctrl_request_noflags(pinctrl, PERIPH_ID_PWM2); | |
36 | if (ret) { | |
37 | debug("%s PWM2 pinctrl init fail!\n", __func__); | |
38 | goto out; | |
39 | } | |
40 | ||
41 | /* rk3399 need to init vdd_center to get the correct output voltage */ | |
42 | ret = regulator_get_by_platname("vdd_center", ®ulator); | |
43 | if (ret) | |
44 | debug("%s: Cannot get vdd_center regulator\n", __func__); | |
45 | ||
46 | ret = regulator_get_by_platname("vcc5v0_host", ®ulator); | |
47 | if (ret) { | |
48 | debug("%s vcc5v0_host init fail! ret %d\n", __func__, ret); | |
49 | goto out; | |
50 | } | |
51 | ||
52 | ret = regulator_set_enable(regulator, true); | |
53 | if (ret) { | |
54 | debug("%s vcc5v0-host-en set fail!\n", __func__); | |
55 | goto out; | |
56 | } | |
57 | ||
58 | out: | |
59 | return 0; | |
60 | } | |
61 | ||
8adc9d18 KG |
62 | static void setup_macaddr(void) |
63 | { | |
64 | #if CONFIG_IS_ENABLED(CMD_NET) | |
65 | int ret; | |
66 | const char *cpuid = getenv("cpuid#"); | |
67 | u8 hash[SHA256_SUM_LEN]; | |
68 | int size = sizeof(hash); | |
69 | u8 mac_addr[6]; | |
70 | ||
71 | /* Only generate a MAC address, if none is set in the environment */ | |
72 | if (getenv("ethaddr")) | |
73 | return; | |
74 | ||
75 | if (!cpuid) { | |
76 | debug("%s: could not retrieve 'cpuid#'\n", __func__); | |
77 | return; | |
78 | } | |
79 | ||
80 | ret = hash_block("sha256", (void *)cpuid, strlen(cpuid), hash, &size); | |
81 | if (ret) { | |
82 | debug("%s: failed to calculate SHA256\n", __func__); | |
83 | return; | |
84 | } | |
85 | ||
86 | /* Copy 6 bytes of the hash to base the MAC address on */ | |
87 | memcpy(mac_addr, hash, 6); | |
88 | ||
89 | /* Make this a valid MAC address and set it */ | |
90 | mac_addr[0] &= 0xfe; /* clear multicast bit */ | |
91 | mac_addr[0] |= 0x02; /* set local assignment bit (IEEE802) */ | |
92 | eth_setenv_enetaddr("ethaddr", mac_addr); | |
93 | #endif | |
94 | ||
95 | return; | |
96 | } | |
97 | ||
9415b9a7 PT |
98 | static void setup_serial(void) |
99 | { | |
100 | #if CONFIG_IS_ENABLED(ROCKCHIP_EFUSE) | |
26722335 KY |
101 | const u32 cpuid_offset = 0x7; |
102 | const u32 cpuid_length = 0x10; | |
103 | ||
9415b9a7 PT |
104 | struct udevice *dev; |
105 | int ret, i; | |
26722335 KY |
106 | u8 cpuid[cpuid_length]; |
107 | u8 low[cpuid_length/2], high[cpuid_length/2]; | |
108 | char cpuid_str[cpuid_length * 2 + 1]; | |
9415b9a7 PT |
109 | u64 serialno; |
110 | char serialno_str[16]; | |
111 | ||
8adc9d18 KG |
112 | /* retrieve the device */ |
113 | ret = uclass_get_device_by_driver(UCLASS_MISC, | |
114 | DM_GET_DRIVER(rockchip_efuse), &dev); | |
9415b9a7 PT |
115 | if (ret) { |
116 | debug("%s: could not find efuse device\n", __func__); | |
117 | return; | |
118 | } | |
119 | ||
120 | /* read the cpu_id range from the efuses */ | |
26722335 | 121 | ret = misc_read(dev, cpuid_offset, &cpuid, sizeof(cpuid)); |
9415b9a7 PT |
122 | if (ret) { |
123 | debug("%s: reading cpuid from the efuses failed\n", | |
124 | __func__); | |
125 | return; | |
126 | } | |
127 | ||
128 | memset(cpuid_str, 0, sizeof(cpuid_str)); | |
129 | for (i = 0; i < 16; i++) | |
130 | sprintf(&cpuid_str[i * 2], "%02x", cpuid[i]); | |
131 | ||
132 | debug("cpuid: %s\n", cpuid_str); | |
133 | ||
134 | /* | |
135 | * Mix the cpuid bytes using the same rules as in | |
136 | * ${linux}/drivers/soc/rockchip/rockchip-cpuinfo.c | |
137 | */ | |
138 | for (i = 0; i < 8; i++) { | |
139 | low[i] = cpuid[1 + (i << 1)]; | |
140 | high[i] = cpuid[i << 1]; | |
141 | } | |
142 | ||
143 | serialno = crc32_no_comp(0, low, 8); | |
144 | serialno |= (u64)crc32_no_comp(serialno, high, 8) << 32; | |
145 | snprintf(serialno_str, sizeof(serialno_str), "%llx", serialno); | |
146 | ||
382bee57 SG |
147 | env_set("cpuid#", cpuid_str); |
148 | env_set("serial#", serialno_str); | |
9415b9a7 PT |
149 | #endif |
150 | ||
151 | return; | |
152 | } | |
153 | ||
154 | int misc_init_r(void) | |
155 | { | |
156 | setup_serial(); | |
8adc9d18 | 157 | setup_macaddr(); |
9415b9a7 PT |
158 | |
159 | return 0; | |
160 | } | |
161 | ||
162 | #ifdef CONFIG_SERIAL_TAG | |
163 | void get_board_serial(struct tag_serialnr *serialnr) | |
164 | { | |
165 | char *serial_string; | |
166 | u64 serial = 0; | |
167 | ||
168 | serial_string = getenv("serial#"); | |
169 | ||
170 | if (serial_string) | |
171 | serial = simple_strtoull(serial_string, NULL, 16); | |
172 | ||
173 | serialnr->high = (u32)(serial >> 32); | |
174 | serialnr->low = (u32)(serial & 0xffffffff); | |
175 | } | |
176 | #endif |