xref: /arm-trusted-firmware/drivers/nxp/dcfg/dcfg.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright 2020-2022 NXP
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  *
6*91f16700Schasinglulu  */
7*91f16700Schasinglulu 
8*91f16700Schasinglulu #include <common/debug.h>
9*91f16700Schasinglulu #include "dcfg.h"
10*91f16700Schasinglulu #include <lib/mmio.h>
11*91f16700Schasinglulu #ifdef NXP_SFP_ENABLED
12*91f16700Schasinglulu #include <sfp.h>
13*91f16700Schasinglulu #endif
14*91f16700Schasinglulu 
15*91f16700Schasinglulu static soc_info_t soc_info = {0};
16*91f16700Schasinglulu static devdisr5_info_t devdisr5_info = {0};
17*91f16700Schasinglulu static dcfg_init_info_t *dcfg_init_info;
18*91f16700Schasinglulu 
19*91f16700Schasinglulu /* Read the PORSR1 register */
20*91f16700Schasinglulu uint32_t read_reg_porsr1(void)
21*91f16700Schasinglulu {
22*91f16700Schasinglulu 	unsigned int *porsr1_addr = NULL;
23*91f16700Schasinglulu 
24*91f16700Schasinglulu 	if (dcfg_init_info->porsr1 != 0U) {
25*91f16700Schasinglulu 		return dcfg_init_info->porsr1;
26*91f16700Schasinglulu 	}
27*91f16700Schasinglulu 
28*91f16700Schasinglulu 	porsr1_addr = (void *)
29*91f16700Schasinglulu 			(dcfg_init_info->g_nxp_dcfg_addr + DCFG_PORSR1_OFFSET);
30*91f16700Schasinglulu 	dcfg_init_info->porsr1 = gur_in32(porsr1_addr);
31*91f16700Schasinglulu 
32*91f16700Schasinglulu 	return dcfg_init_info->porsr1;
33*91f16700Schasinglulu }
34*91f16700Schasinglulu 
35*91f16700Schasinglulu 
36*91f16700Schasinglulu const soc_info_t *get_soc_info(void)
37*91f16700Schasinglulu {
38*91f16700Schasinglulu 	uint32_t reg;
39*91f16700Schasinglulu 
40*91f16700Schasinglulu 	if (soc_info.is_populated == true) {
41*91f16700Schasinglulu 		return (const soc_info_t *) &soc_info;
42*91f16700Schasinglulu 	}
43*91f16700Schasinglulu 
44*91f16700Schasinglulu 	reg = gur_in32(dcfg_init_info->g_nxp_dcfg_addr + DCFG_SVR_OFFSET);
45*91f16700Schasinglulu 
46*91f16700Schasinglulu 	soc_info.svr_reg.val = reg;
47*91f16700Schasinglulu 
48*91f16700Schasinglulu 	/* zero means SEC enabled. */
49*91f16700Schasinglulu 	soc_info.sec_enabled =
50*91f16700Schasinglulu 		(((reg & SVR_SEC_MASK) >> SVR_SEC_SHIFT) == 0) ? true : false;
51*91f16700Schasinglulu 
52*91f16700Schasinglulu 	soc_info.is_populated = true;
53*91f16700Schasinglulu 	return (const soc_info_t *) &soc_info;
54*91f16700Schasinglulu }
55*91f16700Schasinglulu 
56*91f16700Schasinglulu void dcfg_init(dcfg_init_info_t *dcfg_init_data)
57*91f16700Schasinglulu {
58*91f16700Schasinglulu 	dcfg_init_info = dcfg_init_data;
59*91f16700Schasinglulu 	read_reg_porsr1();
60*91f16700Schasinglulu 	get_soc_info();
61*91f16700Schasinglulu }
62*91f16700Schasinglulu 
63*91f16700Schasinglulu bool is_sec_enabled(void)
64*91f16700Schasinglulu {
65*91f16700Schasinglulu 	return soc_info.sec_enabled;
66*91f16700Schasinglulu }
67*91f16700Schasinglulu 
68*91f16700Schasinglulu const devdisr5_info_t *get_devdisr5_info(void)
69*91f16700Schasinglulu {
70*91f16700Schasinglulu 	uint32_t reg;
71*91f16700Schasinglulu 
72*91f16700Schasinglulu 	if (devdisr5_info.is_populated == true)
73*91f16700Schasinglulu 		return (const devdisr5_info_t *) &devdisr5_info;
74*91f16700Schasinglulu 
75*91f16700Schasinglulu 	reg = gur_in32(dcfg_init_info->g_nxp_dcfg_addr + DCFG_DEVDISR5_OFFSET);
76*91f16700Schasinglulu 
77*91f16700Schasinglulu 	devdisr5_info.ddrc1_present = (reg & DISR5_DDRC1_MASK) ? 0 : 1;
78*91f16700Schasinglulu #if defined(CONFIG_CHASSIS_3_2)
79*91f16700Schasinglulu 	devdisr5_info.ddrc2_present = (reg & DISR5_DDRC2_MASK) ? 0 : 1;
80*91f16700Schasinglulu #endif
81*91f16700Schasinglulu 	devdisr5_info.ocram_present = (reg & DISR5_OCRAM_MASK) ? 0 : 1;
82*91f16700Schasinglulu 	devdisr5_info.is_populated = true;
83*91f16700Schasinglulu 
84*91f16700Schasinglulu 	return (const devdisr5_info_t *) &devdisr5_info;
85*91f16700Schasinglulu }
86*91f16700Schasinglulu 
87*91f16700Schasinglulu int get_clocks(struct sysinfo *sys)
88*91f16700Schasinglulu {
89*91f16700Schasinglulu 	unsigned int *rcwsr0 = NULL;
90*91f16700Schasinglulu 	const unsigned long sysclk = dcfg_init_info->nxp_sysclk_freq;
91*91f16700Schasinglulu 	const unsigned long ddrclk = dcfg_init_info->nxp_ddrclk_freq;
92*91f16700Schasinglulu 
93*91f16700Schasinglulu 	rcwsr0 = (void *)(dcfg_init_info->g_nxp_dcfg_addr + RCWSR0_OFFSET);
94*91f16700Schasinglulu 	sys->freq_platform = sysclk;
95*91f16700Schasinglulu 	sys->freq_ddr_pll0 = ddrclk;
96*91f16700Schasinglulu 	sys->freq_ddr_pll1 = ddrclk;
97*91f16700Schasinglulu 
98*91f16700Schasinglulu 	sys->freq_platform *= (gur_in32(rcwsr0) >>
99*91f16700Schasinglulu 				RCWSR0_SYS_PLL_RAT_SHIFT) &
100*91f16700Schasinglulu 				RCWSR0_SYS_PLL_RAT_MASK;
101*91f16700Schasinglulu 
102*91f16700Schasinglulu 	sys->freq_platform /= dcfg_init_info->nxp_plat_clk_divider;
103*91f16700Schasinglulu 
104*91f16700Schasinglulu 	sys->freq_ddr_pll0 *= (gur_in32(rcwsr0) >>
105*91f16700Schasinglulu 				RCWSR0_MEM_PLL_RAT_SHIFT) &
106*91f16700Schasinglulu 				RCWSR0_MEM_PLL_RAT_MASK;
107*91f16700Schasinglulu 	sys->freq_ddr_pll1 *= (gur_in32(rcwsr0) >>
108*91f16700Schasinglulu 				RCWSR0_MEM2_PLL_RAT_SHIFT) &
109*91f16700Schasinglulu 				RCWSR0_MEM2_PLL_RAT_MASK;
110*91f16700Schasinglulu 	if (sys->freq_platform == 0) {
111*91f16700Schasinglulu 		return 1;
112*91f16700Schasinglulu 	} else {
113*91f16700Schasinglulu 		return 0;
114*91f16700Schasinglulu 	}
115*91f16700Schasinglulu }
116*91f16700Schasinglulu 
117*91f16700Schasinglulu #ifdef NXP_SFP_ENABLED
118*91f16700Schasinglulu /*******************************************************************************
119*91f16700Schasinglulu  * Returns true if secur eboot is enabled on board
120*91f16700Schasinglulu  * mode = 0  (development mode - sb_en = 1)
121*91f16700Schasinglulu  * mode = 1 (production mode - ITS = 1)
122*91f16700Schasinglulu  ******************************************************************************/
123*91f16700Schasinglulu bool check_boot_mode_secure(uint32_t *mode)
124*91f16700Schasinglulu {
125*91f16700Schasinglulu 	uint32_t val = 0U;
126*91f16700Schasinglulu 	uint32_t *rcwsr = NULL;
127*91f16700Schasinglulu 	*mode = 0U;
128*91f16700Schasinglulu 
129*91f16700Schasinglulu 	if (sfp_check_its() == 1) {
130*91f16700Schasinglulu 		/* ITS =1 , Production mode */
131*91f16700Schasinglulu 		*mode = 1U;
132*91f16700Schasinglulu 		return true;
133*91f16700Schasinglulu 	}
134*91f16700Schasinglulu 
135*91f16700Schasinglulu 	rcwsr = (void *)(dcfg_init_info->g_nxp_dcfg_addr + RCWSR_SB_EN_OFFSET);
136*91f16700Schasinglulu 
137*91f16700Schasinglulu 	val = (gur_in32(rcwsr) >> RCWSR_SBEN_SHIFT) &
138*91f16700Schasinglulu 				RCWSR_SBEN_MASK;
139*91f16700Schasinglulu 
140*91f16700Schasinglulu 	if (val == RCWSR_SBEN_MASK) {
141*91f16700Schasinglulu 		*mode = 0U;
142*91f16700Schasinglulu 		return true;
143*91f16700Schasinglulu 	}
144*91f16700Schasinglulu 
145*91f16700Schasinglulu 	return false;
146*91f16700Schasinglulu }
147*91f16700Schasinglulu #endif
148*91f16700Schasinglulu 
149*91f16700Schasinglulu void error_handler(int error_code)
150*91f16700Schasinglulu {
151*91f16700Schasinglulu 	 /* Dump error code in SCRATCH4 register */
152*91f16700Schasinglulu 	INFO("Error in Fuse Provisioning: %x\n", error_code);
153*91f16700Schasinglulu 	gur_out32((void *)
154*91f16700Schasinglulu 		  (dcfg_init_info->g_nxp_dcfg_addr + DCFG_SCRATCH4_OFFSET),
155*91f16700Schasinglulu 		  error_code);
156*91f16700Schasinglulu }
157