mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2025-08-14 19:26:58 +02:00
The sc5xx machine code includes implementations of board_init and board_early_init_f which should not be included in the base soc support code, as they should be implemented by a board where necessary. This removes the default empty implementations of both from mach-sc5xx. Signed-off-by: Greg Malysa <malysagreg@gmail.com>
180 lines
4.4 KiB
C
180 lines
4.4 KiB
C
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
/*
|
|
* (C) Copyright 2022 - Analog Devices, Inc.
|
|
*
|
|
* Written and/or maintained by Timesys Corporation
|
|
*
|
|
* Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
|
|
* Contact: Greg Malysa <greg.malysa@timesys.com>
|
|
*/
|
|
|
|
#include <asm/arch-adi/sc5xx/sc5xx.h>
|
|
#include <asm/arch-adi/sc5xx/soc.h>
|
|
#include <asm/global_data.h>
|
|
#include <asm/io.h>
|
|
#include <cpu_func.h>
|
|
|
|
#ifdef CONFIG_SC58X
|
|
#define RCU0_CTL 0x3108B000
|
|
#define RCU0_STAT 0x3108B004
|
|
#define RCU0_CRCTL 0x3108B008
|
|
#define RCU0_CRSTAT 0x3108B00C
|
|
#define RCU0_SIDIS 0x3108B010
|
|
#define RCU0_MSG_SET 0x3108B064
|
|
#elif defined(CONFIG_SC57X) || defined(CONFIG_SC59X) || defined(CONFIG_SC59X_64)
|
|
#define RCU0_CTL 0x3108C000
|
|
#define RCU0_STAT 0x3108C004
|
|
#define RCU0_CRCTL 0x3108C008
|
|
#define RCU0_CRSTAT 0x3108C00C
|
|
#define RCU0_SIDIS 0x3108C01C
|
|
#define RCU0_MSG_SET 0x3108C070
|
|
#else
|
|
#error "No SC5xx SoC CONFIG_ enabled"
|
|
#endif
|
|
|
|
#define BITP_RCU_STAT_BMODE 8
|
|
#define BITM_RCU_STAT_BMODE 0x00000F00
|
|
|
|
#define REG_ARMPMU0_PMCR 0x31121E04
|
|
#define REG_ARMPMU0_PMUSERENR 0x31121E08
|
|
#define REG_ARMPMU0_PMLAR 0x31121FB0
|
|
|
|
DECLARE_GLOBAL_DATA_PTR;
|
|
|
|
void reset_cpu(void)
|
|
{
|
|
u32 val = readl(RCU0_CTL);
|
|
writel(val | 1, RCU0_CTL);
|
|
}
|
|
|
|
void enable_caches(void)
|
|
{
|
|
if (!IS_ENABLED(CONFIG_SYS_DCACHE_OFF))
|
|
dcache_enable();
|
|
}
|
|
|
|
void sc5xx_enable_ns_sharc_access(uintptr_t securec0_base)
|
|
{
|
|
writel(0, securec0_base);
|
|
writel(0, securec0_base + 0x4);
|
|
writel(0, securec0_base + 0x8);
|
|
}
|
|
|
|
void sc5xx_disable_spu0(uintptr_t spu0_start, uintptr_t spu0_end)
|
|
{
|
|
for (uintptr_t i = spu0_start; i <= spu0_end; i += 4)
|
|
writel(0, i);
|
|
}
|
|
|
|
/**
|
|
* PMU is only available on armv7 platforms and all share the same location
|
|
*/
|
|
void sc5xx_enable_pmu(void)
|
|
{
|
|
if (!IS_ENABLED(CONFIG_SC59X_64)) {
|
|
writel(readl(REG_ARMPMU0_PMUSERENR) | 0x01, REG_ARMPMU0_PMUSERENR);
|
|
writel(0xc5acce55, REG_ARMPMU0_PMLAR);
|
|
writel(readl(REG_ARMPMU0_PMCR) | (1 << 1), REG_ARMPMU0_PMCR);
|
|
}
|
|
}
|
|
|
|
const char *sc5xx_get_boot_mode(u32 *bmode)
|
|
{
|
|
static const char * const bmodes[] = {
|
|
"JTAG/BOOTROM",
|
|
"QSPI Master",
|
|
"QSPI Slave",
|
|
"UART",
|
|
"LP0 Slave",
|
|
"OSPI",
|
|
#ifdef CONFIG_SC59X_64
|
|
"eMMC"
|
|
#endif
|
|
};
|
|
u32 local_mode;
|
|
|
|
local_mode = (readl(RCU0_STAT) & BITM_RCU_STAT_BMODE) >> BITP_RCU_STAT_BMODE;
|
|
|
|
#if CONFIG_ADI_SPL_FORCE_BMODE != 0
|
|
/*
|
|
* In case we want to force boot sequences such as:
|
|
* QSPI -> OSPI
|
|
* QSPI -> eMMC
|
|
* If this is not set, then we will always try to use the BMODE setting
|
|
* for both stages... i.e.
|
|
* QSPI -> QSPI
|
|
*/
|
|
|
|
// (Don't allow skipping JTAG/UART BMODE settings)
|
|
if (local_mode != 0 && local_mode != 3)
|
|
local_mode = CONFIG_ADI_SPL_FORCE_BMODE;
|
|
#endif
|
|
|
|
*bmode = local_mode;
|
|
|
|
if (local_mode >= 0 && local_mode <= ARRAY_SIZE(bmodes))
|
|
return bmodes[local_mode];
|
|
return "unknown";
|
|
}
|
|
|
|
void print_cpu_id(void)
|
|
{
|
|
if (!IS_ENABLED(CONFIG_ARM64)) {
|
|
u32 cpuid = 0;
|
|
|
|
__asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0" : "=r"(cpuid));
|
|
|
|
printf("Detected Revision: %d.%d\n", cpuid & 0xf00000 >> 20, cpuid & 0xf);
|
|
}
|
|
}
|
|
|
|
int print_cpuinfo(void)
|
|
{
|
|
u32 bmode;
|
|
|
|
printf("CPU: ADSP %s (%s boot)\n", CONFIG_LDR_CPU, sc5xx_get_boot_mode(&bmode));
|
|
print_cpu_id();
|
|
|
|
return 0;
|
|
}
|
|
|
|
void fixup_dp83867_phy(struct phy_device *phydev)
|
|
{
|
|
int phy_data = 0;
|
|
|
|
phy_data = phy_read(phydev, MDIO_DEVAD_NONE, 0x32);
|
|
phy_write(phydev, MDIO_DEVAD_NONE, 0x32, (1 << 7) | phy_data);
|
|
int cfg3 = 0;
|
|
#define MII_DP83867_CFG3 (0x1e)
|
|
/*
|
|
* Pin INT/PWDN on DP83867 should be configured as an Interrupt Output
|
|
* instead of a Power-Down Input on ADI SC5XX boards in order to
|
|
* prevent the signal interference from other peripherals during they
|
|
* are running at the same time.
|
|
*/
|
|
cfg3 = phy_read(phydev, MDIO_DEVAD_NONE, MII_DP83867_CFG3);
|
|
cfg3 |= (1 << 7);
|
|
phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_CFG3, cfg3);
|
|
|
|
// Mystery second port fixup on ezkits with two PHYs
|
|
if (CONFIG_DW_PORTS & 2)
|
|
phy_write(phydev, MDIO_DEVAD_NONE, 0x11, 3);
|
|
|
|
if (IS_ENABLED(CONFIG_ADI_BUG_EZKHW21)) {
|
|
phydev->advertising &= PHY_BASIC_FEATURES;
|
|
phydev->speed = SPEED_100;
|
|
}
|
|
|
|
if (phydev->drv->config)
|
|
phydev->drv->config(phydev);
|
|
|
|
if (IS_ENABLED(CONFIG_ADI_BUG_EZKHW21))
|
|
phy_write(phydev, MDIO_DEVAD_NONE, 0, 0x3100);
|
|
}
|
|
|
|
int dram_init(void)
|
|
{
|
|
gd->ram_size = CFG_SYS_SDRAM_SIZE;
|
|
return 0;
|
|
}
|