nxp: add dcfg driver

NXP SoC needs Device Configuration driver to
fetch the current SoC configuration.

Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
Change-Id: Ie17cca01a8eb9a6f5feebb093756f577692432bf
This commit is contained in:
Pankaj Gupta 2020-12-09 14:02:38 +05:30
parent 0499215e1d
commit 86b1b89fbf
6 changed files with 495 additions and 0 deletions

167
drivers/nxp/dcfg/dcfg.c Normal file
View File

@ -0,0 +1,167 @@
/*
* Copyright 2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#include <common/debug.h>
#include "dcfg.h"
#include <lib/mmio.h>
#ifdef NXP_SFP_ENABLED
#include <sfp.h>
#endif
static soc_info_t soc_info = {0};
static devdisr5_info_t devdisr5_info = {0};
static dcfg_init_info_t *dcfg_init_info;
/* Read the PORSR1 register */
uint32_t read_reg_porsr1(void)
{
unsigned int *porsr1_addr = NULL;
if (dcfg_init_info->porsr1 != 0U) {
return dcfg_init_info->porsr1;
}
porsr1_addr = (void *)
(dcfg_init_info->g_nxp_dcfg_addr + DCFG_PORSR1_OFFSET);
dcfg_init_info->porsr1 = gur_in32(porsr1_addr);
return dcfg_init_info->porsr1;
}
const soc_info_t *get_soc_info(void)
{
uint32_t reg;
if (soc_info.is_populated == true) {
return (const soc_info_t *) &soc_info;
}
reg = gur_in32(dcfg_init_info->g_nxp_dcfg_addr + DCFG_SVR_OFFSET);
soc_info.mfr_id = (reg & SVR_MFR_ID_MASK) >> SVR_MFR_ID_SHIFT;
#if defined(CONFIG_CHASSIS_3_2)
soc_info.family = (reg & SVR_FAMILY_MASK) >> SVR_FAMILY_SHIFT;
soc_info.dev_id = (reg & SVR_DEV_ID_MASK) >> SVR_DEV_ID_SHIFT;
#endif
/* zero means SEC enabled. */
soc_info.sec_enabled =
(((reg & SVR_SEC_MASK) >> SVR_SEC_SHIFT) == 0) ? true : false;
soc_info.personality = (reg & SVR_PERSONALITY_MASK)
>> SVR_PERSONALITY_SHIFT;
soc_info.maj_ver = (reg & SVR_MAJ_VER_MASK) >> SVR_MAJ_VER_SHIFT;
soc_info.min_ver = reg & SVR_MIN_VER_MASK;
soc_info.is_populated = true;
return (const soc_info_t *) &soc_info;
}
void dcfg_init(dcfg_init_info_t *dcfg_init_data)
{
dcfg_init_info = dcfg_init_data;
read_reg_porsr1();
get_soc_info();
}
bool is_sec_enabled(void)
{
return soc_info.sec_enabled;
}
const devdisr5_info_t *get_devdisr5_info(void)
{
uint32_t reg;
if (devdisr5_info.is_populated == true)
return (const devdisr5_info_t *) &devdisr5_info;
reg = gur_in32(dcfg_init_info->g_nxp_dcfg_addr + DCFG_DEVDISR5_OFFSET);
#if defined(CONFIG_CHASSIS_3_2)
devdisr5_info.ddrc1_present = (reg & DISR5_DDRC1_MASK) ? 0 : 1;
devdisr5_info.ddrc2_present = (reg & DISR5_DDRC2_MASK) ? 0 : 1;
devdisr5_info.ocram_present = (reg & DISR5_OCRAM_MASK) ? 0 : 1;
#elif defined(CONFIG_CHASSIS_2)
devdisr5_info.ddrc1_present = (reg & DISR5_DDRC1_MASK) ? 0 : 1;
devdisr5_info.ocram_present = (reg & DISR5_OCRAM_MASK) ? 0 : 1;
#endif
devdisr5_info.is_populated = true;
return (const devdisr5_info_t *) &devdisr5_info;
}
int get_clocks(struct sysinfo *sys)
{
unsigned int *rcwsr0 = NULL;
const unsigned long sysclk = dcfg_init_info->nxp_sysclk_freq;
const unsigned long ddrclk = dcfg_init_info->nxp_ddrclk_freq;
rcwsr0 = (void *)(dcfg_init_info->g_nxp_dcfg_addr + RCWSR0_OFFSET);
sys->freq_platform = sysclk;
sys->freq_ddr_pll0 = ddrclk;
sys->freq_ddr_pll1 = ddrclk;
sys->freq_platform *= (gur_in32(rcwsr0) >>
RCWSR0_SYS_PLL_RAT_SHIFT) &
RCWSR0_SYS_PLL_RAT_MASK;
sys->freq_platform /= dcfg_init_info->nxp_plat_clk_divider;
sys->freq_ddr_pll0 *= (gur_in32(rcwsr0) >>
RCWSR0_MEM_PLL_RAT_SHIFT) &
RCWSR0_MEM_PLL_RAT_MASK;
sys->freq_ddr_pll1 *= (gur_in32(rcwsr0) >>
RCWSR0_MEM2_PLL_RAT_SHIFT) &
RCWSR0_MEM2_PLL_RAT_MASK;
if (sys->freq_platform == 0) {
return 1;
} else {
return 0;
}
}
#ifdef NXP_SFP_ENABLED
/*******************************************************************************
* Returns true if secur eboot is enabled on board
* mode = 0 (development mode - sb_en = 1)
* mode = 1 (production mode - ITS = 1)
******************************************************************************/
bool check_boot_mode_secure(uint32_t *mode)
{
uint32_t val = 0U;
uint32_t *rcwsr = NULL;
*mode = 0U;
if (sfp_check_its() == 1) {
/* ITS =1 , Production mode */
*mode = 1U;
return true;
}
rcwsr = (void *)(dcfg_init_info->g_nxp_dcfg_addr + RCWSR_SB_EN_OFFSET);
val = (gur_in32(rcwsr) >> RCWSR_SBEN_SHIFT) &
RCWSR_SBEN_MASK;
if (val == RCWSR_SBEN_MASK) {
*mode = 0U;
return true;
}
return false;
}
#endif
void error_handler(int error_code)
{
/* Dump error code in SCRATCH4 register */
INFO("Error in Fuse Provisioning: %x\n", error_code);
gur_out32((void *)
(dcfg_init_info->g_nxp_dcfg_addr + DCFG_SCRATCH4_OFFSET),
error_code);
}

85
drivers/nxp/dcfg/dcfg.h Normal file
View File

@ -0,0 +1,85 @@
/*
* Copyright 2018-2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef DCFG_H
#define DCFG_H
#include <endian.h>
#if defined(CONFIG_CHASSIS_2)
#include <dcfg_lsch2.h>
#elif defined(CONFIG_CHASSIS_3_2)
#include <dcfg_lsch3.h>
#endif
#ifdef NXP_GUR_BE
#define gur_in32(a) bswap32(mmio_read_32((uintptr_t)(a)))
#define gur_out32(a, v) mmio_write_32((uintptr_t)(a), bswap32(v))
#elif defined(NXP_GUR_LE)
#define gur_in32(a) mmio_read_32((uintptr_t)(a))
#define gur_out32(a, v) mmio_write_32((uintptr_t)(a), v)
#else
#error Please define CCSR GUR register endianness
#endif
typedef struct {
bool is_populated;
uint8_t mfr_id;
#if defined(CONFIG_CHASSIS_3_2)
uint8_t family;
uint8_t dev_id;
#endif
uint8_t personality;
bool sec_enabled;
uint8_t maj_ver;
uint8_t min_ver;
} soc_info_t;
typedef struct {
bool is_populated;
uint8_t ocram_present;
uint8_t ddrc1_present;
#if defined(CONFIG_CHASSIS_3_2)
uint8_t ddrc2_present;
#endif
} devdisr5_info_t;
typedef struct {
uint32_t porsr1;
uintptr_t g_nxp_dcfg_addr;
unsigned long nxp_sysclk_freq;
unsigned long nxp_ddrclk_freq;
unsigned int nxp_plat_clk_divider;
} dcfg_init_info_t;
struct sysinfo {
unsigned long freq_platform;
unsigned long freq_ddr_pll0;
unsigned long freq_ddr_pll1;
};
int get_clocks(struct sysinfo *sys);
/* Read the PORSR1 register */
uint32_t read_reg_porsr1(void);
/*******************************************************************************
* Returns true if secur eboot is enabled on board
* mode = 0 (development mode - sb_en = 1)
* mode = 1 (production mode - ITS = 1)
******************************************************************************/
bool check_boot_mode_secure(uint32_t *mode);
const soc_info_t *get_soc_info();
const devdisr5_info_t *get_devdisr5_info();
void dcfg_init(dcfg_init_info_t *dcfg_init_data);
bool is_sec_enabled(void);
void error_handler(int error_code);
#endif /* DCFG_H */

28
drivers/nxp/dcfg/dcfg.mk Normal file
View File

@ -0,0 +1,28 @@
#
# Copyright 2020 NXP
#
# SPDX-License-Identifier: BSD-3-Clause
#
ifeq (${ADD_DCFG},)
ADD_DCFG := 1
DCFG_DRIVERS_PATH := ${PLAT_DRIVERS_PATH}/dcfg
PLAT_INCLUDES += -I$(DCFG_DRIVERS_PATH)
DCFG_SOURCES += $(DCFG_DRIVERS_PATH)/dcfg.c
ifeq (${BL_COMM_DCFG_NEEDED},yes)
BL_COMMON_SOURCES += ${DCFG_SOURCES}
else
ifeq (${BL2_DCFG_NEEDED},yes)
BL2_SOURCES += ${DCFG_SOURCES}
endif
ifeq (${BL31_DCFG_NEEDED},yes)
BL31_SOURCES += ${DCFG_SOURCES}
endif
endif
endif

View File

@ -0,0 +1,79 @@
/*
* Copyright 2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef DCFG_LSCH2_H
#define DCFG_LSCH2_H
/* dcfg block register offsets and bitfields */
#define DCFG_PORSR1_OFFSET 0x00
#define DCFG_DEVDISR1_OFFSET 0x070
#define DCFG_DEVDISR4_OFFSET 0x07C
#define DCFG_DEVDISR5_OFFSET 0x080
#define DCFG_COREDISR_OFFSET 0x094
#define RCWSR0_OFFSET 0x100
#define RCWSR5_OFFSET 0x118
#define DCFG_BOOTLOCPTRL_OFFSET 0x400
#define DCFG_BOOTLOCPTRH_OFFSET 0x404
#define DCFG_COREDISABLEDSR_OFFSET 0x990
#define DCFG_SCRATCH4_OFFSET 0x20C
#define DCFG_SVR_OFFSET 0x0A4
#define DCFG_BRR_OFFSET 0x0E4
#define DCFG_RSTCR_OFFSET 0x0B0
#define RSTCR_RESET_REQ 0x2
#define DCFG_RSTRQSR1_OFFSET 0x0C8
#define DCFG_RSTRQMR1_OFFSET 0x0C0
/* DCFG DCSR Macros */
#define DCFG_DCSR_PORCR1_OFFSET 0x0
#define SVR_MFR_ID_MASK 0xF0000000
#define SVR_MFR_ID_SHIFT 28
#define SVR_FAMILY_MASK 0xF000000
#define SVR_FAMILY_SHIFT 24
#define SVR_DEV_ID_MASK 0x3F0000
#define SVR_DEV_ID_SHIFT 16
#define SVR_PERSONALITY_MASK 0x3E00
#define SVR_PERSONALITY_SHIFT 9
#define SVR_SEC_MASK 0x100
#define SVR_SEC_SHIFT 8
#define SVR_MAJ_VER_MASK 0xF0
#define SVR_MAJ_VER_SHIFT 4
#define SVR_MIN_VER_MASK 0xF
#define DISR5_DDRC1_MASK 0x1
#define DISR5_OCRAM_MASK 0x40
/* DCFG regsiters bit masks */
#define RCWSR0_SYS_PLL_RAT_SHIFT 25
#define RCWSR0_SYS_PLL_RAT_MASK 0x1f
#define RCWSR0_MEM_PLL_RAT_SHIFT 16
#define RCWSR0_MEM_PLL_RAT_MASK 0x3f
#define RCWSR0_MEM2_PLL_RAT_SHIFT 18
#define RCWSR0_MEM2_PLL_RAT_MASK 0x3f
#define RCWSR_SB_EN_OFFSET RCWSR5_OFFSET
#define RCWSR_SBEN_MASK 0x1
#define RCWSR_SBEN_SHIFT 21
/* RCW SRC NAND */
#define RCW_SRC_NAND_MASK (0x100)
#define RCW_SRC_NAND_VAL (0x100)
#define NAND_RESERVED_MASK (0xFC)
#define NAND_RESERVED_1 (0x0)
#define NAND_RESERVED_2 (0x80)
/* RCW SRC NOR */
#define RCW_SRC_NOR_MASK (0x1F0)
#define NOR_8B_VAL (0x10)
#define NOR_16B_VAL (0x20)
#define SD_VAL (0x40)
#define QSPI_VAL1 (0x44)
#define QSPI_VAL2 (0x45)
#endif /* DCFG_LSCH2_H */

View File

@ -0,0 +1,77 @@
/*
* Copyright 2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef DCFG_LSCH3_H
#define DCFG_LSCH3_H
/* dcfg block register offsets and bitfields */
#define DCFG_PORSR1_OFFSET 0x00
#define DCFG_DEVDISR1_OFFSET 0x70
#define DCFG_DEVDISR1_SEC (1 << 22)
#define DCFG_DEVDISR2_OFFSET 0x74
#define DCFG_DEVDISR3_OFFSET 0x78
#define DCFG_DEVDISR3_QBMAIN (1 << 12)
#define DCFG_DEVDISR4_OFFSET 0x7C
#define DCFG_DEVDISR4_SPI_QSPI (1 << 4 | 1 << 5)
#define DCFG_DEVDISR5_OFFSET 0x80
#define DISR5_DDRC1_MASK 0x1
#define DISR5_DDRC2_MASK 0x2
#define DISR5_OCRAM_MASK 0x1000
#define DEVDISR5_MASK_ALL_MEM 0x00001003
#define DEVDISR5_MASK_DDR 0x00000003
#define DEVDISR5_MASK_DBG 0x00000400
#define DCFG_DEVDISR6_OFFSET 0x84
//#define DEVDISR6_MASK 0x00000001
#define DCFG_COREDISR_OFFSET 0x94
#define DCFG_SVR_OFFSET 0x0A4
#define SVR_MFR_ID_MASK 0xF0000000
#define SVR_MFR_ID_SHIFT 28
#define SVR_FAMILY_MASK 0xF000000
#define SVR_FAMILY_SHIFT 24
#define SVR_DEV_ID_MASK 0x3F0000
#define SVR_DEV_ID_SHIFT 16
#define SVR_PERSONALITY_MASK 0x3E00
#define SVR_PERSONALITY_SHIFT 9
#define SVR_SEC_MASK 0x100
#define SVR_SEC_SHIFT 8
#define SVR_MAJ_VER_MASK 0xF0
#define SVR_MAJ_VER_SHIFT 4
#define SVR_MIN_VER_MASK 0xF
#define RCWSR0_OFFSET 0x100
#define RCWSR0_SYS_PLL_RAT_SHIFT 2
#define RCWSR0_SYS_PLL_RAT_MASK 0x1f
#define RCWSR0_MEM_PLL_RAT_SHIFT 10
#define RCWSR0_MEM_PLL_RAT_MASK 0x3f
#define RCWSR0_MEM2_PLL_RAT_SHIFT 18
#define RCWSR0_MEM2_PLL_RAT_MASK 0x3f
#define RCWSR5_OFFSET 0x110
#define RCWSR9_OFFSET 0x120
#define RCWSR_SB_EN_OFFSET RCWSR9_OFFSET
#define RCWSR_SBEN_MASK 0x1
#define RCWSR_SBEN_SHIFT 10
#define RCW_SR27_OFFSET 0x168
/* DCFG register to dump error code */
#define DCFG_SCRATCH4_OFFSET 0x20C
#define DCFG_SCRATCHRW5_OFFSET 0x210
#define DCFG_SCRATCHRW6_OFFSET 0x214
#define DCFG_SCRATCHRW7_OFFSET 0x218
#define DCFG_BOOTLOCPTRL_OFFSET 0x400
#define DCFG_BOOTLOCPTRH_OFFSET 0x404
#define DCFG_COREDISABLEDSR_OFFSET 0x990
#endif /* DCFG_LSCH3_H */

59
drivers/nxp/dcfg/scfg.h Normal file
View File

@ -0,0 +1,59 @@
/*
* Copyright 2020 NXP
*
* SPDX-License-Identifier: BSD-3-Clause
*
*/
#ifndef SCFG_H
#define SCFG_H
#ifdef CONFIG_CHASSIS_2
/* SCFG register offsets */
#define SCFG_CORE0_SFT_RST_OFFSET 0x0130
#define SCFG_SNPCNFGCR_OFFSET 0x01A4
#define SCFG_CORESRENCR_OFFSET 0x0204
#define SCFG_RVBAR0_0_OFFSET 0x0220
#define SCFG_RVBAR0_1_OFFSET 0x0224
#define SCFG_COREBCR_OFFSET 0x0680
#define SCFG_RETREQCR_OFFSET 0x0424
#define SCFG_COREPMCR_OFFSET 0x042C
#define COREPMCR_WFIL2 0x1
#define SCFG_GIC400_ADDR_ALIGN_OFFSET 0x0188
#define SCFG_BOOTLOCPTRH_OFFSET 0x0600
#define SCFG_BOOTLOCPTRL_OFFSET 0x0604
#define SCFG_SCRATCHRW2_OFFSET 0x0608
#define SCFG_SCRATCHRW3_OFFSET 0x060C
/* SCFG bit fields */
#define SCFG_SNPCNFGCR_SECRDSNP 0x80000000
#define SCFG_SNPCNFGCR_SECWRSNP 0x40000000
#endif /* CONFIG_CHASSIS_2 */
#ifndef __ASSEMBLER__
#include <endian.h>
#include <lib/mmio.h>
#ifdef NXP_SCFG_BE
#define scfg_in32(a) bswap32(mmio_read_32((uintptr_t)(a)))
#define scfg_out32(a, v) mmio_write_32((uintptr_t)(a), bswap32(v))
#define scfg_setbits32(a, v) mmio_setbits_32((uintptr_t)(a), v)
#define scfg_clrbits32(a, v) mmio_clrbits_32((uintptr_t)(a), v)
#define scfg_clrsetbits32(a, clear, set) \
mmio_clrsetbits_32((uintptr_t)(a), clear, set)
#elif defined(NXP_GUR_LE)
#define scfg_in32(a) mmio_read_32((uintptr_t)(a))
#define scfg_out32(a, v) mmio_write_32((uintptr_t)(a), v)
#define scfg_setbits32(a, v) mmio_setbits_32((uintptr_t)(a), v)
#define scfg_clrbits32(a, v) mmio_clrbits_32((uintptr_t)(a), v)
#define scfg_clrsetbits32(a, clear, set) \
mmio_clrsetbits_32((uintptr_t)(a), clear, set)
#else
#error Please define CCSR SCFG register endianness
#endif
#endif /* __ASSEMBLER__ */
#endif /* SCFG_H */