xref: /rk3399_ARM-atf/drivers/nxp/dcfg/dcfg.c (revision df02aeeec640d2358301e903d9c8c473d455be9e)
186b1b89fSPankaj Gupta /*
2*df02aeeeSBiwen Li  * Copyright 2020-2022 NXP
386b1b89fSPankaj Gupta  *
486b1b89fSPankaj Gupta  * SPDX-License-Identifier: BSD-3-Clause
586b1b89fSPankaj Gupta  *
686b1b89fSPankaj Gupta  */
786b1b89fSPankaj Gupta 
886b1b89fSPankaj Gupta #include <common/debug.h>
986b1b89fSPankaj Gupta #include "dcfg.h"
1086b1b89fSPankaj Gupta #include <lib/mmio.h>
1186b1b89fSPankaj Gupta #ifdef NXP_SFP_ENABLED
1286b1b89fSPankaj Gupta #include <sfp.h>
1386b1b89fSPankaj Gupta #endif
1486b1b89fSPankaj Gupta 
1586b1b89fSPankaj Gupta static soc_info_t soc_info = {0};
1686b1b89fSPankaj Gupta static devdisr5_info_t devdisr5_info = {0};
1786b1b89fSPankaj Gupta static dcfg_init_info_t *dcfg_init_info;
1886b1b89fSPankaj Gupta 
1986b1b89fSPankaj Gupta /* Read the PORSR1 register */
2086b1b89fSPankaj Gupta uint32_t read_reg_porsr1(void)
2186b1b89fSPankaj Gupta {
2286b1b89fSPankaj Gupta 	unsigned int *porsr1_addr = NULL;
2386b1b89fSPankaj Gupta 
2486b1b89fSPankaj Gupta 	if (dcfg_init_info->porsr1 != 0U) {
2586b1b89fSPankaj Gupta 		return dcfg_init_info->porsr1;
2686b1b89fSPankaj Gupta 	}
2786b1b89fSPankaj Gupta 
2886b1b89fSPankaj Gupta 	porsr1_addr = (void *)
2986b1b89fSPankaj Gupta 			(dcfg_init_info->g_nxp_dcfg_addr + DCFG_PORSR1_OFFSET);
3086b1b89fSPankaj Gupta 	dcfg_init_info->porsr1 = gur_in32(porsr1_addr);
3186b1b89fSPankaj Gupta 
3286b1b89fSPankaj Gupta 	return dcfg_init_info->porsr1;
3386b1b89fSPankaj Gupta }
3486b1b89fSPankaj Gupta 
3586b1b89fSPankaj Gupta 
3686b1b89fSPankaj Gupta const soc_info_t *get_soc_info(void)
3786b1b89fSPankaj Gupta {
3886b1b89fSPankaj Gupta 	uint32_t reg;
3986b1b89fSPankaj Gupta 
4086b1b89fSPankaj Gupta 	if (soc_info.is_populated == true) {
4186b1b89fSPankaj Gupta 		return (const soc_info_t *) &soc_info;
4286b1b89fSPankaj Gupta 	}
4386b1b89fSPankaj Gupta 
4486b1b89fSPankaj Gupta 	reg = gur_in32(dcfg_init_info->g_nxp_dcfg_addr + DCFG_SVR_OFFSET);
4586b1b89fSPankaj Gupta 
4608695df9SJiafei Pan 	soc_info.svr_reg.val = reg;
4708695df9SJiafei Pan 
4886b1b89fSPankaj Gupta 	/* zero means SEC enabled. */
4986b1b89fSPankaj Gupta 	soc_info.sec_enabled =
5086b1b89fSPankaj Gupta 		(((reg & SVR_SEC_MASK) >> SVR_SEC_SHIFT) == 0) ? true : false;
5186b1b89fSPankaj Gupta 
5286b1b89fSPankaj Gupta 	soc_info.is_populated = true;
5386b1b89fSPankaj Gupta 	return (const soc_info_t *) &soc_info;
5486b1b89fSPankaj Gupta }
5586b1b89fSPankaj Gupta 
5686b1b89fSPankaj Gupta void dcfg_init(dcfg_init_info_t *dcfg_init_data)
5786b1b89fSPankaj Gupta {
5886b1b89fSPankaj Gupta 	dcfg_init_info = dcfg_init_data;
5986b1b89fSPankaj Gupta 	read_reg_porsr1();
6086b1b89fSPankaj Gupta 	get_soc_info();
6186b1b89fSPankaj Gupta }
6286b1b89fSPankaj Gupta 
6386b1b89fSPankaj Gupta bool is_sec_enabled(void)
6486b1b89fSPankaj Gupta {
6586b1b89fSPankaj Gupta 	return soc_info.sec_enabled;
6686b1b89fSPankaj Gupta }
6786b1b89fSPankaj Gupta 
6886b1b89fSPankaj Gupta const devdisr5_info_t *get_devdisr5_info(void)
6986b1b89fSPankaj Gupta {
7086b1b89fSPankaj Gupta 	uint32_t reg;
7186b1b89fSPankaj Gupta 
7286b1b89fSPankaj Gupta 	if (devdisr5_info.is_populated == true)
7386b1b89fSPankaj Gupta 		return (const devdisr5_info_t *) &devdisr5_info;
7486b1b89fSPankaj Gupta 
7586b1b89fSPankaj Gupta 	reg = gur_in32(dcfg_init_info->g_nxp_dcfg_addr + DCFG_DEVDISR5_OFFSET);
7686b1b89fSPankaj Gupta 
77*df02aeeeSBiwen Li 	devdisr5_info.ddrc1_present = (reg & DISR5_DDRC1_MASK) ? 0 : 1;
7886b1b89fSPankaj Gupta #if defined(CONFIG_CHASSIS_3_2)
7986b1b89fSPankaj Gupta 	devdisr5_info.ddrc2_present = (reg & DISR5_DDRC2_MASK) ? 0 : 1;
8086b1b89fSPankaj Gupta #endif
81*df02aeeeSBiwen Li 	devdisr5_info.ocram_present = (reg & DISR5_OCRAM_MASK) ? 0 : 1;
8286b1b89fSPankaj Gupta 	devdisr5_info.is_populated = true;
8386b1b89fSPankaj Gupta 
8486b1b89fSPankaj Gupta 	return (const devdisr5_info_t *) &devdisr5_info;
8586b1b89fSPankaj Gupta }
8686b1b89fSPankaj Gupta 
8786b1b89fSPankaj Gupta int get_clocks(struct sysinfo *sys)
8886b1b89fSPankaj Gupta {
8986b1b89fSPankaj Gupta 	unsigned int *rcwsr0 = NULL;
9086b1b89fSPankaj Gupta 	const unsigned long sysclk = dcfg_init_info->nxp_sysclk_freq;
9186b1b89fSPankaj Gupta 	const unsigned long ddrclk = dcfg_init_info->nxp_ddrclk_freq;
9286b1b89fSPankaj Gupta 
9386b1b89fSPankaj Gupta 	rcwsr0 = (void *)(dcfg_init_info->g_nxp_dcfg_addr + RCWSR0_OFFSET);
9486b1b89fSPankaj Gupta 	sys->freq_platform = sysclk;
9586b1b89fSPankaj Gupta 	sys->freq_ddr_pll0 = ddrclk;
9686b1b89fSPankaj Gupta 	sys->freq_ddr_pll1 = ddrclk;
9786b1b89fSPankaj Gupta 
9886b1b89fSPankaj Gupta 	sys->freq_platform *= (gur_in32(rcwsr0) >>
9986b1b89fSPankaj Gupta 				RCWSR0_SYS_PLL_RAT_SHIFT) &
10086b1b89fSPankaj Gupta 				RCWSR0_SYS_PLL_RAT_MASK;
10186b1b89fSPankaj Gupta 
10286b1b89fSPankaj Gupta 	sys->freq_platform /= dcfg_init_info->nxp_plat_clk_divider;
10386b1b89fSPankaj Gupta 
10486b1b89fSPankaj Gupta 	sys->freq_ddr_pll0 *= (gur_in32(rcwsr0) >>
10586b1b89fSPankaj Gupta 				RCWSR0_MEM_PLL_RAT_SHIFT) &
10686b1b89fSPankaj Gupta 				RCWSR0_MEM_PLL_RAT_MASK;
10786b1b89fSPankaj Gupta 	sys->freq_ddr_pll1 *= (gur_in32(rcwsr0) >>
10886b1b89fSPankaj Gupta 				RCWSR0_MEM2_PLL_RAT_SHIFT) &
10986b1b89fSPankaj Gupta 				RCWSR0_MEM2_PLL_RAT_MASK;
11086b1b89fSPankaj Gupta 	if (sys->freq_platform == 0) {
11186b1b89fSPankaj Gupta 		return 1;
11286b1b89fSPankaj Gupta 	} else {
11386b1b89fSPankaj Gupta 		return 0;
11486b1b89fSPankaj Gupta 	}
11586b1b89fSPankaj Gupta }
11686b1b89fSPankaj Gupta 
11786b1b89fSPankaj Gupta #ifdef NXP_SFP_ENABLED
11886b1b89fSPankaj Gupta /*******************************************************************************
11986b1b89fSPankaj Gupta  * Returns true if secur eboot is enabled on board
12086b1b89fSPankaj Gupta  * mode = 0  (development mode - sb_en = 1)
12186b1b89fSPankaj Gupta  * mode = 1 (production mode - ITS = 1)
12286b1b89fSPankaj Gupta  ******************************************************************************/
12386b1b89fSPankaj Gupta bool check_boot_mode_secure(uint32_t *mode)
12486b1b89fSPankaj Gupta {
12586b1b89fSPankaj Gupta 	uint32_t val = 0U;
12686b1b89fSPankaj Gupta 	uint32_t *rcwsr = NULL;
12786b1b89fSPankaj Gupta 	*mode = 0U;
12886b1b89fSPankaj Gupta 
12986b1b89fSPankaj Gupta 	if (sfp_check_its() == 1) {
13086b1b89fSPankaj Gupta 		/* ITS =1 , Production mode */
13186b1b89fSPankaj Gupta 		*mode = 1U;
13286b1b89fSPankaj Gupta 		return true;
13386b1b89fSPankaj Gupta 	}
13486b1b89fSPankaj Gupta 
13586b1b89fSPankaj Gupta 	rcwsr = (void *)(dcfg_init_info->g_nxp_dcfg_addr + RCWSR_SB_EN_OFFSET);
13686b1b89fSPankaj Gupta 
13786b1b89fSPankaj Gupta 	val = (gur_in32(rcwsr) >> RCWSR_SBEN_SHIFT) &
13886b1b89fSPankaj Gupta 				RCWSR_SBEN_MASK;
13986b1b89fSPankaj Gupta 
14086b1b89fSPankaj Gupta 	if (val == RCWSR_SBEN_MASK) {
14186b1b89fSPankaj Gupta 		*mode = 0U;
14286b1b89fSPankaj Gupta 		return true;
14386b1b89fSPankaj Gupta 	}
14486b1b89fSPankaj Gupta 
14586b1b89fSPankaj Gupta 	return false;
14686b1b89fSPankaj Gupta }
14786b1b89fSPankaj Gupta #endif
14886b1b89fSPankaj Gupta 
14986b1b89fSPankaj Gupta void error_handler(int error_code)
15086b1b89fSPankaj Gupta {
15186b1b89fSPankaj Gupta 	 /* Dump error code in SCRATCH4 register */
15286b1b89fSPankaj Gupta 	INFO("Error in Fuse Provisioning: %x\n", error_code);
15386b1b89fSPankaj Gupta 	gur_out32((void *)
15486b1b89fSPankaj Gupta 		  (dcfg_init_info->g_nxp_dcfg_addr + DCFG_SCRATCH4_OFFSET),
15586b1b89fSPankaj Gupta 		  error_code);
15686b1b89fSPankaj Gupta }
157