blob: 8f13127a6603d7bed4e9bc5240bcd4a9e85f0228 [file] [log] [blame]
Nathan Barrett-Morrison48a0b0b2024-04-24 20:04:00 -04001// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * (C) Copyright 2022 - Analog Devices, Inc.
4 *
5 * Written and/or maintained by Timesys Corporation
6 *
7 * Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
8 * Contact: Greg Malysa <greg.malysa@timesys.com>
9 */
10
11#include <asm/arch-adi/sc5xx/sc5xx.h>
12#include <asm/arch-adi/sc5xx/soc.h>
13#include <asm/global_data.h>
14#include <asm/io.h>
15#include <cpu_func.h>
16
17#ifdef CONFIG_SC58X
18 #define RCU0_CTL 0x3108B000
19 #define RCU0_STAT 0x3108B004
20 #define RCU0_CRCTL 0x3108B008
21 #define RCU0_CRSTAT 0x3108B00C
22 #define RCU0_SIDIS 0x3108B010
23 #define RCU0_MSG_SET 0x3108B064
24#elif defined(CONFIG_SC57X) || defined(CONFIG_SC59X) || defined(CONFIG_SC59X_64)
25 #define RCU0_CTL 0x3108C000
26 #define RCU0_STAT 0x3108C004
27 #define RCU0_CRCTL 0x3108C008
28 #define RCU0_CRSTAT 0x3108C00C
29 #define RCU0_SIDIS 0x3108C01C
30 #define RCU0_MSG_SET 0x3108C070
31#else
32 #error "No SC5xx SoC CONFIG_ enabled"
33#endif
34
35#define BITP_RCU_STAT_BMODE 8
36#define BITM_RCU_STAT_BMODE 0x00000F00
37
38#define REG_ARMPMU0_PMCR 0x31121E04
39#define REG_ARMPMU0_PMUSERENR 0x31121E08
40#define REG_ARMPMU0_PMLAR 0x31121FB0
41
42DECLARE_GLOBAL_DATA_PTR;
43
44void reset_cpu(void)
45{
46 u32 val = readl(RCU0_CTL);
47 writel(val | 1, RCU0_CTL);
48}
49
50void enable_caches(void)
51{
52 if (!IS_ENABLED(CONFIG_SYS_DCACHE_OFF))
53 dcache_enable();
54}
55
56void sc5xx_enable_ns_sharc_access(uintptr_t securec0_base)
57{
58 writel(0, securec0_base);
59 writel(0, securec0_base + 0x4);
60 writel(0, securec0_base + 0x8);
61}
62
63void sc5xx_disable_spu0(uintptr_t spu0_start, uintptr_t spu0_end)
64{
65 for (uintptr_t i = spu0_start; i <= spu0_end; i += 4)
66 writel(0, i);
67}
68
69/**
70 * PMU is only available on armv7 platforms and all share the same location
71 */
72void sc5xx_enable_pmu(void)
73{
74 if (!IS_ENABLED(CONFIG_SC59X_64)) {
75 writel(readl(REG_ARMPMU0_PMUSERENR) | 0x01, REG_ARMPMU0_PMUSERENR);
76 writel(0xc5acce55, REG_ARMPMU0_PMLAR);
77 writel(readl(REG_ARMPMU0_PMCR) | (1 << 1), REG_ARMPMU0_PMCR);
78 }
79}
80
81const char *sc5xx_get_boot_mode(u32 *bmode)
82{
83 static const char * const bmodes[] = {
84 "JTAG/BOOTROM",
85 "QSPI Master",
86 "QSPI Slave",
87 "UART",
88 "LP0 Slave",
89 "OSPI",
90#ifdef CONFIG_SC59X_64
91 "eMMC"
92#endif
93 };
94 u32 local_mode;
95
96 local_mode = (readl(RCU0_STAT) & BITM_RCU_STAT_BMODE) >> BITP_RCU_STAT_BMODE;
97
98#if CONFIG_ADI_SPL_FORCE_BMODE != 0
99 /*
100 * In case we want to force boot sequences such as:
101 * QSPI -> OSPI
102 * QSPI -> eMMC
103 * If this is not set, then we will always try to use the BMODE setting
104 * for both stages... i.e.
105 * QSPI -> QSPI
106 */
107
108 // (Don't allow skipping JTAG/UART BMODE settings)
109 if (local_mode != 0 && local_mode != 3)
110 local_mode = CONFIG_ADI_SPL_FORCE_BMODE;
111#endif
112
113 *bmode = local_mode;
114
115 if (local_mode >= 0 && local_mode <= ARRAY_SIZE(bmodes))
116 return bmodes[local_mode];
117 return "unknown";
118}
119
120void print_cpu_id(void)
121{
122 if (!IS_ENABLED(CONFIG_ARM64)) {
123 u32 cpuid = 0;
124
125 __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0" : "=r"(cpuid));
126
127 printf("Detected Revision: %d.%d\n", cpuid & 0xf00000 >> 20, cpuid & 0xf);
128 }
129}
130
131int print_cpuinfo(void)
132{
133 u32 bmode;
134
135 printf("CPU: ADSP %s (%s boot)\n", CONFIG_LDR_CPU, sc5xx_get_boot_mode(&bmode));
136 print_cpu_id();
137
138 return 0;
139}
140
141void fixup_dp83867_phy(struct phy_device *phydev)
142{
143 int phy_data = 0;
144
145 phy_data = phy_read(phydev, MDIO_DEVAD_NONE, 0x32);
146 phy_write(phydev, MDIO_DEVAD_NONE, 0x32, (1 << 7) | phy_data);
147 int cfg3 = 0;
148 #define MII_DP83867_CFG3 (0x1e)
149 /*
150 * Pin INT/PWDN on DP83867 should be configured as an Interrupt Output
151 * instead of a Power-Down Input on ADI SC5XX boards in order to
152 * prevent the signal interference from other peripherals during they
153 * are running at the same time.
154 */
155 cfg3 = phy_read(phydev, MDIO_DEVAD_NONE, MII_DP83867_CFG3);
156 cfg3 |= (1 << 7);
157 phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_CFG3, cfg3);
158
159 // Mystery second port fixup on ezkits with two PHYs
160 if (CONFIG_DW_PORTS & 2)
161 phy_write(phydev, MDIO_DEVAD_NONE, 0x11, 3);
162
163 if (IS_ENABLED(CONFIG_ADI_BUG_EZKHW21)) {
164 phydev->advertising &= PHY_BASIC_FEATURES;
165 phydev->speed = SPEED_100;
166 }
167
168 if (phydev->drv->config)
169 phydev->drv->config(phydev);
170
171 if (IS_ENABLED(CONFIG_ADI_BUG_EZKHW21))
172 phy_write(phydev, MDIO_DEVAD_NONE, 0, 0x3100);
173}
174
175int dram_init(void)
176{
177 gd->ram_size = CFG_SYS_SDRAM_SIZE;
178 return 0;
179}