From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tim Harvey Date: Fri, 22 Feb 2019 10:03:01 -0800 Subject: [U-Boot] [RFC 04/22] thunderx: add thunderx register definitions and misc functions In-Reply-To: <20190222180319.32221-1-tharvey@gateworks.com> References: <20190222180319.32221-1-tharvey@gateworks.com> Message-ID: <20190222180319.32221-5-tharvey@gateworks.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de Add Cavium Thunderx common registers, structures, and helper functions Signed-off-by: Tim Harvey --- arch/arm/include/asm/arch-thunderx/thunderx.h | 300 ++++++++++++++++++ arch/arm/mach-thunderx/Makefile | 2 +- arch/arm/mach-thunderx/misc.c | 33 ++ 3 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/arch-thunderx/thunderx.h create mode 100644 arch/arm/mach-thunderx/misc.c diff --git a/arch/arm/include/asm/arch-thunderx/thunderx.h b/arch/arm/include/asm/arch-thunderx/thunderx.h new file mode 100644 index 0000000000..58f36c6cdc --- /dev/null +++ b/arch/arm/include/asm/arch-thunderx/thunderx.h @@ -0,0 +1,300 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Cavium Inc. + */ +#ifndef __THUNDERX_H__ +#define __THUNDERX_H__ + +/* Registers */ +#define CAVM_RST_BOOT 0x87e006001600ll +#define CAVM_MIO_FUS_DAT2 0x87e003001410ll +#define CAVM_XCVX_RESET 0x87e0db000000ll + +/* + * Flag bits in top byte. The top byte of MIDR_EL1 is defined + * as ox43, the Cavium implementer code. In this number, bits + * 7,5,4 are defiend as zero. We use these bits to signal + * that revision numbers should be ignored. It isn't ideal + * that these are in the middle of an already defined field, + * but this keeps the model numbers as 32 bits + */ +#define __OM_IGNORE_REVISION 0x80000000 +#define __OM_IGNORE_MINOR_REVISION 0x20000000 +#define __OM_IGNORE_MODEL 0x10000000 + +#define CAVIUM_CN88XX_PASS1_0 0x430f0a10 +#define CAVIUM_CN88XX_PASS1_1 0x430f0a11 +#define CAVIUM_CN88XX_PASS2_0 0x431f0a10 +#define CAVIUM_CN88XX_PASS2_1 0x431f0a11 +#define CAVIUM_CN88XX_PASS2_2 0x431f0a12 +#define CAVIUM_CN88XX (CAVIUM_CN88XX_PASS1_0 | __OM_IGNORE_REVISION) +#define CAVIUM_CN88XX_PASS1_X (CAVIUM_CN88XX_PASS1_0 | __OM_IGNORE_MINOR_REVISION) +#define CAVIUM_CN88XX_PASS2_X (CAVIUM_CN88XX_PASS2_0 | __OM_IGNORE_MINOR_REVISION) + +#define CAVIUM_CN83XX_PASS1_0 0x430f0a30 +#define CAVIUM_CN83XX (CAVIUM_CN83XX_PASS1_0 | __OM_IGNORE_REVISION) +#define CAVIUM_CN83XX_PASS1_X (CAVIUM_CN83XX_PASS1_0 | __OM_IGNORE_MINOR_REVISION) + +#define CAVIUM_CN81XX_PASS1_0 0x430f0a20 +#define CAVIUM_CN81XX (CAVIUM_CN81XX_PASS1_0 | __OM_IGNORE_REVISION) +#define CAVIUM_CN81XX_PASS1_X (CAVIUM_CN81XX_PASS1_0 | __OM_IGNORE_MINOR_REVISION) + +#define CAVIUM_CN98XX_PASS1_0 0x430f0b10 +#define CAVIUM_CN98XX (CAVIUM_CN98XX_PASS1_0 | __OM_IGNORE_REVISION) +#define CAVIUM_CN98XX_PASS1_X (CAVIUM_CN98XX_PASS1_0 | __OM_IGNORE_MINOR_REVISION) + +/* These match entire families of chips */ +#define CAVIUM_CN8XXX (CAVIUM_CN88XX_PASS1_0 | __OM_IGNORE_MODEL) +#define CAVIUM_CN9XXX (CAVIUM_CN98XX_PASS1_0 | __OM_IGNORE_MODEL) + +static inline uint64_t cavium_get_model(void) +{ + uint64_t result; + + __asm ("mrs %[rd],MIDR_EL1" : [rd] "=r" (result)); + + return result; +} + +/** + * Return non-zero if the chip matched the passed model. + * + * @param arg_model One of the CAVIUM_* constants for chip models and passes + * @return Non-zero if match + */ +static inline int CAVIUM_IS_MODEL(uint32_t arg_model) +{ + const uint32_t FAMILY = 0xff00; /* Bits 15:8 */ + const uint32_t PARTNUM = 0xfff0; /* Bits 15:4 */ + const uint32_t VARIANT = 0xf00000; /* Bits 23:20 */ + const uint32_t REVISION = 0xf; /* Bits 3:0 */ + + uint32_t my_model = cavium_get_model(); + uint32_t mask; + + if (arg_model & __OM_IGNORE_MODEL) + mask = FAMILY; + else if (arg_model & __OM_IGNORE_REVISION) + mask = PARTNUM; + else if (arg_model & __OM_IGNORE_MINOR_REVISION) + mask = PARTNUM | VARIANT; + else + mask = PARTNUM | VARIANT | REVISION; + return ((arg_model & mask) == (my_model & mask)); +} + +/** + * Register (RSL) rst_boot + * + * RST Boot Register + */ +union cavm_rst_boot +{ + u64 u; + struct cavm_rst_boot_s { +#if __BYTE_ORDER == __BIG_ENDIAN /* Word 0 - Big Endian */ + u64 chipkill:1; + u64 jtcsrdis:1; + u64 ejtagdis:1; + u64 trusted_mode:1; + u64 ckill_ppdis:1; + u64 jt_tstmode:1; + u64 vrm_err:1; + u64 dis_huk:1; + u64 dis_scan:1; + u64 reserved_47_54:8; + u64 c_mul:7; + u64 reserved_39:1; + u64 pnr_mul:6; + u64 lboot_oci:3; + u64 lboot_pf_flr:4; + u64 lboot_ckill:1; + u64 lboot_jtg:1; + u64 lboot_ext45:6; + u64 lboot_ext23:6; + u64 lboot:10; + u64 rboot:1; + u64 rboot_pin:1; +#else /* Word 0 - Little Endian */ + u64 rboot_pin:1; + u64 rboot:1; + u64 lboot:10; + u64 lboot_ext23:6; + u64 lboot_ext45:6; + u64 lboot_jtg:1; + u64 lboot_ckill:1; + u64 lboot_pf_flr:4; + u64 lboot_oci:3; + u64 pnr_mul:6; + u64 reserved_39:1; + u64 c_mul:7; + u64 reserved_47_54:8; + u64 dis_scan:1; + u64 dis_huk:1; + u64 vrm_err:1; + u64 jt_tstmode:1; + u64 ckill_ppdis:1; + u64 trusted_mode:1; + u64 ejtagdis:1; + u64 jtcsrdis:1; + u64 chipkill:1; +#endif /* Word 0 - End */ + } s; + struct cavm_rst_boot_cn81xx { +#if __BYTE_ORDER == __BIG_ENDIAN /* Word 0 - Big Endian */ + u64 chipkill:1; + u64 jtcsrdis:1; + u64 ejtagdis:1; + u64 trusted_mode:1; + u64 ckill_ppdis:1; + u64 jt_tstmode:1; + u64 vrm_err:1; + u64 dis_huk:1; + u64 dis_scan:1; + u64 reserved_47_54:8; + u64 c_mul:7; + u64 reserved_39:1; + u64 pnr_mul:6; + u64 lboot_oci:3; + u64 reserved_26_29:4; + u64 lboot_ckill:1; + u64 lboot_jtg:1; + u64 lboot_ext45:6; + u64 lboot_ext23:6; + u64 lboot:10; + u64 rboot:1; + u64 rboot_pin:1; +#else /* Word 0 - Little Endian */ + u64 rboot_pin:1; + u64 rboot:1; + u64 lboot:10; + u64 lboot_ext23:6; + u64 lboot_ext45:6; + u64 lboot_jtg:1; + u64 lboot_ckill:1; + u64 reserved_26_29:4; + u64 lboot_oci:3; + u64 pnr_mul:6; + u64 reserved_39:1; + u64 c_mul:7; + u64 reserved_47_54:8; + u64 dis_scan:1; + u64 dis_huk:1; + u64 vrm_err:1; + u64 jt_tstmode:1; + u64 ckill_ppdis:1; + u64 trusted_mode:1; + u64 ejtagdis:1; + u64 jtcsrdis:1; + u64 chipkill:1; +#endif /* Word 0 - End */ + } cn81xx; + struct cavm_rst_boot_cn88xx { +#if __BYTE_ORDER == __BIG_ENDIAN /* Word 0 - Big Endian */ + u64 chipkill:1; + u64 jtcsrdis:1; + u64 ejtagdis:1; + u64 trusted_mode:1; + u64 ckill_ppdis:1; + u64 jt_tstmode:1; + u64 vrm_err:1; + u64 dis_huk:1; + u64 dis_scan:1; + u64 reserved_47_54:8; + u64 c_mul:7; + u64 reserved_39:1; + u64 pnr_mul:6; + u64 lboot_oci:3; + u64 reserved_26_29:4; + u64 reserved_24_25:2; + u64 lboot_ext45:6; + u64 lboot_ext23:6; + u64 lboot:10; + u64 rboot:1; + u64 rboot_pin:1; +#else /* Word 0 - Little Endian */ + u64 rboot_pin:1; + u64 rboot:1; + u64 lboot:10; + u64 lboot_ext23:6; + u64 lboot_ext45:6; + u64 reserved_24_25:2; + u64 reserved_26_29:4; + u64 lboot_oci:3; + u64 pnr_mul:6; + u64 reserved_39:1; + u64 c_mul:7; + u64 reserved_47_54:8; + u64 dis_scan:1; + u64 dis_huk:1; + u64 vrm_err:1; + u64 jt_tstmode:1; + u64 ckill_ppdis:1; + u64 trusted_mode:1; + u64 ejtagdis:1; + u64 jtcsrdis:1; + u64 chipkill:1; +#endif /* Word 0 - End */ + } cn88xx; + struct cavm_rst_boot_cn83xx { +#if __BYTE_ORDER == __BIG_ENDIAN /* Word 0 - Big Endian */ + u64 chipkill:1; + u64 jtcsrdis:1; + u64 ejtagdis:1; + u64 trusted_mode:1; + u64 ckill_ppdis:1; + u64 jt_tstmode:1; + u64 vrm_err:1; + u64 dis_huk:1; + u64 dis_scan:1; + u64 reserved_47_54:8; + u64 c_mul:7; + u64 reserved_39:1; + u64 pnr_mul:6; + u64 lboot_oci:3; + u64 lboot_pf_flr:4; + u64 lboot_ckill:1; + u64 lboot_jtg:1; + u64 lboot_ext45:6; + u64 lboot_ext23:6; + u64 lboot:10; + u64 rboot:1; + u64 rboot_pin:1; +#else /* Word 0 - Little Endian */ + u64 rboot_pin:1; + u64 rboot:1; + u64 lboot:10; + u64 lboot_ext23:6; + u64 lboot_ext45:6; + u64 lboot_jtg:1; + u64 lboot_ckill:1; + u64 lboot_pf_flr:4; + u64 lboot_oci:3; + u64 pnr_mul:6; + u64 reserved_39:1; + u64 c_mul:7; + u64 reserved_47_54:8; + u64 dis_scan:1; + u64 dis_huk:1; + u64 vrm_err:1; + u64 jt_tstmode:1; + u64 ckill_ppdis:1; + u64 trusted_mode:1; + u64 ejtagdis:1; + u64 jtcsrdis:1; + u64 chipkill:1; +#endif /* Word 0 - End */ + } cn83xx; +}; + +/** + * Returns the I/O clock speed in Hz + */ +u64 thunderx_get_io_clock(void); + +/** + * Returns the core clock speed in Hz + */ +u64 thunderx_get_core_clock(void); + +#endif diff --git a/arch/arm/mach-thunderx/Makefile b/arch/arm/mach-thunderx/Makefile index fb457cb3e0..b3328f4e08 100644 --- a/arch/arm/mach-thunderx/Makefile +++ b/arch/arm/mach-thunderx/Makefile @@ -1,2 +1,2 @@ # SPDX-License-Identifier: GPL-2.0+ -obj-y := atf.o lowlevel_init.o fdt.o +obj-y := atf.o lowlevel_init.o fdt.o misc.o diff --git a/arch/arm/mach-thunderx/misc.c b/arch/arm/mach-thunderx/misc.c new file mode 100644 index 0000000000..25ac154a9a --- /dev/null +++ b/arch/arm/mach-thunderx/misc.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018, Cavium Inc. + */ + +#include + +#include +#include + +/** + * Returns the I/O clock speed in Hz + */ +u64 thunderx_get_io_clock(void) +{ + union cavm_rst_boot rst_boot; + + rst_boot.u = readq(CAVM_RST_BOOT); + + return rst_boot.s.pnr_mul * PLL_REF_CLK; +} + +/** + * Returns the core clock speed in Hz + */ +u64 thunderx_get_core_clock(void) +{ + union cavm_rst_boot rst_boot; + + rst_boot.u = readq(CAVM_RST_BOOT); + + return rst_boot.s.c_mul * PLL_REF_CLK; +} -- 2.17.1