1 /* SPDX-License-Identifier: GPL-2.0+ */
3 * Copyright 2019 Broadcom Ltd.
7 #include <asm/arch/cpu.h>
8 #include <asm/arch/ddr.h>
9 #include <asm/arch/ubus4.h>
12 #if defined(CONFIG_BCMBCA_PMC)
14 #include "asm/arch/BPCM.h"
18 int arch_cpu_init(void)
20 #if defined(CONFIG_SPL_BUILD) && !defined(CONFIG_TPL_BUILD)
21 u32 frq
= COUNTER_FREQUENCY
;
23 // set arch timer frequency
24 asm volatile("mcr p15, 0, %0, c14, c0, 0" : : "r" (frq
));
26 // enable system timer
27 BIUCFG
->TSO_CNTCR
|= 1;
29 /* enable unalgined access */
30 set_cr(get_cr() & ~CR_A
);
36 void boost_cpu_clock(void)
40 PLL_CTRL_REG ctrl_reg
;
42 chipid
= (((PERF
->RevID
& CHIP_ID_MASK
) >> (CHIP_ID_SHIFT
-CHIP_ID_LC_SIZE
)) | (TOP
->OtpChipidLC
&& CHIP_ID_LC_MASK
));
43 if ((chipid
==0x68552c) || (chipid
==0x682520) || (chipid
==0x685500))
45 stat
= ReadBPCMRegister(PMB_ADDR_BIU_PLL
, PLLBPCMRegOffset(resets
), &ctrl_reg
.Reg32
);
46 ctrl_reg
.Bits
.byp_wait
= 1;
47 stat
|= WriteBPCMRegister(PMB_ADDR_BIU_PLL
, PLLBPCMRegOffset(resets
), ctrl_reg
.Reg32
);
49 stat
|= pll_vco_config(PMB_ADDR_BIU_PLL
,60, 1);
50 stat
|= pll_ch_freq_set(PMB_ADDR_BIU_PLL
, 0, 2);
52 stat
= ReadBPCMRegister(PMB_ADDR_BIU_PLL
, PLLBPCMRegOffset(resets
), &ctrl_reg
.Reg32
);
53 ctrl_reg
.Bits
.byp_wait
= 0;
54 stat
|= WriteBPCMRegister(PMB_ADDR_BIU_PLL
, PLLBPCMRegOffset(resets
), ctrl_reg
.Reg32
);
56 else if (chipid
==685520)
57 stat
= pll_ch_freq_set(PMB_ADDR_BIU_PLL
, 0, 2);
60 printf("Error: failed to set cpu clock\n");
62 UBUS4CLK
->ClockCtrl
= UBUS4_CLK_BYPASS_MASK
;
65 #if !defined(CONFIG_SPL_BUILD)
66 void print_chipinfo(void)
68 unsigned int cpu_speed
, rdp_speed
, nr_cores
;
69 unsigned int chipId
= (PERF
->RevID
& CHIP_ID_MASK
) >> CHIP_ID_SHIFT
;
70 unsigned int revId
= PERF
->RevID
& REV_ID_MASK
;
72 unsigned int chipIdLC
= (TOP
->OtpChipidLC
&& CHIP_ID_LC_MASK
);
74 chipId
= (chipId
<< CHIP_ID_LC_SIZE
) | chipIdLC
;
76 printf("Chip ID: BCM%X_%X\n",chipId
,revId
);
78 pll_ch_freq_get(PMB_ADDR_BIU_PLL
, 0, &cpu_speed
);
79 if (bcm_otp_get_nr_cpus(&nr_cores
))
80 printf("Error: failed to read cores from OTP\n");
84 printf("ARM Cortex A7 Dual Core: %dMHz", cpu_speed
);
86 printf("ARM Cortex A7 Triple Core: %dMHz", cpu_speed
);
89 get_rdp_freq(& rdp_speed
);
90 printf("RDP Freq: %dMHz\n", rdp_speed
);
94 int bcmbca_get_boot_device(void)
96 if ((MISC
->miscStrapBus
&MISC_STRAP_BUS_BOOT_SEL_NAND_MASK
) == MISC_STRAP_BUS_BOOT_NAND
)
97 return BOOT_DEVICE_NAND
;
99 if ((MISC
->miscStrapBus
&MISC_STRAP_BUS_BOOT_SEL_MASK
) == MISC_STRAP_BUS_BOOT_SPI_NAND
)
100 return BOOT_DEVICE_SPI
;
102 printf("Error: boot_sel straps are not set correctly\n");
104 return BOOT_DEVICE_NONE
;
107 #if !defined(CONFIG_TPL_ATF)
108 void boot_secondary_cpu(unsigned long vector
)
112 ARM_CONTROL_REG ctrl_reg
;
113 uint64_t rvbar
= vector
;
116 printf("boot secondary cpu from 0x%lx\n", vector
);
118 *(volatile uint32_t*)(BOOTLUT_BASE
+0x20) = vector
;
120 if ( bcm_otp_get_nr_cpus(&nr_cpus
) )
123 nr_cpus
= MAX_NUM_OF_CPU
-nr_cpus
;
125 while (cpu
< nr_cpus
)
127 BIUCFG
->cluster
[0].rvbar_addr
[cpu
] = rvbar
;
129 stat
= PowerOnDevice(PMB_ADDR_ORION_CPU0
+ cpu
);
130 if (stat
!= kPMC_NO_ERROR
)
131 printf("failed to power on secondary cpu %d - sts %d\n", cpu
, stat
);
133 stat
= ReadBPCMRegister(PMB_ADDR_BIU_BPCM
, ARMBPCMRegOffset(arm_control
), &ctrl_reg
.Reg32
);
134 ctrl_reg
.Bits
.cpu_reset_n
&= ~(0x1 << cpu
);
135 stat
|= WriteBPCMRegister(PMB_ADDR_BIU_BPCM
, ARMBPCMRegOffset(arm_control
), ctrl_reg
.Reg32
);
136 if (stat
!= kPMC_NO_ERROR
)
137 printf("failed to boot secondary cpu %d - sts %d\n", cpu
, stat
);