Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 | // 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; } |