mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-12-24 12:03:39 +00:00
12c84d5984
distroboot should try first on the same MMC medium as the one the SPL loaded U-Boot proper from. This was the case when the introducing commit was merged because the default order was eMMC first and then SD card. The check was therefore made only on whether we booted from SD card, because otherwise the order was the expected one. However, in commitb212ad24a6
("rockchip: Fix MMC boot order"), the order was swapped. Meaning our simple check is now useless. Let's fix that by accounting for all scenarii: default boot_targets has mmc0 first but booting from SD Card, mmc1 first but booting from eMMC. Fixes:b212ad24a6
("rockchip: Fix MMC boot order") Cc: Quentin Schulz <foss+uboot@0leil.net> Signed-off-by: Quentin Schulz <quentin.schulz@theobroma-systems.com> Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
139 lines
3.5 KiB
C
139 lines
3.5 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* (C) Copyright 2017 Theobroma Systems Design und Consulting GmbH
|
|
*/
|
|
|
|
#include <common.h>
|
|
#include <dm.h>
|
|
#include <env.h>
|
|
#include <init.h>
|
|
#include <log.h>
|
|
#include <misc.h>
|
|
#include <spl.h>
|
|
#include <syscon.h>
|
|
#include <u-boot/crc.h>
|
|
#include <usb.h>
|
|
#include <dm/pinctrl.h>
|
|
#include <dm/uclass-internal.h>
|
|
#include <asm/io.h>
|
|
#include <asm/setup.h>
|
|
#include <asm/arch-rockchip/clock.h>
|
|
#include <asm/arch-rockchip/hardware.h>
|
|
#include <asm/arch-rockchip/grf_rk3399.h>
|
|
#include <asm/arch-rockchip/periph.h>
|
|
#include <asm/arch-rockchip/misc.h>
|
|
#include <power/regulator.h>
|
|
#include <u-boot/sha256.h>
|
|
|
|
static void setup_iodomain(void)
|
|
{
|
|
const u32 GRF_IO_VSEL_GPIO4CD_SHIFT = 3;
|
|
struct rk3399_grf_regs *grf =
|
|
syscon_get_first_range(ROCKCHIP_SYSCON_GRF);
|
|
|
|
/*
|
|
* Set bit 3 in GRF_IO_VSEL so PCIE_RST# works (pin GPIO4_C6).
|
|
* Linux assumes that PCIE_RST# works out of the box as it probes
|
|
* PCIe before loading the iodomain driver.
|
|
*/
|
|
rk_setreg(&grf->io_vsel, 1 << GRF_IO_VSEL_GPIO4CD_SHIFT);
|
|
}
|
|
|
|
/*
|
|
* Swap mmc0 and mmc1 in boot_targets if booted from SD-Card.
|
|
*
|
|
* If bootsource is uSD-card we can assume that we want to use the
|
|
* SD-Card instead of the eMMC as first boot_target for distroboot.
|
|
* We only want to swap the defaults and not any custom environment a
|
|
* user has set. We exit early if a changed boot_targets environment
|
|
* is detected.
|
|
*/
|
|
static int setup_boottargets(void)
|
|
{
|
|
const char *boot_device =
|
|
ofnode_read_chosen_string("u-boot,spl-boot-device");
|
|
char *env_default, *env;
|
|
|
|
if (!boot_device) {
|
|
debug("%s: /chosen/u-boot,spl-boot-device not set\n",
|
|
__func__);
|
|
return -1;
|
|
}
|
|
debug("%s: booted from %s\n", __func__, boot_device);
|
|
|
|
env_default = env_get_default("boot_targets");
|
|
env = env_get("boot_targets");
|
|
if (!env) {
|
|
debug("%s: boot_targets does not exist\n", __func__);
|
|
return -1;
|
|
}
|
|
debug("%s: boot_targets current: %s - default: %s\n",
|
|
__func__, env, env_default);
|
|
|
|
if (strcmp(env_default, env) != 0) {
|
|
debug("%s: boot_targets not default, don't change it\n",
|
|
__func__);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
* Make the default boot medium between SD Card and eMMC, the one that
|
|
* was used to load U-Boot proper. If SPI-NOR flash was used, keep
|
|
* original default order.
|
|
*/
|
|
if (strcmp(boot_device, "/spi@ff1d0000/flash@0")) {
|
|
bool sd_booted = !strcmp(boot_device, "/mmc@fe320000");
|
|
char *mmc0, *mmc1;
|
|
|
|
debug("%s: booted from %s\n", __func__,
|
|
sd_booted ? "SD-Card" : "eMMC");
|
|
mmc0 = strstr(env, "mmc0");
|
|
mmc1 = strstr(env, "mmc1");
|
|
|
|
if (!mmc0 || !mmc1) {
|
|
debug("%s: only one mmc boot_target found\n", __func__);
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
* If mmc0 comes first in the boot order and U-Boot proper was
|
|
* loaded from mmc1, swap mmc0 and mmc1 in the list.
|
|
* If mmc1 comes first in the boot order and U-Boot proper was
|
|
* loaded from mmc0, swap mmc0 and mmc1 in the list.
|
|
*/
|
|
if ((mmc0 < mmc1 && sd_booted) ||
|
|
(mmc0 > mmc1 && !sd_booted)) {
|
|
mmc0[3] = '1';
|
|
mmc1[3] = '0';
|
|
debug("%s: set boot_targets to: %s\n", __func__, env);
|
|
env_set("boot_targets", env);
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int misc_init_r(void)
|
|
{
|
|
const u32 cpuid_offset = 0x7;
|
|
const u32 cpuid_length = 0x10;
|
|
u8 cpuid[cpuid_length];
|
|
int ret;
|
|
|
|
ret = rockchip_cpuid_from_efuse(cpuid_offset, cpuid_length, cpuid);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ret = rockchip_cpuid_set(cpuid, cpuid_length);
|
|
if (ret)
|
|
return ret;
|
|
|
|
ret = rockchip_setup_macaddr();
|
|
if (ret)
|
|
return ret;
|
|
|
|
setup_iodomain();
|
|
setup_boottargets();
|
|
|
|
return 0;
|
|
}
|