xref: /arm-trusted-firmware/plat/brcm/board/stingray/src/bl2_setup.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2016-2020, Broadcom
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  */
6*91f16700Schasinglulu 
7*91f16700Schasinglulu #include <arch_helpers.h>
8*91f16700Schasinglulu #include <common/bl_common.h>
9*91f16700Schasinglulu #include <common/debug.h>
10*91f16700Schasinglulu #include <drivers/arm/sp805.h>
11*91f16700Schasinglulu #include <drivers/delay_timer.h>
12*91f16700Schasinglulu #include <lib/mmio.h>
13*91f16700Schasinglulu 
14*91f16700Schasinglulu #include <chimp.h>
15*91f16700Schasinglulu #include <chip_id.h>
16*91f16700Schasinglulu #include <cmn_plat_util.h>
17*91f16700Schasinglulu #include <dmu.h>
18*91f16700Schasinglulu #include <emmc_api.h>
19*91f16700Schasinglulu #include <fru.h>
20*91f16700Schasinglulu #ifdef USE_GPIO
21*91f16700Schasinglulu #include <drivers/gpio.h>
22*91f16700Schasinglulu #include <iproc_gpio.h>
23*91f16700Schasinglulu #endif
24*91f16700Schasinglulu #include <platform_def.h>
25*91f16700Schasinglulu #include <sotp.h>
26*91f16700Schasinglulu #include <swreg.h>
27*91f16700Schasinglulu #include <sr_utils.h>
28*91f16700Schasinglulu #ifdef USE_DDR
29*91f16700Schasinglulu #include <ddr_init.h>
30*91f16700Schasinglulu #else
31*91f16700Schasinglulu #include <ext_sram_init.h>
32*91f16700Schasinglulu #endif
33*91f16700Schasinglulu #if DRIVER_OCOTP_ENABLE
34*91f16700Schasinglulu #include <ocotp.h>
35*91f16700Schasinglulu #endif
36*91f16700Schasinglulu #include "board_info.h"
37*91f16700Schasinglulu 
38*91f16700Schasinglulu #define WORD_SIZE              8
39*91f16700Schasinglulu #define SWREG_AVS_OTP_OFFSET   (13 * WORD_SIZE) /* 13th row byte offset */
40*91f16700Schasinglulu #define AON_GPIO_OTP_OFFSET    (28 * WORD_SIZE) /* 28th row byte offset */
41*91f16700Schasinglulu #define BYTES_TO_READ          8
42*91f16700Schasinglulu 
43*91f16700Schasinglulu /* OTP voltage step definitions */
44*91f16700Schasinglulu #define MVOLT_STEP_MAX         0x18  /* 1v */
45*91f16700Schasinglulu #define MVOLT_PER_STEP         10    /* 0.01mv per step */
46*91f16700Schasinglulu #define MVOLT_BASE             760   /* 0.76v */
47*91f16700Schasinglulu 
48*91f16700Schasinglulu #define STEP_TO_UVOLTS(step) \
49*91f16700Schasinglulu 	((MVOLT_BASE + (MVOLT_PER_STEP * (step))) * 1000)
50*91f16700Schasinglulu 
51*91f16700Schasinglulu #define GET_BITS(first, last, data) \
52*91f16700Schasinglulu 	((data >> first) & ((1 << (last - first + 1)) - 1))
53*91f16700Schasinglulu 
54*91f16700Schasinglulu /*
55*91f16700Schasinglulu  * SW-REG OTP encoding:
56*91f16700Schasinglulu  *
57*91f16700Schasinglulu  * SWREG_bits[11:0]  = OTP 13th row 12 bits[55:44]
58*91f16700Schasinglulu  * SWREG_bits[11:10] - Valid Bits (0x2 - valid, if not 0x2 - Invalid)
59*91f16700Schasinglulu  * SWREG_bits[9:5]   - iHost03, iHost12
60*91f16700Schasinglulu  * SWREG_bits[4:0]   - Core VDDC
61*91f16700Schasinglulu  */
62*91f16700Schasinglulu #define SWREG_OTP_BITS_START        12    /* 44th bit in MSB 32-bits */
63*91f16700Schasinglulu #define SWREG_OTP_BITS_END          23    /* 55th bit in MSB 32-bits */
64*91f16700Schasinglulu #define SWREG_VDDC_FIELD_START      0
65*91f16700Schasinglulu #define SWREG_VDDC_FIELD_END        4
66*91f16700Schasinglulu #define SWREG_IHOST_FIELD_START     5
67*91f16700Schasinglulu #define SWREG_IHOST_FIELD_END       9
68*91f16700Schasinglulu #define SWREG_VALID_BIT_START       10
69*91f16700Schasinglulu #define SWREG_VALID_BIT_END         11
70*91f16700Schasinglulu #define SWREG_VALID_BITS            0x2
71*91f16700Schasinglulu 
72*91f16700Schasinglulu /*
73*91f16700Schasinglulu  * Row 13 bit 56 is programmed as '1' today. It is not being used, so plan
74*91f16700Schasinglulu  * is to flip this bit to '0' for B1 rev. Hence SW can leverage this bit
75*91f16700Schasinglulu  * to identify Bx chip to program different sw-regulators.
76*91f16700Schasinglulu  */
77*91f16700Schasinglulu #define SPARE_BIT             24
78*91f16700Schasinglulu 
79*91f16700Schasinglulu #define IS_SR_B0(data)        (((data) >> SPARE_BIT) & 0x1)
80*91f16700Schasinglulu 
81*91f16700Schasinglulu #if DRIVER_OCOTP_ENABLE
82*91f16700Schasinglulu static struct otpc_map otp_stingray_map = {
83*91f16700Schasinglulu 	.otpc_row_size = 2,
84*91f16700Schasinglulu 	.data_r_offset = {0x10, 0x5c},
85*91f16700Schasinglulu 	.data_w_offset = {0x2c, 0x64},
86*91f16700Schasinglulu 	.word_size = 8,
87*91f16700Schasinglulu 	.stride = 8,
88*91f16700Schasinglulu };
89*91f16700Schasinglulu #endif
90*91f16700Schasinglulu 
91*91f16700Schasinglulu void plat_bcm_bl2_early_platform_setup(void)
92*91f16700Schasinglulu {
93*91f16700Schasinglulu 	/* Select UART0 for AP via mux setting*/
94*91f16700Schasinglulu 	if (PLAT_BRCM_BOOT_UART_BASE == UART0_BASE_ADDR) {
95*91f16700Schasinglulu 		mmio_write_32(UART0_SIN_MODE_SEL_CONTROL, 1);
96*91f16700Schasinglulu 		mmio_write_32(UART0_SOUT_MODE_SEL_CONTROL, 1);
97*91f16700Schasinglulu 	}
98*91f16700Schasinglulu }
99*91f16700Schasinglulu 
100*91f16700Schasinglulu #ifdef USE_NAND
101*91f16700Schasinglulu static void brcm_stingray_nand_init(void)
102*91f16700Schasinglulu {
103*91f16700Schasinglulu 	unsigned int val;
104*91f16700Schasinglulu 	unsigned int nand_idm_reset_control = 0x68e0a800;
105*91f16700Schasinglulu 
106*91f16700Schasinglulu 	VERBOSE(" stingray nand init start.\n");
107*91f16700Schasinglulu 
108*91f16700Schasinglulu 	/* Reset NAND */
109*91f16700Schasinglulu 	VERBOSE(" - reset nand\n");
110*91f16700Schasinglulu 	val = mmio_read_32((uintptr_t)(nand_idm_reset_control + 0x0));
111*91f16700Schasinglulu 	mmio_write_32((uintptr_t)(nand_idm_reset_control + 0x0), val | 0x1);
112*91f16700Schasinglulu 	udelay(500);
113*91f16700Schasinglulu 	val = mmio_read_32((uintptr_t)(nand_idm_reset_control + 0x0));
114*91f16700Schasinglulu 	mmio_write_32((uintptr_t)(nand_idm_reset_control + 0x0), val & ~0x1);
115*91f16700Schasinglulu 	udelay(500);
116*91f16700Schasinglulu 
117*91f16700Schasinglulu 	VERBOSE(" stingray nand init done.\n");
118*91f16700Schasinglulu }
119*91f16700Schasinglulu #endif
120*91f16700Schasinglulu 
121*91f16700Schasinglulu #if defined(USE_PAXB) || defined(USE_PAXC) || defined(USE_SATA)
122*91f16700Schasinglulu #define PCIE_RESCAL_CFG_0 0x40000130
123*91f16700Schasinglulu #define PCIE_CFG_RESCAL_RSTB_R (1 << 16)
124*91f16700Schasinglulu #define PCIE_CFG_RESCAL_PWRDNB_R (1 << 8)
125*91f16700Schasinglulu #define PCIE_RESCAL_STATUS_0 0x4000014c
126*91f16700Schasinglulu #define PCIE_STAT_PON_VALID_R (1 << 0)
127*91f16700Schasinglulu #define PCIE_RESCAL_OUTPUT_STATUS 0x40000154
128*91f16700Schasinglulu #define CDRU_PCIE_RESET_N_R (1 << CDRU_MISC_RESET_CONTROL__CDRU_PCIE_RESET_N_R)
129*91f16700Schasinglulu 
130*91f16700Schasinglulu #ifdef EMULATION_SETUP
131*91f16700Schasinglulu static void brcm_stingray_pcie_reset(void)
132*91f16700Schasinglulu {
133*91f16700Schasinglulu }
134*91f16700Schasinglulu #else
135*91f16700Schasinglulu static void brcm_stingray_pcie_reset(void)
136*91f16700Schasinglulu {
137*91f16700Schasinglulu 	unsigned int data;
138*91f16700Schasinglulu 	int try;
139*91f16700Schasinglulu 
140*91f16700Schasinglulu 	if (bcm_chimp_is_nic_mode()) {
141*91f16700Schasinglulu 		INFO("NIC mode detected; PCIe reset/rescal not executed\n");
142*91f16700Schasinglulu 		return;
143*91f16700Schasinglulu 	}
144*91f16700Schasinglulu 
145*91f16700Schasinglulu 	mmio_clrbits_32(CDRU_MISC_RESET_CONTROL, CDRU_PCIE_RESET_N_R);
146*91f16700Schasinglulu 	mmio_setbits_32(CDRU_MISC_RESET_CONTROL, CDRU_PCIE_RESET_N_R);
147*91f16700Schasinglulu 	/* Release reset */
148*91f16700Schasinglulu 	mmio_setbits_32(PCIE_RESCAL_CFG_0, PCIE_CFG_RESCAL_RSTB_R);
149*91f16700Schasinglulu 	mdelay(1);
150*91f16700Schasinglulu 	/* Power UP */
151*91f16700Schasinglulu 	mmio_setbits_32(PCIE_RESCAL_CFG_0,
152*91f16700Schasinglulu 			(PCIE_CFG_RESCAL_RSTB_R | PCIE_CFG_RESCAL_PWRDNB_R));
153*91f16700Schasinglulu 
154*91f16700Schasinglulu 	try = 1000;
155*91f16700Schasinglulu 	do {
156*91f16700Schasinglulu 		udelay(1);
157*91f16700Schasinglulu 		data = mmio_read_32(PCIE_RESCAL_STATUS_0);
158*91f16700Schasinglulu 		try--;
159*91f16700Schasinglulu 	} while ((data & PCIE_STAT_PON_VALID_R) == 0x0 && (try > 0));
160*91f16700Schasinglulu 
161*91f16700Schasinglulu 	if (try <= 0)
162*91f16700Schasinglulu 		ERROR("PCIE_RESCAL_STATUS_0: 0x%x\n", data);
163*91f16700Schasinglulu 
164*91f16700Schasinglulu 	VERBOSE("PCIE_SATA_RESCAL_STATUS_0 0x%x.\n",
165*91f16700Schasinglulu 			mmio_read_32(PCIE_RESCAL_STATUS_0));
166*91f16700Schasinglulu 	VERBOSE("PCIE_SATA_RESCAL_OUTPUT_STATUS 0x%x.\n",
167*91f16700Schasinglulu 			mmio_read_32(PCIE_RESCAL_OUTPUT_STATUS));
168*91f16700Schasinglulu 	INFO("PCIE SATA Rescal Init done\n");
169*91f16700Schasinglulu }
170*91f16700Schasinglulu #endif /* EMULATION_SETUP */
171*91f16700Schasinglulu #endif /* USE_PAXB || USE_PAXC || USE_SATA */
172*91f16700Schasinglulu 
173*91f16700Schasinglulu #ifdef USE_PAXC
174*91f16700Schasinglulu void brcm_stingray_chimp_check_and_fastboot(void)
175*91f16700Schasinglulu {
176*91f16700Schasinglulu 	int fastboot_init_result;
177*91f16700Schasinglulu 
178*91f16700Schasinglulu 	if (bcm_chimp_is_nic_mode())
179*91f16700Schasinglulu 		/* Do not wait here */
180*91f16700Schasinglulu 		return;
181*91f16700Schasinglulu 
182*91f16700Schasinglulu #if WARMBOOT_DDR_S3_SUPPORT
183*91f16700Schasinglulu 	/*
184*91f16700Schasinglulu 	 * Currently DDR shmoo parameters and QSPI boot source are
185*91f16700Schasinglulu 	 * tied. DDR shmoo parameters are stored in QSPI, which is
186*91f16700Schasinglulu 	 * used for warmboot.
187*91f16700Schasinglulu 	 * Do not reset nitro for warmboot
188*91f16700Schasinglulu 	 */
189*91f16700Schasinglulu 	if (is_warmboot() && (boot_source_get() == BOOT_SOURCE_QSPI))
190*91f16700Schasinglulu 		return;
191*91f16700Schasinglulu #endif /* WARMBOOT_DDR_S3_SUPPORT */
192*91f16700Schasinglulu 
193*91f16700Schasinglulu 	/*
194*91f16700Schasinglulu 	 * Not in NIC mode,
195*91f16700Schasinglulu 	 * initiate fastboot (if enabled)
196*91f16700Schasinglulu 	 */
197*91f16700Schasinglulu 	if (FASTBOOT_TYPE == CHIMP_FASTBOOT_NITRO_RESET) {
198*91f16700Schasinglulu 
199*91f16700Schasinglulu 		VERBOSE("Bring up Nitro/ChiMP\n");
200*91f16700Schasinglulu 
201*91f16700Schasinglulu 		if (boot_source_get() == BOOT_SOURCE_QSPI)
202*91f16700Schasinglulu 			WARN("Nitro boots from QSPI when AP has booted from QSPI.\n");
203*91f16700Schasinglulu 		brcm_stingray_set_qspi_mux(0);
204*91f16700Schasinglulu 		VERBOSE("Nitro controls the QSPI\n");
205*91f16700Schasinglulu 	}
206*91f16700Schasinglulu 
207*91f16700Schasinglulu 	fastboot_init_result = bcm_chimp_initiate_fastboot(FASTBOOT_TYPE);
208*91f16700Schasinglulu 	if (fastboot_init_result && boot_source_get() != BOOT_SOURCE_QSPI)
209*91f16700Schasinglulu 		ERROR("Nitro init error %d. Status: 0x%x; bpe_mod reg: 0x%x\n"
210*91f16700Schasinglulu 			"fastboot register: 0x%x; handshake register 0x%x\n",
211*91f16700Schasinglulu 			fastboot_init_result,
212*91f16700Schasinglulu 			bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_STAT_REG),
213*91f16700Schasinglulu 			bcm_chimp_read_ctrl(CHIMP_REG_CTRL_BPE_MODE_REG),
214*91f16700Schasinglulu 			bcm_chimp_read_ctrl(CHIMP_REG_CTRL_FSTBOOT_PTR_REG),
215*91f16700Schasinglulu 			bcm_chimp_read(CHIMP_REG_ECO_RESERVED));
216*91f16700Schasinglulu 
217*91f16700Schasinglulu 	/*
218*91f16700Schasinglulu 	 * CRMU watchdog kicks is an example, which is L1 reset,
219*91f16700Schasinglulu 	 * does not clear Nitro scratch pad ram.
220*91f16700Schasinglulu 	 * For Nitro resets: Clear the Nitro health status memory.
221*91f16700Schasinglulu 	 */
222*91f16700Schasinglulu 	bcm_chimp_write((CHIMP_REG_CHIMP_SCPAD + CHIMP_HEALTH_STATUS_OFFSET),
223*91f16700Schasinglulu 			0);
224*91f16700Schasinglulu }
225*91f16700Schasinglulu #endif
226*91f16700Schasinglulu 
227*91f16700Schasinglulu void set_ihost_vddc_swreg(uint32_t ihost_uvolts, uint32_t vddc_uvolts)
228*91f16700Schasinglulu {
229*91f16700Schasinglulu 	NOTICE("ihost_uvolts: %duv, vddc_uvolts: %duv\n",
230*91f16700Schasinglulu 	       ihost_uvolts, vddc_uvolts);
231*91f16700Schasinglulu 
232*91f16700Schasinglulu 	set_swreg(VDDC_CORE, vddc_uvolts);
233*91f16700Schasinglulu 	set_swreg(IHOST03, ihost_uvolts);
234*91f16700Schasinglulu 	set_swreg(IHOST12, ihost_uvolts);
235*91f16700Schasinglulu }
236*91f16700Schasinglulu 
237*91f16700Schasinglulu /*
238*91f16700Schasinglulu  * Reads SWREG AVS OTP bits (13th row) with ECC enabled and get voltage
239*91f16700Schasinglulu  * defined in OTP if valid OTP is found
240*91f16700Schasinglulu  */
241*91f16700Schasinglulu void read_avs_otp_bits(uint32_t *ihost_uvolts, uint32_t *vddc_uvolts)
242*91f16700Schasinglulu {
243*91f16700Schasinglulu 	uint32_t offset = SWREG_AVS_OTP_OFFSET;
244*91f16700Schasinglulu 	uint32_t ihost_step, vddc_step;
245*91f16700Schasinglulu 	uint32_t avs_bits;
246*91f16700Schasinglulu 	uint32_t buf[2];
247*91f16700Schasinglulu 
248*91f16700Schasinglulu 	if (bcm_otpc_read(offset, &buf[0], BYTES_TO_READ, 1) == -1)
249*91f16700Schasinglulu 		return;
250*91f16700Schasinglulu 
251*91f16700Schasinglulu 	VERBOSE("AVS OTP %d ROW: 0x%x.0x%x\n",
252*91f16700Schasinglulu 		offset/WORD_SIZE, buf[1], buf[0]);
253*91f16700Schasinglulu 
254*91f16700Schasinglulu 	/* get voltage readings from AVS OTP bits */
255*91f16700Schasinglulu 	avs_bits = GET_BITS(SWREG_OTP_BITS_START,
256*91f16700Schasinglulu 			    SWREG_OTP_BITS_END,
257*91f16700Schasinglulu 			    buf[1]);
258*91f16700Schasinglulu 
259*91f16700Schasinglulu 	/* check for valid otp bits */
260*91f16700Schasinglulu 	if (GET_BITS(SWREG_VALID_BIT_START, SWREG_VALID_BIT_END, avs_bits) !=
261*91f16700Schasinglulu 	    SWREG_VALID_BITS) {
262*91f16700Schasinglulu 		WARN("Invalid AVS OTP bits at %d row\n", offset/WORD_SIZE);
263*91f16700Schasinglulu 		return;
264*91f16700Schasinglulu 	}
265*91f16700Schasinglulu 
266*91f16700Schasinglulu 	/* get ihost and vddc step value */
267*91f16700Schasinglulu 	vddc_step = GET_BITS(SWREG_VDDC_FIELD_START,
268*91f16700Schasinglulu 			     SWREG_VDDC_FIELD_END,
269*91f16700Schasinglulu 			     avs_bits);
270*91f16700Schasinglulu 
271*91f16700Schasinglulu 	ihost_step = GET_BITS(SWREG_IHOST_FIELD_START,
272*91f16700Schasinglulu 			      SWREG_IHOST_FIELD_END,
273*91f16700Schasinglulu 			      avs_bits);
274*91f16700Schasinglulu 
275*91f16700Schasinglulu 	if ((ihost_step > MVOLT_STEP_MAX) || (vddc_step > MVOLT_STEP_MAX)) {
276*91f16700Schasinglulu 		WARN("OTP entry invalid\n");
277*91f16700Schasinglulu 		return;
278*91f16700Schasinglulu 	}
279*91f16700Schasinglulu 
280*91f16700Schasinglulu 	/* get voltage in micro-volts */
281*91f16700Schasinglulu 	*ihost_uvolts = STEP_TO_UVOLTS(ihost_step);
282*91f16700Schasinglulu 	*vddc_uvolts = STEP_TO_UVOLTS(vddc_step);
283*91f16700Schasinglulu }
284*91f16700Schasinglulu 
285*91f16700Schasinglulu /*
286*91f16700Schasinglulu  * This api reads otp bits and program internal swreg's - ihos12, ihost03,
287*91f16700Schasinglulu  * vddc_core and ddr_core based on different chip. External swreg's
288*91f16700Schasinglulu  * programming will be done from crmu.
289*91f16700Schasinglulu  *
290*91f16700Schasinglulu  * For A2 chip:
291*91f16700Schasinglulu  *   Read OTP row 20, bit 50. This bit will be set for A2 chip. Once A2 chip is
292*91f16700Schasinglulu  *   found, read AVS OTP row 13, 12bits[55:44], if valid otp bits are found
293*91f16700Schasinglulu  *   then set ihost and vddc according to avs otp bits else set them to 0.94v
294*91f16700Schasinglulu  *   and 0.91v respectively. Also update the firmware after setting voltage.
295*91f16700Schasinglulu  *
296*91f16700Schasinglulu  * For B0 chip:
297*91f16700Schasinglulu  *   Read OTP row 13, bit 56. This bit will be set for B0 chip. Once B0 chip is
298*91f16700Schasinglulu  *   found then set ihost and vddc to 0.95v and ddr_core to 1v. No AVS OTP bits
299*91f16700Schasinglulu  *   are used get ihost/vddc voltages.
300*91f16700Schasinglulu  *
301*91f16700Schasinglulu  * For B1 chip:
302*91f16700Schasinglulu  *   Read AVS OTP row 13, 12bits[55:44], if valid otp bits are found then set
303*91f16700Schasinglulu  *   ihost and vddc according to avs otp bits else set them to 0.94v and 0.91v
304*91f16700Schasinglulu  *   respectively.
305*91f16700Schasinglulu  */
306*91f16700Schasinglulu void set_swreg_based_on_otp(void)
307*91f16700Schasinglulu {
308*91f16700Schasinglulu 	/* default voltage if no valid OTP */
309*91f16700Schasinglulu 	uint32_t vddc_uvolts = VDDC_CORE_DEF_VOLT;
310*91f16700Schasinglulu 	uint32_t ihost_uvolts = IHOST_DEF_VOLT;
311*91f16700Schasinglulu 	uint32_t ddrc_uvolts;
312*91f16700Schasinglulu 	uint32_t offset;
313*91f16700Schasinglulu 	uint32_t buf[2];
314*91f16700Schasinglulu 
315*91f16700Schasinglulu 	offset = SWREG_AVS_OTP_OFFSET;
316*91f16700Schasinglulu 	if (bcm_otpc_read(offset, &buf[0], BYTES_TO_READ, 1) == -1)
317*91f16700Schasinglulu 		return;
318*91f16700Schasinglulu 
319*91f16700Schasinglulu 	VERBOSE("OTP %d ROW: 0x%x.0x%x\n",
320*91f16700Schasinglulu 		offset/WORD_SIZE, buf[1], buf[0]);
321*91f16700Schasinglulu 
322*91f16700Schasinglulu 	if (IS_SR_B0(buf[1])) {
323*91f16700Schasinglulu 		/* don't read AVS OTP for B0 */
324*91f16700Schasinglulu 		ihost_uvolts = B0_IHOST_DEF_VOLT;
325*91f16700Schasinglulu 		vddc_uvolts = B0_VDDC_CORE_DEF_VOLT;
326*91f16700Schasinglulu 		ddrc_uvolts = B0_DDR_VDDC_DEF_VOLT;
327*91f16700Schasinglulu 	} else {
328*91f16700Schasinglulu 		read_avs_otp_bits(&ihost_uvolts, &vddc_uvolts);
329*91f16700Schasinglulu 	}
330*91f16700Schasinglulu 
331*91f16700Schasinglulu #if (IHOST_REG_TYPE == IHOST_REG_INTEGRATED) && \
332*91f16700Schasinglulu 	(VDDC_REG_TYPE == VDDC_REG_INTEGRATED)
333*91f16700Schasinglulu 	/* enable IHOST12 cluster before changing voltage */
334*91f16700Schasinglulu 	NOTICE("Switching on the Regulator idx: %u\n",
335*91f16700Schasinglulu 	       SWREG_IHOST1_DIS);
336*91f16700Schasinglulu 	mmio_clrsetbits_32(CRMU_SWREG_CTRL_ADDR,
337*91f16700Schasinglulu 			   BIT(SWREG_IHOST1_DIS),
338*91f16700Schasinglulu 			   BIT(SWREG_IHOST1_REG_RESETB));
339*91f16700Schasinglulu 
340*91f16700Schasinglulu 	/* wait for regulator supply gets stable */
341*91f16700Schasinglulu 	while (!(mmio_read_32(CRMU_SWREG_STATUS_ADDR) &
342*91f16700Schasinglulu 	       (1 << SWREG_IHOST1_PMU_STABLE)))
343*91f16700Schasinglulu 		;
344*91f16700Schasinglulu 
345*91f16700Schasinglulu 	INFO("Regulator supply got stable\n");
346*91f16700Schasinglulu 
347*91f16700Schasinglulu #ifndef DEFAULT_SWREG_CONFIG
348*91f16700Schasinglulu 	swreg_firmware_update();
349*91f16700Schasinglulu #endif
350*91f16700Schasinglulu 
351*91f16700Schasinglulu 	set_ihost_vddc_swreg(ihost_uvolts, vddc_uvolts);
352*91f16700Schasinglulu #endif
353*91f16700Schasinglulu 	if (IS_SR_B0(buf[1])) {
354*91f16700Schasinglulu 		NOTICE("ddrc_uvolts: %duv\n", ddrc_uvolts);
355*91f16700Schasinglulu 		set_swreg(DDR_VDDC, ddrc_uvolts);
356*91f16700Schasinglulu 	}
357*91f16700Schasinglulu }
358*91f16700Schasinglulu 
359*91f16700Schasinglulu #ifdef USE_DDR
360*91f16700Schasinglulu static struct ddr_info ddr_info;
361*91f16700Schasinglulu #endif
362*91f16700Schasinglulu #ifdef USE_FRU
363*91f16700Schasinglulu static struct fru_area_info fru_area[FRU_MAX_NR_AREAS];
364*91f16700Schasinglulu static struct fru_board_info board_info;
365*91f16700Schasinglulu static struct fru_time fru_tm;
366*91f16700Schasinglulu static uint8_t fru_tbl[BCM_MAX_FRU_LEN];
367*91f16700Schasinglulu 
368*91f16700Schasinglulu static void board_detect_fru(void)
369*91f16700Schasinglulu {
370*91f16700Schasinglulu 	uint32_t i, result;
371*91f16700Schasinglulu 	int ret = -1;
372*91f16700Schasinglulu 
373*91f16700Schasinglulu 	result = bcm_emmc_init(false);
374*91f16700Schasinglulu 	if (!result) {
375*91f16700Schasinglulu 		ERROR("eMMC init failed\n");
376*91f16700Schasinglulu 		return;
377*91f16700Schasinglulu 	}
378*91f16700Schasinglulu 
379*91f16700Schasinglulu 	/* go through eMMC boot partitions looking for FRU table */
380*91f16700Schasinglulu 	for (i = EMMC_BOOT_PARTITION1; i <= EMMC_BOOT_PARTITION2; i++) {
381*91f16700Schasinglulu 		result = emmc_partition_select(i);
382*91f16700Schasinglulu 		if (!result) {
383*91f16700Schasinglulu 			ERROR("Switching to eMMC part %u failed\n", i);
384*91f16700Schasinglulu 			return;
385*91f16700Schasinglulu 		}
386*91f16700Schasinglulu 
387*91f16700Schasinglulu 		result = emmc_read(BCM_FRU_TBL_OFFSET, (uintptr_t)fru_tbl,
388*91f16700Schasinglulu 				   BCM_MAX_FRU_LEN, BCM_MAX_FRU_LEN);
389*91f16700Schasinglulu 		if (!result) {
390*91f16700Schasinglulu 			ERROR("Failed to read from eMMC part %u\n", i);
391*91f16700Schasinglulu 			return;
392*91f16700Schasinglulu 		}
393*91f16700Schasinglulu 
394*91f16700Schasinglulu 		/*
395*91f16700Schasinglulu 		 * Run sanity check and checksum to make sure valid FRU table
396*91f16700Schasinglulu 		 * is detected
397*91f16700Schasinglulu 		 */
398*91f16700Schasinglulu 		ret = fru_validate(fru_tbl, fru_area);
399*91f16700Schasinglulu 		if (ret < 0) {
400*91f16700Schasinglulu 			WARN("FRU table not found in eMMC part %u\n", i);
401*91f16700Schasinglulu 			continue;
402*91f16700Schasinglulu 		}
403*91f16700Schasinglulu 
404*91f16700Schasinglulu 		/* parse DDR information from FRU table */
405*91f16700Schasinglulu 		ret = fru_parse_ddr(fru_tbl, &fru_area[FRU_AREA_INTERNAL],
406*91f16700Schasinglulu 				    &ddr_info);
407*91f16700Schasinglulu 		if (ret < 0) {
408*91f16700Schasinglulu 			WARN("No FRU DDR info found in eMMC part %u\n", i);
409*91f16700Schasinglulu 			continue;
410*91f16700Schasinglulu 		}
411*91f16700Schasinglulu 
412*91f16700Schasinglulu 		/* parse board information from FRU table */
413*91f16700Schasinglulu 		ret = fru_parse_board(fru_tbl, &fru_area[FRU_AREA_BOARD_INFO],
414*91f16700Schasinglulu 				      &board_info);
415*91f16700Schasinglulu 		if (ret < 0) {
416*91f16700Schasinglulu 			WARN("No FRU board info found in eMMC part %u\n", i);
417*91f16700Schasinglulu 			continue;
418*91f16700Schasinglulu 		}
419*91f16700Schasinglulu 
420*91f16700Schasinglulu 		/* if we reach here, valid FRU table is parsed */
421*91f16700Schasinglulu 		break;
422*91f16700Schasinglulu 	}
423*91f16700Schasinglulu 
424*91f16700Schasinglulu 	if (ret < 0) {
425*91f16700Schasinglulu 		WARN("FRU table missing for this board\n");
426*91f16700Schasinglulu 		return;
427*91f16700Schasinglulu 	}
428*91f16700Schasinglulu 
429*91f16700Schasinglulu 	for (i = 0; i < BCM_MAX_NR_DDR; i++) {
430*91f16700Schasinglulu 		INFO("DDR channel index: %d\n", ddr_info.mcb[i].idx);
431*91f16700Schasinglulu 		INFO("DDR size %u GB\n", ddr_info.mcb[i].size_mb / 1024);
432*91f16700Schasinglulu 		INFO("DDR ref ID by SW (Not MCB Ref ID) 0x%x\n",
433*91f16700Schasinglulu 		     ddr_info.mcb[i].ref_id);
434*91f16700Schasinglulu 	}
435*91f16700Schasinglulu 
436*91f16700Schasinglulu 	fru_format_time(board_info.mfg_date, &fru_tm);
437*91f16700Schasinglulu 
438*91f16700Schasinglulu 	INFO("**** FRU board information ****\n");
439*91f16700Schasinglulu 	INFO("Language 0x%x\n", board_info.lang);
440*91f16700Schasinglulu 	INFO("Manufacturing Date %u.%02u.%02u, %02u:%02u\n",
441*91f16700Schasinglulu 	     fru_tm.year, fru_tm.month, fru_tm.day,
442*91f16700Schasinglulu 	     fru_tm.hour, fru_tm.min);
443*91f16700Schasinglulu 	INFO("Manufacturing Date(Raw) 0x%x\n", board_info.mfg_date);
444*91f16700Schasinglulu 	INFO("Manufacturer %s\n", board_info.manufacturer);
445*91f16700Schasinglulu 	INFO("Product Name %s\n", board_info.product_name);
446*91f16700Schasinglulu 	INFO("Serial number %s\n", board_info.serial_number);
447*91f16700Schasinglulu 	INFO("Part number %s\n", board_info.part_number);
448*91f16700Schasinglulu 	INFO("File ID %s\n", board_info.file_id);
449*91f16700Schasinglulu }
450*91f16700Schasinglulu #endif /* USE_FRU */
451*91f16700Schasinglulu 
452*91f16700Schasinglulu #ifdef USE_GPIO
453*91f16700Schasinglulu 
454*91f16700Schasinglulu #define INVALID_GPIO    0xffff
455*91f16700Schasinglulu 
456*91f16700Schasinglulu static const int gpio_cfg_bitmap[MAX_NR_GPIOS] = {
457*91f16700Schasinglulu #ifdef BRD_DETECT_GPIO_BIT0
458*91f16700Schasinglulu 	BRD_DETECT_GPIO_BIT0,
459*91f16700Schasinglulu #else
460*91f16700Schasinglulu 	INVALID_GPIO,
461*91f16700Schasinglulu #endif
462*91f16700Schasinglulu #ifdef BRD_DETECT_GPIO_BIT1
463*91f16700Schasinglulu 	BRD_DETECT_GPIO_BIT1,
464*91f16700Schasinglulu #else
465*91f16700Schasinglulu 	INVALID_GPIO,
466*91f16700Schasinglulu #endif
467*91f16700Schasinglulu #ifdef BRD_DETECT_GPIO_BIT2
468*91f16700Schasinglulu 	BRD_DETECT_GPIO_BIT2,
469*91f16700Schasinglulu #else
470*91f16700Schasinglulu 	INVALID_GPIO,
471*91f16700Schasinglulu #endif
472*91f16700Schasinglulu #ifdef BRD_DETECT_GPIO_BIT3
473*91f16700Schasinglulu 	BRD_DETECT_GPIO_BIT3,
474*91f16700Schasinglulu #else
475*91f16700Schasinglulu 	INVALID_GPIO,
476*91f16700Schasinglulu #endif
477*91f16700Schasinglulu };
478*91f16700Schasinglulu 
479*91f16700Schasinglulu static uint8_t gpio_bitmap;
480*91f16700Schasinglulu 
481*91f16700Schasinglulu /*
482*91f16700Schasinglulu  * Use an odd number to avoid potential conflict with public GPIO level
483*91f16700Schasinglulu  * defines
484*91f16700Schasinglulu  */
485*91f16700Schasinglulu #define GPIO_STATE_FLOAT         15
486*91f16700Schasinglulu 
487*91f16700Schasinglulu /*
488*91f16700Schasinglulu  * If GPIO_SUPPORT_FLOAT_DETECTION is disabled, simply return GPIO level
489*91f16700Schasinglulu  *
490*91f16700Schasinglulu  * If GPIO_SUPPORT_FLOAT_DETECTION is enabled, add additional test for possible
491*91f16700Schasinglulu  * pin floating (unconnected) scenario. This support is assuming externally
492*91f16700Schasinglulu  * applied pull up / pull down will have a stronger pull than the internal pull
493*91f16700Schasinglulu  * up / pull down.
494*91f16700Schasinglulu  */
495*91f16700Schasinglulu static uint8_t gpio_get_state(int gpio)
496*91f16700Schasinglulu {
497*91f16700Schasinglulu 	uint8_t val;
498*91f16700Schasinglulu 
499*91f16700Schasinglulu 	/* set direction to GPIO input */
500*91f16700Schasinglulu 	gpio_set_direction(gpio, GPIO_DIR_IN);
501*91f16700Schasinglulu 
502*91f16700Schasinglulu #ifndef GPIO_SUPPORT_FLOAT_DETECTION
503*91f16700Schasinglulu 	if (gpio_get_value(gpio) == GPIO_LEVEL_HIGH)
504*91f16700Schasinglulu 		val = GPIO_LEVEL_HIGH;
505*91f16700Schasinglulu 	else
506*91f16700Schasinglulu 		val = GPIO_LEVEL_LOW;
507*91f16700Schasinglulu 
508*91f16700Schasinglulu 	return val;
509*91f16700Schasinglulu #else
510*91f16700Schasinglulu 	/*
511*91f16700Schasinglulu 	 * Enable internal pull down. If GPIO level is still high, there must
512*91f16700Schasinglulu 	 * be an external pull up
513*91f16700Schasinglulu 	 */
514*91f16700Schasinglulu 	gpio_set_pull(gpio, GPIO_PULL_DOWN);
515*91f16700Schasinglulu 	if (gpio_get_value(gpio) == GPIO_LEVEL_HIGH) {
516*91f16700Schasinglulu 		val = GPIO_LEVEL_HIGH;
517*91f16700Schasinglulu 		goto exit;
518*91f16700Schasinglulu 	}
519*91f16700Schasinglulu 
520*91f16700Schasinglulu 	/*
521*91f16700Schasinglulu 	 * Enable internal pull up. If GPIO level is still low, there must
522*91f16700Schasinglulu 	 * be an external pull down
523*91f16700Schasinglulu 	 */
524*91f16700Schasinglulu 	gpio_set_pull(gpio, GPIO_PULL_UP);
525*91f16700Schasinglulu 	if (gpio_get_value(gpio) == GPIO_LEVEL_LOW) {
526*91f16700Schasinglulu 		val = GPIO_LEVEL_LOW;
527*91f16700Schasinglulu 		goto exit;
528*91f16700Schasinglulu 	}
529*91f16700Schasinglulu 
530*91f16700Schasinglulu 	/* if reached here, the pin must be not connected */
531*91f16700Schasinglulu 	val = GPIO_STATE_FLOAT;
532*91f16700Schasinglulu 
533*91f16700Schasinglulu exit:
534*91f16700Schasinglulu 	/* make sure internall pull is disabled */
535*91f16700Schasinglulu 	if (gpio_get_pull(gpio) != GPIO_PULL_NONE)
536*91f16700Schasinglulu 		gpio_set_pull(gpio, GPIO_PULL_NONE);
537*91f16700Schasinglulu 
538*91f16700Schasinglulu 	return val;
539*91f16700Schasinglulu #endif
540*91f16700Schasinglulu }
541*91f16700Schasinglulu 
542*91f16700Schasinglulu static void board_detect_gpio(void)
543*91f16700Schasinglulu {
544*91f16700Schasinglulu 	unsigned int i, val;
545*91f16700Schasinglulu 	int gpio;
546*91f16700Schasinglulu 
547*91f16700Schasinglulu 	iproc_gpio_init(IPROC_GPIO_S_BASE, IPROC_GPIO_NR,
548*91f16700Schasinglulu 			IPROC_IOPAD_MODE_BASE, HSLS_IOPAD_BASE);
549*91f16700Schasinglulu 
550*91f16700Schasinglulu 	gpio_bitmap = 0;
551*91f16700Schasinglulu 	for (i = 0; i < MAX_NR_GPIOS; i++) {
552*91f16700Schasinglulu 		if (gpio_cfg_bitmap[i] == INVALID_GPIO)
553*91f16700Schasinglulu 			continue;
554*91f16700Schasinglulu 
555*91f16700Schasinglulu 		/*
556*91f16700Schasinglulu 		 * Construct the bitmap based on GPIO value. Floating pin
557*91f16700Schasinglulu 		 * detection is a special case. As soon as a floating pin is
558*91f16700Schasinglulu 		 * detected, a special value of MAX_GPIO_BITMAP_VAL is
559*91f16700Schasinglulu 		 * assigned and we break out of the loop immediately
560*91f16700Schasinglulu 		 */
561*91f16700Schasinglulu 		gpio = gpio_cfg_bitmap[i];
562*91f16700Schasinglulu 		val = gpio_get_state(gpio);
563*91f16700Schasinglulu 		if (val == GPIO_STATE_FLOAT) {
564*91f16700Schasinglulu 			gpio_bitmap = MAX_GPIO_BITMAP_VAL;
565*91f16700Schasinglulu 			break;
566*91f16700Schasinglulu 		}
567*91f16700Schasinglulu 
568*91f16700Schasinglulu 		if (val == GPIO_LEVEL_HIGH)
569*91f16700Schasinglulu 			gpio_bitmap |= BIT(i);
570*91f16700Schasinglulu 	}
571*91f16700Schasinglulu 
572*91f16700Schasinglulu 	memcpy(&ddr_info, &gpio_ddr_info[gpio_bitmap], sizeof(ddr_info));
573*91f16700Schasinglulu 	INFO("Board detection GPIO bitmap = 0x%x\n", gpio_bitmap);
574*91f16700Schasinglulu }
575*91f16700Schasinglulu #endif /* USE_GPIO */
576*91f16700Schasinglulu 
577*91f16700Schasinglulu static void bcm_board_detect(void)
578*91f16700Schasinglulu {
579*91f16700Schasinglulu #ifdef DDR_LEGACY_MCB_SUPPORTED
580*91f16700Schasinglulu 	/* Loading default DDR info */
581*91f16700Schasinglulu 	memcpy(&ddr_info, &default_ddr_info, sizeof(ddr_info));
582*91f16700Schasinglulu #endif
583*91f16700Schasinglulu #ifdef USE_FRU
584*91f16700Schasinglulu 	board_detect_fru();
585*91f16700Schasinglulu #endif
586*91f16700Schasinglulu #ifdef USE_GPIO
587*91f16700Schasinglulu 	board_detect_gpio();
588*91f16700Schasinglulu #endif
589*91f16700Schasinglulu }
590*91f16700Schasinglulu 
591*91f16700Schasinglulu static void dump_persistent_regs(void)
592*91f16700Schasinglulu {
593*91f16700Schasinglulu 	NOTICE("pr0: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG0));
594*91f16700Schasinglulu 	NOTICE("pr1: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG1));
595*91f16700Schasinglulu 	NOTICE("pr2: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG2));
596*91f16700Schasinglulu 	NOTICE("pr3: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG3));
597*91f16700Schasinglulu 	NOTICE("pr4: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG4));
598*91f16700Schasinglulu 	NOTICE("pr5: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG5));
599*91f16700Schasinglulu 	NOTICE("pr6: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG6));
600*91f16700Schasinglulu 	NOTICE("pr7: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG7));
601*91f16700Schasinglulu 	NOTICE("pr8: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG8));
602*91f16700Schasinglulu 	NOTICE("pr9: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG9));
603*91f16700Schasinglulu 	NOTICE("pr10: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG10));
604*91f16700Schasinglulu 	NOTICE("pr11: %x\n", mmio_read_32(CRMU_IHOST_SW_PERSISTENT_REG11));
605*91f16700Schasinglulu }
606*91f16700Schasinglulu 
607*91f16700Schasinglulu void plat_bcm_bl2_plat_arch_setup(void)
608*91f16700Schasinglulu {
609*91f16700Schasinglulu 	if (chip_get_rev_id_major() == CHIP_REV_MAJOR_AX) {
610*91f16700Schasinglulu 		if (!(sotp_mem_read(SOTP_ATF_CFG_ROW_ID, SOTP_ROW_NO_ECC) &
611*91f16700Schasinglulu 		      SOTP_ATF_WATCHDOG_ENABLE_MASK)) {
612*91f16700Schasinglulu 			/*
613*91f16700Schasinglulu 			 * Stop sp805 watchdog timer immediately.
614*91f16700Schasinglulu 			 * It might has been set up by MCU patch earlier for
615*91f16700Schasinglulu 			 * eMMC workaround.
616*91f16700Schasinglulu 			 *
617*91f16700Schasinglulu 			 * Note the watchdog timer started in CRMU has a very
618*91f16700Schasinglulu 			 * short timeout and needs to be stopped immediately.
619*91f16700Schasinglulu 			 * Down below we restart it with a much longer timeout
620*91f16700Schasinglulu 			 * for BL2 and BL31
621*91f16700Schasinglulu 			 */
622*91f16700Schasinglulu 			sp805_stop(ARM_SP805_TWDG_BASE);
623*91f16700Schasinglulu 		}
624*91f16700Schasinglulu 	}
625*91f16700Schasinglulu 
626*91f16700Schasinglulu #if !BRCM_DISABLE_TRUSTED_WDOG
627*91f16700Schasinglulu 	/*
628*91f16700Schasinglulu 	 * start secure watchdog for BL2 and BL31.
629*91f16700Schasinglulu 	 * Note that UART download can take a longer time,
630*91f16700Schasinglulu 	 * so do not allow watchdog for UART download,
631*91f16700Schasinglulu 	 * as this boot source is not a standard modus operandi.
632*91f16700Schasinglulu 	 */
633*91f16700Schasinglulu 	if (boot_source_get() != BOOT_SOURCE_UART)
634*91f16700Schasinglulu 		sp805_start(ARM_SP805_TWDG_BASE, ARM_TWDG_LOAD_VAL);
635*91f16700Schasinglulu #endif
636*91f16700Schasinglulu 
637*91f16700Schasinglulu #ifdef BCM_ELOG
638*91f16700Schasinglulu 	/* Ensure logging is started out fresh in BL2. */
639*91f16700Schasinglulu 	mmio_write_32(BCM_ELOG_BL2_BASE, 0);
640*91f16700Schasinglulu #endif
641*91f16700Schasinglulu 	/*
642*91f16700Schasinglulu 	 * In BL2, since we have very limited space to store logs, we only
643*91f16700Schasinglulu 	 * save logs that are >= the WARNING level.
644*91f16700Schasinglulu 	 */
645*91f16700Schasinglulu 	bcm_elog_init((void *)BCM_ELOG_BL2_BASE, BCM_ELOG_BL2_SIZE,
646*91f16700Schasinglulu 		      LOG_LEVEL_WARNING);
647*91f16700Schasinglulu 
648*91f16700Schasinglulu 	dump_persistent_regs();
649*91f16700Schasinglulu 
650*91f16700Schasinglulu 	/* Read CRMU mailbox 0 */
651*91f16700Schasinglulu 	NOTICE("RESET (reported by CRMU): 0x%x\n",
652*91f16700Schasinglulu 	       mmio_read_32(CRMU_READ_MAIL_BOX0));
653*91f16700Schasinglulu 
654*91f16700Schasinglulu 	/*
655*91f16700Schasinglulu 	 * All non-boot-source PADs are in forced input-mode at
656*91f16700Schasinglulu 	 * reset so clear the force on non-boot-source PADs using
657*91f16700Schasinglulu 	 * CDRU register.
658*91f16700Schasinglulu 	 */
659*91f16700Schasinglulu 	mmio_clrbits_32((uintptr_t)CDRU_CHIP_IO_PAD_CONTROL,
660*91f16700Schasinglulu 		(1 << CDRU_CHIP_IO_PAD_CONTROL__CDRU_IOMUX_FORCE_PAD_IN_R));
661*91f16700Schasinglulu 
662*91f16700Schasinglulu #if DRIVER_OCOTP_ENABLE
663*91f16700Schasinglulu 	bcm_otpc_init(&otp_stingray_map);
664*91f16700Schasinglulu #endif
665*91f16700Schasinglulu 
666*91f16700Schasinglulu 	set_swreg_based_on_otp();
667*91f16700Schasinglulu 
668*91f16700Schasinglulu #if IHOST_PLL_FREQ != 0
669*91f16700Schasinglulu 	bcm_set_ihost_pll_freq(0x0, IHOST_PLL_FREQ);
670*91f16700Schasinglulu #endif
671*91f16700Schasinglulu 
672*91f16700Schasinglulu #ifdef INCLUDE_EMMC_DRIVER_ERASE_CODE
673*91f16700Schasinglulu 	/* The erasable unit of the eMMC is the "Erase Group";
674*91f16700Schasinglulu 	 * Erase group is measured in write blocks which are the
675*91f16700Schasinglulu 	 * basic writable units of the Device.
676*91f16700Schasinglulu 	 * The size of the Erase Group is a Device specific parameter
677*91f16700Schasinglulu 	 */
678*91f16700Schasinglulu 	emmc_erase(EMMC_ERASE_START_BLOCK, EMMC_ERASE_BLOCK_COUNT,
679*91f16700Schasinglulu 		   EMMC_ERASE_PARTITION);
680*91f16700Schasinglulu #endif
681*91f16700Schasinglulu 
682*91f16700Schasinglulu 	bcm_board_detect();
683*91f16700Schasinglulu #ifdef DRIVER_EMMC_ENABLE
684*91f16700Schasinglulu 	/* Initialize the card, if it is not */
685*91f16700Schasinglulu 	if (bcm_emmc_init(true) == 0)
686*91f16700Schasinglulu 		WARN("eMMC Card Initialization Failed!!!\n");
687*91f16700Schasinglulu #endif
688*91f16700Schasinglulu 
689*91f16700Schasinglulu #if BL2_TEST_I2C
690*91f16700Schasinglulu 	i2c_test();
691*91f16700Schasinglulu #endif
692*91f16700Schasinglulu 
693*91f16700Schasinglulu #ifdef USE_DDR
694*91f16700Schasinglulu 	ddr_initialize(&ddr_info);
695*91f16700Schasinglulu 
696*91f16700Schasinglulu 	ddr_secure_region_config(SECURE_DDR_BASE_ADDRESS,
697*91f16700Schasinglulu 				 SECURE_DDR_END_ADDRESS);
698*91f16700Schasinglulu #ifdef NITRO_SECURE_ACCESS
699*91f16700Schasinglulu 	ddr_secure_region_config(DDR_NITRO_SECURE_REGION_START,
700*91f16700Schasinglulu 				 DDR_NITRO_SECURE_REGION_END);
701*91f16700Schasinglulu #endif
702*91f16700Schasinglulu #else
703*91f16700Schasinglulu 	ext_sram_init();
704*91f16700Schasinglulu #endif
705*91f16700Schasinglulu 
706*91f16700Schasinglulu #if BL2_TEST_MEM
707*91f16700Schasinglulu 	ddr_test();
708*91f16700Schasinglulu #endif
709*91f16700Schasinglulu 
710*91f16700Schasinglulu #ifdef USE_NAND
711*91f16700Schasinglulu 	brcm_stingray_nand_init();
712*91f16700Schasinglulu #endif
713*91f16700Schasinglulu 
714*91f16700Schasinglulu #if defined(USE_PAXB) || defined(USE_PAXC) || defined(USE_SATA)
715*91f16700Schasinglulu 	brcm_stingray_pcie_reset();
716*91f16700Schasinglulu #endif
717*91f16700Schasinglulu 
718*91f16700Schasinglulu #ifdef USE_PAXC
719*91f16700Schasinglulu 	if (boot_source_get() != BOOT_SOURCE_QSPI)
720*91f16700Schasinglulu 		brcm_stingray_chimp_check_and_fastboot();
721*91f16700Schasinglulu #endif
722*91f16700Schasinglulu 
723*91f16700Schasinglulu #if ((!CLEAN_DDR || MMU_DISABLED))
724*91f16700Schasinglulu 	/*
725*91f16700Schasinglulu 	 * Now DDR has been initialized. We want to copy all the logs in SRAM
726*91f16700Schasinglulu 	 * into DDR so we will have much more space to store the logs in the
727*91f16700Schasinglulu 	 * next boot stage
728*91f16700Schasinglulu 	 */
729*91f16700Schasinglulu 	bcm_elog_copy_log((void *)BCM_ELOG_BL31_BASE,
730*91f16700Schasinglulu 			   MIN(BCM_ELOG_BL2_SIZE, BCM_ELOG_BL31_SIZE)
731*91f16700Schasinglulu 			 );
732*91f16700Schasinglulu 
733*91f16700Schasinglulu 	/*
734*91f16700Schasinglulu 	 * We are not yet at the end of BL2, but we can stop log here so we do
735*91f16700Schasinglulu 	 * not need to add 'bcm_elog_exit' to the standard BL2 code. The
736*91f16700Schasinglulu 	 * benefit of capturing BL2 logs after this is very minimal in a
737*91f16700Schasinglulu 	 * production system
738*91f16700Schasinglulu 	 * NOTE: BL2 logging must be exited before going forward to setup
739*91f16700Schasinglulu 	 * page tables
740*91f16700Schasinglulu 	 */
741*91f16700Schasinglulu 	bcm_elog_exit();
742*91f16700Schasinglulu #endif
743*91f16700Schasinglulu }
744