[U-Boot] [RFC 04/22] thunderx: add thunderx register definitions and misc functions

Tim Harvey tharvey at gateworks.com
Fri Feb 22 18:03:01 UTC 2019


Add Cavium Thunderx common registers, structures, and helper functions

Signed-off-by: Tim Harvey <tharvey at gateworks.com>
---
 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 <common.h>
+
+#include <asm/arch-thunderx/thunderx.h>
+#include <asm/io.h>
+
+/**
+ * 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



More information about the U-Boot mailing list