Add Broadcom / Netgear changes from RAXE 1.0.0.48
[project/bcm63xx/u-boot.git] / arch / arm / mach-bcmbca / bcm4912 / cpu.c
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 /*
3 * Copyright 2019 Broadcom Ltd.
4 */
5
6 #include <common.h>
7 #include <asm/arch/cpu.h>
8 #include <asm/io.h>
9 #include <spl.h>
10 #if defined(CONFIG_BCMBCA_DDRC)
11 #include <asm/arch/ddr.h>
12 #endif
13 #if defined(CONFIG_BCMBCA_PMC)
14 #include "pmc_drv.h"
15 #include "asm/arch/BPCM.h"
16 #endif
17 #include "tpl_params.h"
18
19 #if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
20
21 static void enable_ts0_couner(void)
22 {
23 BIUCFG->ts0_ctrl.CNTCR |= 0x1;
24 }
25
26 static void enable_upper_memory_access(void)
27 {
28 /* enable the 8G to 16G address range for memc */
29 BIUCFG->bac.bac_cciaddr = 0x55550055;
30 CCI500->ctrl_ovr |= (1 << 29);
31 }
32
33 #elif defined(CONFIG_TPL_BUILD)
34 static void cci500_enable(void)
35 {
36 /*Enable access from E2 and below */
37 CCI500->secr_acc |= SECURE_ACCESS_UNSECURE_ENABLE;
38 }
39
40 static void enable_ns_access(void)
41 {
42 BIUCFG->bac.bac_permission |= 0x33; // Linux access to BAC_CPU_THERM_TEMP
43 }
44
45 static void disable_memc_sram(void)
46 {
47 uint32_t addr = MEMC_BASE + mc2_afx_sram_match_cfg_sram_start_addr_hi;
48
49 writel(readl(addr)&~0x80000000, addr);
50 }
51
52 static void setup_ubus_rangechk(void)
53 {
54 /* Size in MB. First 2GB is set up by default */
55 int size_left = tplparams->ddr_size - 2048;
56 int size, size_bit, i = 1;
57 #ifdef PHYS_SDRAM_2
58 uint64_t addr = PHYS_SDRAM_2;
59 #else
60 uint64_t addr = 0x100000000UL;
61 #endif
62
63 /* Fix the default of RC0 to only enable lower 2G memory for ubus master */
64 UBUS4_RANGE_CHK_SETUP->cfg[0].base = 0x13;
65
66 /* setup the second range check for the top DDR region */
67 while (size_left > 0 && i < 16) {
68 /* each range checker can support up to 4GB size */
69 if (size_left > 4096 )
70 size = 4096;
71 else
72 size = size_left;
73 size_left -= size;
74 size_bit = 0;
75 size = (size << 8); /* MB to # of 4KB */
76 while (size) {
77 size = (size >> 1);
78 if (size)
79 size_bit++;
80 }
81
82 UBUS4_RANGE_CHK_SETUP->cfg[i].control = 0x1f0;
83 UBUS4_RANGE_CHK_SETUP->cfg[i].srcpid[0] = 0xffffffff;
84 UBUS4_RANGE_CHK_SETUP->cfg[i].seclev = 0xffffffff;
85 UBUS4_RANGE_CHK_SETUP->cfg[i].base = (addr&0xffffffe0) | size_bit;
86 UBUS4_RANGE_CHK_SETUP->cfg[i].base_up = addr >> 32;
87
88 addr += 4096UL << size_bit;
89 i++;
90 }
91 }
92
93 #endif
94
95 #if !defined(CONFIG_SPL_BUILD)
96 void print_chipinfo(void)
97 {
98 unsigned int chipId = (PERF->RevID & CHIP_ID_MASK) >> CHIP_ID_SHIFT;
99 unsigned int revId = PERF->RevID & REV_ID_MASK;
100 printf("Chip ID: BCM%X_%X\n",chipId,revId);
101 }
102 #endif
103
104 #if defined(CONFIG_BCMBCA_PMC)
105 void boost_cpu_clock(void)
106 {
107 printf("set cpu freq to 2000MHz\n");
108 set_cpu_freq(2000);
109 pll_ch_freq_set(PMB_ADDR_BIU_PLL, 1, 4000/800); // raise ACEBIU clock rate to 800 MHz
110 }
111
112 int set_cpu_freq(int freqMHz)
113 {
114 int mdiv;
115
116 if( freqMHz > 2000 || freqMHz < 400 )
117 {
118 printf("%dMHz is not supported\n", freqMHz);
119 return -1;
120 }
121
122 /* VCO at 4GHz, mdiv = Fvco/target frequency */
123 mdiv = 4000/freqMHz;
124
125 pll_ch_freq_set(PMB_ADDR_BIU_PLL, 0, mdiv);
126
127 return 4000/mdiv;
128 }
129 #endif
130
131 static int reset_plls(void)
132 {
133 /* Software workaround for non-resetting eMMC PLL */
134 pll_ch_reset(PMB_ADDR_BIU_PLL, 5, PLLBPCMRegOffset(ch45_cfg));
135 return 0;
136 }
137
138 int arch_cpu_init(void)
139 {
140 #if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
141 enable_ts0_couner();
142 #if defined(CONFIG_BCMBCA_DDRC)
143 spl_ddrinit_prepare();
144 #endif
145 enable_upper_memory_access();
146 /* enable unalgined access */
147 set_sctlr(get_sctlr() & ~CR_A);
148 #endif
149
150 #if defined(CONFIG_TPL_BUILD)
151 enable_ns_access();
152 disable_memc_sram();
153 setup_ubus_rangechk();
154 cci500_enable();
155 #endif
156
157 reset_plls();
158 return 0;
159 }
160
161 int bcmbca_get_boot_device(void)
162 {
163 if ((MISC->miscStrapBus&MISC_STRAP_BUS_BOOT_SEL_NAND_MASK) == MISC_STRAP_BUS_BOOT_NAND)
164 return BOOT_DEVICE_NAND;
165
166 if ((MISC->miscStrapBus&MISC_STRAP_BUS_BOOT_SEL_MASK) == MISC_STRAP_BUS_BOOT_SPI_NAND)
167 return BOOT_DEVICE_SPI;
168
169 if ((MISC->miscStrapBus&MISC_STRAP_BUS_BOOT_SEL_MASK) == MISC_STRAP_BUS_BOOT_EMMC)
170 return BOOT_DEVICE_MMC1;
171
172 printf("Error: boot_sel straps are not set correctly\n");
173
174 return BOOT_DEVICE_NONE;
175 }
176
177 #if !defined(CONFIG_TPL_ATF)
178 void boot_secondary_cpu(unsigned long vector)
179 {
180 uint32_t cpu, nr_cpus = 4;
181 ARM_CONTROL_REG ctrl_reg;
182 uint64_t rvbar = vector;
183
184 printf("boot secondary cpu from 0x%lx\n", vector);
185
186 cpu = 1;
187 while (cpu < nr_cpus) {
188 int stat;
189
190 BIUCFG->cluster[0].rvbar_addr[cpu] = rvbar;
191 stat = PowerOnDevice(PMB_ADDR_ORION_CPU0 + cpu);
192 if (stat != kPMC_NO_ERROR)
193 printf("failed to power on secondary cpu %d - sts %d\n", cpu, stat);
194
195 stat = ReadBPCMRegister(PMB_ADDR_BIU_BPCM, ARMBPCMRegOffset(arm_control), &ctrl_reg.Reg32);
196 ctrl_reg.Bits.cpu_reset_n &= ~(0x1 << cpu);
197 stat |= WriteBPCMRegister(PMB_ADDR_BIU_BPCM, ARMBPCMRegOffset(arm_control), ctrl_reg.Reg32);
198 if (stat != kPMC_NO_ERROR)
199 printf("failed to boot secondary cpu %d - sts %d\n", cpu, stat);
200 cpu++;
201 }
202
203 return;
204 }
205 #endif