blob: 47d1a40ef7c63ff0e8af6604a653650e30c71c6f [file] [log] [blame]
Quentin Schulz00a6f602023-01-09 11:36:45 +01001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2022 Theobroma Systems Design und Consulting GmbH
4 */
5
6#include <common.h>
7#include <dm.h>
8#include <env.h>
9#include <env_internal.h>
10#include <init.h>
11#include <log.h>
12#include <misc.h>
13#include <spl.h>
14#include <syscon.h>
15#include <u-boot/crc.h>
16#include <usb.h>
17#include <dm/pinctrl.h>
18#include <dm/uclass-internal.h>
19#include <asm/io.h>
20#include <asm/setup.h>
21#include <asm/arch-rockchip/clock.h>
22#include <asm/arch-rockchip/hardware.h>
23#include <asm/arch-rockchip/periph.h>
24#include <asm/arch-rockchip/misc.h>
25#include <power/regulator.h>
26#include <u-boot/sha256.h>
27
28/*
29 * Swap mmc0 and mmc1 in boot_targets if booted from SD-Card.
30 *
31 * If bootsource is uSD-card we can assume that we want to use the
32 * SD-Card instead of the eMMC as first boot_target for distroboot.
33 * We only want to swap the defaults and not any custom environment a
34 * user has set. We exit early if a changed boot_targets environment
35 * is detected.
36 */
37static int setup_boottargets(void)
38{
39 const char *boot_device =
40 ofnode_read_chosen_string("u-boot,spl-boot-device");
41 char *env_default, *env;
42
43 if (!boot_device) {
44 debug("%s: /chosen/u-boot,spl-boot-device not set\n",
45 __func__);
46 return -1;
47 }
48 debug("%s: booted from %s\n", __func__, boot_device);
49
50 env_default = env_get_default("boot_targets");
51 env = env_get("boot_targets");
52 if (!env) {
53 debug("%s: boot_targets does not exist\n", __func__);
54 return -1;
55 }
56 debug("%s: boot_targets current: %s - default: %s\n",
57 __func__, env, env_default);
58
59 if (strcmp(env_default, env) != 0) {
60 debug("%s: boot_targets not default, don't change it\n",
61 __func__);
62 return 0;
63 }
64
65 /*
66 * Make the default boot medium between SD Card and eMMC, the one that
67 * was used to load U-Boot proper.
68 */
69 bool sd_booted = !strcmp(boot_device, "/mmc@ff370000");
70 char *mmc0, *mmc1;
71
72 debug("%s: booted from %s\n", __func__,
73 sd_booted ? "SD-Card" : "eMMC");
74 mmc0 = strstr(env, "mmc0");
75 mmc1 = strstr(env, "mmc1");
76
77 if (!mmc0 || !mmc1) {
78 debug("%s: only one mmc boot_target found\n", __func__);
79 return -1;
80 }
81
82 /*
83 * If mmc0 comes first in the boot order and U-Boot proper was
84 * loaded from mmc1, swap mmc0 and mmc1 in the list.
85 * If mmc1 comes first in the boot order and U-Boot proper was
86 * loaded from mmc0, swap mmc0 and mmc1 in the list.
87 */
88 if ((mmc0 < mmc1 && sd_booted) ||
89 (mmc0 > mmc1 && !sd_booted)) {
90 mmc0[3] = '1';
91 mmc1[3] = '0';
92 debug("%s: set boot_targets to: %s\n", __func__, env);
93 env_set("boot_targets", env);
94 }
95
96 return 0;
97}
98
99int mmc_get_env_dev(void)
100{
101 const char *boot_device =
102 ofnode_read_chosen_string("u-boot,spl-boot-device");
103
104 if (!boot_device) {
105 debug("%s: /chosen/u-boot,spl-boot-device not set\n",
106 __func__);
107 return CONFIG_SYS_MMC_ENV_DEV;
108 }
109
110 debug("%s: booted from %s\n", __func__, boot_device);
111
112 if (!strcmp(boot_device, "/mmc@ff370000"))
113 return 1;
114
115 if (!strcmp(boot_device, "/mmc@ff390000"))
116 return 0;
117
118 return CONFIG_SYS_MMC_ENV_DEV;
119}
120
121#if !IS_ENABLED(CONFIG_ENV_IS_NOWHERE)
122#error Please enable CONFIG_ENV_IS_NOWHERE
123#endif
124
125enum env_location arch_env_get_location(enum env_operation op, int prio)
126{
127 const char *boot_device =
128 ofnode_read_chosen_string("u-boot,spl-boot-device");
129
130 if (prio > 0)
131 return ENVL_UNKNOWN;
132
133 if (!boot_device) {
134 debug("%s: /chosen/u-boot,spl-boot-device not set\n",
135 __func__);
136 return ENVL_NOWHERE;
137 }
138
139 debug("%s: booted from %s\n", __func__, boot_device);
140
141 if (IS_ENABLED(CONFIG_ENV_IS_IN_MMC) &&
142 (!strcmp(boot_device, "/mmc@ff370000") ||
143 !strcmp(boot_device, "/mmc@ff390000")))
144 return ENVL_MMC;
145
146 printf("%s: No environment available: booted from %s but U-Boot "
147 "config does not allow loading environment from it.",
148 __func__, boot_device);
149
150 return ENVL_NOWHERE;
151}
152
153int misc_init_r(void)
154{
155 const u32 cpuid_offset = 0x7;
156 const u32 cpuid_length = 0x10;
157 u8 cpuid[cpuid_length];
158 int ret;
159
160 ret = rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid);
161 if (ret)
162 return ret;
163
164 ret = rockchip_cpuid_set(cpuid, cpuid_length);
165 if (ret)
166 return ret;
167
168 ret = rockchip_setup_macaddr();
169 if (ret)
170 return ret;
171
172 setup_boottargets();
173
174 return 0;
175}