u-boot/board/freescale/imx8ulp_evk/spl.c
Ye Li 3524540e70 imx: imx8ulp: Load the lposc fuse for dual boot
Found the lposc fuse loading having impact to cpu idle in kernel.
Without the loading in dual boot mode, kernel will hang after idle
for a while.

Reviewed-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Ye Li <ye.li@nxp.com>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
2022-04-12 17:33:56 +02:00

113 lines
2.1 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2021 NXP
*/
#include <common.h>
#include <init.h>
#include <spl.h>
#include <asm/io.h>
#include <errno.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/clock.h>
#include <asm/arch/imx8ulp-pins.h>
#include <dm/uclass.h>
#include <dm/device.h>
#include <dm/uclass-internal.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <asm/arch/ddr.h>
#include <asm/arch/rdc.h>
#include <asm/arch/upower.h>
DECLARE_GLOBAL_DATA_PTR;
void spl_dram_init(void)
{
/* Reboot in dual boot setting no need to init ddr again */
bool ddr_enable = pcc_clock_is_enable(5, LPDDR4_PCC5_SLOT);
if (!ddr_enable) {
init_clk_ddr();
ddr_init(&dram_timing);
} else {
/* reinit pfd/pfddiv and lpavnic except pll4*/
cgc2_pll4_init(false);
}
}
u32 spl_boot_device(void)
{
return BOOT_DEVICE_BOOTROM;
}
int power_init_board(void)
{
if (IS_ENABLED(CONFIG_IMX8ULP_LD_MODE)) {
/* Set buck3 to 0.9v LD */
upower_pmic_i2c_write(0x22, 0x18);
} else if (IS_ENABLED(CONFIG_IMX8ULP_ND_MODE)) {
/* Set buck3 to 1.0v ND */
upower_pmic_i2c_write(0x22, 0x20);
} else {
/* Set buck3 to 1.1v OD */
upower_pmic_i2c_write(0x22, 0x28);
}
return 0;
}
void spl_board_init(void)
{
struct udevice *dev;
uclass_find_first_device(UCLASS_MISC, &dev);
for (; dev; uclass_find_next_device(&dev)) {
if (device_probe(dev))
continue;
}
board_early_init_f();
preloader_console_init();
puts("Normal Boot\n");
/* After AP set iomuxc0, the i2c can't work, Need M33 to set it now */
/* Load the lposc fuse to work around ROM issue. The fuse depends on S400 to read. */
if (is_soc_rev(CHIP_REV_1_0))
load_lposc_fuse();
upower_init();
power_init_board();
clock_init_late();
/* DDR initialization */
spl_dram_init();
/* This must place after upower init, so access to MDA and MRC are valid */
/* Init XRDC MDA */
xrdc_init_mda();
/* Init XRDC MRC for VIDEO, DSP domains */
xrdc_init_mrc();
/* Call it after PS16 power up */
set_lpav_qos();
}
void board_init_f(ulong dummy)
{
/* Clear the BSS. */
memset(__bss_start, 0, __bss_end - __bss_start);
timer_init();
arch_cpu_init();
board_init_r(NULL, 0);
}