Add Broadcom / Netgear changes from RAXE 1.0.0.48
[project/bcm63xx/u-boot.git] / arch / arm / mach-bcmbca / bcm6858 / cpu.c
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3 * Copyright 2019 Broadcom Ltd.
4 */
5
6 #include <common.h>
7 #include <spl_ddrinit.h>
8 #include <asm/arch/cpu.h>
9 #include <asm/arch/misc.h>
10 #include "bcm_otp.h"
11 #include <spl.h>
12 #if defined(CONFIG_BCMBCA_PMC)
13 #include "pmc_drv.h"
14 #include "clk_rst.h"
15 #include "asm/arch/BPCM.h"
16 #endif
17
18 #if defined(CONFIG_TPL_BUILD)
19 static void cci400_enable(void)
20 {
21 CCI400->secr_acc |= SECURE_ACCESS_UNSECURE_ENABLE;
22 }
23
24 static void enable_ns_access(void)
25 {
26 BIUCFG->aux.permission |= 0xff;
27 }
28 #endif
29
30 #if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
31 static void swrw(unsigned int ps, unsigned int reg, unsigned int val)
32 {
33 unsigned int cmd = 0;
34 unsigned int cmd1 = 0;
35 unsigned int reg0 = 0;
36
37 PROCMON->SSBMaster.control = SWR_EN;
38
39 if (reg == 0) {
40 /* no need read reg0 in case that we write to it , we know wal :) */
41 reg0 = val;
42 } else {
43 /* read reg0 */
44 cmd1 = SWR_READ_CMD_P | SET_ADDR(ps, 0);
45 PROCMON->SSBMaster.control = cmd1;
46 SR_TEST(1)
47 reg0 = PROCMON->SSBMaster.rd_data;
48 }
49 /* write reg */
50 PROCMON->SSBMaster.wr_data = val;
51 cmd = SWR_WR_CMD_P | SET_ADDR(ps, reg);
52 PROCMON->SSBMaster.control = cmd;
53 SR_TEST(2);
54 /*toggele bit 1 reg0 this load the new regs value */
55 cmd1 = SWR_WR_CMD_P | SET_ADDR(ps, 0);
56 PROCMON->SSBMaster.wr_data = reg0 & ~0x2;
57 PROCMON->SSBMaster.control = cmd1;
58 SR_TEST(3);
59 PROCMON->SSBMaster.wr_data = reg0 | 0x2;
60 PROCMON->SSBMaster.control = cmd1;
61 SR_TEST(4);
62 PROCMON->SSBMaster.wr_data = reg0 & ~0x2;
63 PROCMON->SSBMaster.control = cmd1;
64 SR_TEST(5);
65 }
66
67 static void bcm_setsw(void)
68 {
69 swrw(1,3,0x5170);
70 swrw(1,7,0x4829);
71 swrw(2,3,0x5172);
72 swrw(2,7,0x4829);
73 }
74 #endif
75
76 #if defined(CONFIG_TPL_BUILD)
77 #define CLOCK_RESET_XTAL_CONTROL_BIT_PD_DRV (17)
78 static void disable_xtal_clk(void)
79 {
80 uint32_t data;
81 int ret;
82
83 ret = ReadBPCMRegister(PMB_ADDR_CHIP_CLKRST,
84 CLKRSTBPCMRegOffset(xtal_control), &data);
85
86 data |= (0x1 << CLOCK_RESET_XTAL_CONTROL_BIT_PD_DRV);
87
88 ret |= WriteBPCMRegister(PMB_ADDR_CHIP_CLKRST,
89 CLKRSTBPCMRegOffset(xtal_control), data);
90
91 if (ret)
92 printf("Failed to disable xtal clk\n");
93 }
94 #endif
95
96 void boost_cpu_clock(void)
97 {
98 unsigned int clk_index, cpu_clock;
99 unsigned int chipId = 0;
100 int stat;
101 bcm_otp_get_chipid(&chipId);
102
103 if (chipId == 0x5 || chipId == 0x2)
104 {
105 cpu_clock = 1000;
106 if (pll_ch_freq_set(PMB_ADDR_BIU_PLL, 0, 3))
107 printf("Error: failed to set CPU clock\n");
108 }
109 else if ( !bcm_otp_get_cpu_clk(&clk_index) )
110 cpu_clock = 500 + 500*(2-clk_index);
111 else
112 cpu_clock = 0;
113
114 /* configure AXI clock */
115 if (pll_ch_freq_set(PMB_ADDR_BIU_PLL, 2, 4))
116 printf("Error: failed to set AXI clock\n");
117
118 /* Change cpu to fast clock */
119 if ((MISC->miscStrapBus)&MISC_STRAP_BUS_CPU_SLOW_FREQ)
120 {
121 int stat;
122 PLL_CTRL_REG ctrl_reg;
123 stat = ReadBPCMRegister(PMB_ADDR_BIU_PLL, PLLBPCMRegOffset(resets), &ctrl_reg.Reg32);
124 ctrl_reg.Bits.byp_wait = 0;
125 stat |= WriteBPCMRegister(PMB_ADDR_BIU_PLL, PLLBPCMRegOffset(resets), ctrl_reg.Reg32);
126 if (stat)
127 printf("Error: failed to set cpu fast mode\n");
128 }
129
130 printf("CPU Clock: %dMHz\n", cpu_clock);
131
132 stat = PowerOnDevice(PMB_ADDR_RDPPLL);
133
134 stat = pll_ch_freq_set(PMB_ADDR_RDPPLL, 0, 2);
135 stat |= pll_ch_freq_set(PMB_ADDR_RDPPLL, 1, 1);
136
137 if (stat)
138 printf("Error: Failed to set RDPPLL\n");
139
140 disable_xtal_clk();
141 }
142
143 int arch_cpu_init(void)
144 {
145 #if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
146 spl_ddrinit_prepare();
147 // enable system timer
148 BIUCFG->TSO_CNTCR |= 1;
149
150 bcm_setsw();
151 /* enable unalgined access */
152 set_sctlr(get_sctlr() & ~CR_A);
153 #endif
154
155 #if defined(CONFIG_TPL_BUILD)
156 enable_ns_access();
157 cci400_enable();
158 #endif
159
160 return 0;
161 }
162
163 #if !defined(CONFIG_SPL_BUILD)
164 void print_chipinfo(void)
165 {
166 char *mktname = NULL;
167 char *nr_cores = NULL;
168 unsigned int cpu_speed, rdp_speed, chipId;
169 unsigned int revId = PERF->RevID & REV_ID_MASK;
170
171 if (bcm_otp_get_chipid(&chipId)) {
172 chipId = 0;
173 }
174
175
176 switch (chipId) {
177 case(0x0):
178 nr_cores = "Quad";
179 case(0x1):
180 mktname = "68580X";
181 break;
182 case(0x2):
183 nr_cores = "Dual";
184 mktname = "55040";
185 break;
186 case(0x3):
187 mktname = "68580H";
188 break;
189 case(0x4):
190 mktname = "55040P";
191 break;
192 case(0x5):
193 nr_cores = "Dual";
194 mktname = "55045";
195 break;
196 case(0x6):
197 mktname = "68580XV";
198 break;
199 case(0x7):
200 mktname = "49508";
201 break;
202 case(0x8):
203 mktname = "62119";
204 break;
205 case(0x9):
206 mktname = "68580XP";
207 break;
208 case(0xA):
209 mktname = "62119P";
210 break;
211 case(0xB):
212 nr_cores = "Dual";
213 mktname = "55040B";
214 break;
215 case(0xC):
216 mktname = "55040M";
217 break;
218 case(0xD):
219 mktname = "68580XF";
220 break;
221 default:
222 mktname = NULL;
223 }
224
225 printf("Chip ID: BCM%s_%X\n",mktname,revId);
226
227 pll_ch_freq_get(PMB_ADDR_BIU_PLL, 0, &cpu_speed);
228 printf("Broadcom B53 %s Core: %dMHz\n", nr_cores, cpu_speed);
229
230 get_rdp_freq(&rdp_speed);
231 printf("RDP: %dMHz\n",rdp_speed);
232 }
233 #endif
234
235 int bcmbca_get_boot_device(void)
236 {
237 unsigned int bootsel = ((MISC->miscStrapBus & MISC_STRAP_BUS_BOOT_SEL0_4_MASK) >> MISC_STRAP_BUS_BOOT_SEL0_4_SHIFT) |
238 ((MISC->miscStrapBus & MISC_STRAP_BUS_BOOT_SEL5_MASK) >> BOOT_SEL5_STRAP_ADJ_SHIFT);
239
240 if ((bootsel & BOOT_SEL_STRAP_BOOT_SEL_NAND_MASK) == BOOT_SEL_STRAP_NAND)
241 return BOOT_DEVICE_NAND;
242
243 if ((bootsel & BOOT_SEL_STRAP_BOOT_SEL_MASK) == BOOT_SEL_STRAP_SPI_NAND)
244 return BOOT_DEVICE_SPI;
245
246 if ((bootsel & BOOT_SEL_STRAP_BOOT_SEL_MASK) == BOOT_SEL_STRAP_EMMC)
247 return BOOT_DEVICE_MMC1;
248
249 printf("Error: boot_sel straps are not set correctly\n");
250
251 return BOOT_DEVICE_NONE;
252 }
253
254 #if !defined(CONFIG_TPL_ATF)
255 void boot_secondary_cpu(unsigned long vector)
256 {
257 uint32_t cpu = 1;
258 uint32_t nr_cpus = 4;
259 ARM_CONTROL_REG ctrl_reg;
260
261 printf("boot secondary cpu from 0x%lx\n", vector);
262
263 while (cpu < nr_cpus) {
264 int stat;
265
266 BIUCFG->cluster[0].rvbar_addr[cpu] = vector >> 8;
267 stat = PowerOnDevice(PMB_ADDR_ORION_CPU0 + cpu);
268 if (stat != kPMC_NO_ERROR)
269 printf("failed to power on secondary cpu %d - sts %d\n", cpu, stat);
270
271 stat = ReadBPCMRegister(PMB_ADDR_BIU_BPCM, ARMBPCMRegOffset(arm_control), &ctrl_reg.Reg32);
272 ctrl_reg.Bits.cpu_reset_n &= ~(0x1 << cpu);
273 stat |= WriteBPCMRegister(PMB_ADDR_BIU_BPCM, ARMBPCMRegOffset(arm_control), ctrl_reg.Reg32);
274 if (stat != kPMC_NO_ERROR)
275 printf("failed to boot secondary cpu %d - sts %d\n", cpu, stat);
276 cpu++;
277 }
278
279 return;
280 }
281 #endif