diff mbox series

[v4,03/52] common/cnxk: add model init and IO handling API

Message ID 20210406114131.25874-4-ndabilpuram@marvell.com (mailing list archive)
State Superseded, archived
Delegated to: Jerin Jacob
Headers show
Series Add Marvell CNXK common driver | expand

Checks

Context Check Description
ci/checkpatch warning coding style issues

Commit Message

Nithin Kumar Dabilpuram April 6, 2021, 11:40 a.m. UTC
From: Jerin Jacob <jerinj@marvell.com>

Add routines for SoC model identification and HW IO handling
routines specific to CN9K and CN10K Marvell SoC's.
These are based on arm64 ISA and behaviour specific to
Marvell SoC's.

Signed-off-by: Jerin Jacob <jerinj@marvell.com>
Signed-off-by: Srikanth Yalavarthi <syalavarthi@marvell.com>
---
 drivers/common/cnxk/meson.build      |   4 +-
 drivers/common/cnxk/roc_api.h        |  13 +++
 drivers/common/cnxk/roc_io.h         | 187 ++++++++++++++++++++++++++++++++
 drivers/common/cnxk/roc_io_generic.h | 122 +++++++++++++++++++++
 drivers/common/cnxk/roc_model.c      | 204 +++++++++++++++++++++++++++++++++++
 drivers/common/cnxk/roc_model.h      | 128 ++++++++++++++++++++++
 drivers/common/cnxk/roc_platform.c   |  28 +++++
 drivers/common/cnxk/roc_platform.h   |  10 ++
 drivers/common/cnxk/roc_priv.h       |  11 ++
 drivers/common/cnxk/roc_util_priv.h  |  14 +++
 drivers/common/cnxk/roc_utils.c      |  35 ++++++
 drivers/common/cnxk/roc_utils.h      |  13 +++
 drivers/common/cnxk/version.map      |   5 +
 13 files changed, 773 insertions(+), 1 deletion(-)
 create mode 100644 drivers/common/cnxk/roc_io.h
 create mode 100644 drivers/common/cnxk/roc_io_generic.h
 create mode 100644 drivers/common/cnxk/roc_model.c
 create mode 100644 drivers/common/cnxk/roc_model.h
 create mode 100644 drivers/common/cnxk/roc_priv.h
 create mode 100644 drivers/common/cnxk/roc_util_priv.h
 create mode 100644 drivers/common/cnxk/roc_utils.c
 create mode 100644 drivers/common/cnxk/roc_utils.h
diff mbox series

Patch

diff --git a/drivers/common/cnxk/meson.build b/drivers/common/cnxk/meson.build
index d1160e6..b0c02ce 100644
--- a/drivers/common/cnxk/meson.build
+++ b/drivers/common/cnxk/meson.build
@@ -10,5 +10,7 @@  endif
 
 config_flag_fmt = 'RTE_LIBRTE_@0@_COMMON'
 deps = ['eal', 'pci', 'bus_pci', 'mbuf']
-sources = files('roc_platform.c')
+sources = files('roc_model.c',
+		'roc_platform.c',
+		'roc_utils.c')
 includes += include_directories('../../bus/pci')
diff --git a/drivers/common/cnxk/roc_api.h b/drivers/common/cnxk/roc_api.h
index ec4ea24..70d9c4a 100644
--- a/drivers/common/cnxk/roc_api.h
+++ b/drivers/common/cnxk/roc_api.h
@@ -29,6 +29,13 @@ 
 #define ROC_LMT_BASE_PER_CORE_LOG2                                             \
 	(ROC_LMT_LINES_PER_CORE_LOG2 + ROC_LMT_LINE_SIZE_LOG2)
 
+/* IO */
+#if defined(__aarch64__)
+#include "roc_io.h"
+#else
+#include "roc_io_generic.h"
+#endif
+
 /* PCI IDs */
 #define PCI_VENDOR_ID_CAVIUM	      0x177D
 #define PCI_DEVID_CNXK_RVU_PF	      0xA063
@@ -66,4 +73,10 @@ 
 #include "hw/ssow.h"
 #include "hw/tim.h"
 
+/* Model */
+#include "roc_model.h"
+
+/* Utils */
+#include "roc_utils.h"
+
 #endif /* _ROC_API_H_ */
diff --git a/drivers/common/cnxk/roc_io.h b/drivers/common/cnxk/roc_io.h
new file mode 100644
index 0000000..fb3d9c5
--- /dev/null
+++ b/drivers/common/cnxk/roc_io.h
@@ -0,0 +1,187 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#ifndef _ROC_IO_H_
+#define _ROC_IO_H_
+
+#define ROC_LMT_BASE_ID_GET(lmt_addr, lmt_id)                                  \
+	do {                                                                   \
+		/* 32 Lines per core */                                        \
+		lmt_id = plt_lcore_id() << ROC_LMT_LINES_PER_CORE_LOG2;        \
+		/* Each line is of 128B */                                     \
+		(lmt_addr) += ((uint64_t)lmt_id << ROC_LMT_LINE_SIZE_LOG2);    \
+	} while (0)
+
+#define roc_load_pair(val0, val1, addr)                                        \
+	({                                                                     \
+		asm volatile("ldp %x[x0], %x[x1], [%x[p1]]"                    \
+			     : [x0] "=r"(val0), [x1] "=r"(val1)                \
+			     : [p1] "r"(addr));                                \
+	})
+
+#define roc_store_pair(val0, val1, addr)                                       \
+	({                                                                     \
+		asm volatile(                                                  \
+			"stp %x[x0], %x[x1], [%x[p1], #0]!" ::[x0] "r"(val0),  \
+			[x1] "r"(val1), [p1] "r"(addr));                       \
+	})
+
+#define roc_prefetch_store_keep(ptr)                                           \
+	({ asm volatile("prfm pstl1keep, [%x0]\n" : : "r"(ptr)); })
+
+#if defined(__clang__)
+static __plt_always_inline void
+roc_atomic128_cas_noreturn(uint64_t swap0, uint64_t swap1, int64_t *ptr)
+{
+	register uint64_t x0 __asm("x0") = swap0;
+	register uint64_t x1 __asm("x1") = swap1;
+
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE
+		     "casp %[x0], %[x1], %[x0], %[x1], [%[ptr]]\n"
+		     : [x0] "+r"(x0), [x1] "+r"(x1)
+		     : [ptr] "r"(ptr)
+		     : "memory");
+}
+#else
+static __plt_always_inline void
+roc_atomic128_cas_noreturn(uint64_t swap0, uint64_t swap1, uint64_t ptr)
+{
+	__uint128_t wdata = swap0 | ((__uint128_t)swap1 << 64);
+
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE
+		     "casp %[wdata], %H[wdata], %[wdata], %H[wdata], [%[ptr]]\n"
+		     : [wdata] "+r"(wdata)
+		     : [ptr] "r"(ptr)
+		     : "memory");
+}
+#endif
+
+static __plt_always_inline uint64_t
+roc_atomic64_cas(uint64_t compare, uint64_t swap, int64_t *ptr)
+{
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE
+		     "cas %[compare], %[swap], [%[ptr]]\n"
+		     : [compare] "+r"(compare)
+		     : [swap] "r"(swap), [ptr] "r"(ptr)
+		     : "memory");
+
+	return compare;
+}
+
+static __plt_always_inline uint64_t
+roc_atomic64_add_nosync(int64_t incr, int64_t *ptr)
+{
+	uint64_t result;
+
+	/* Atomic add with no ordering */
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE "ldadd %x[i], %x[r], [%[b]]"
+		     : [r] "=r"(result), "+m"(*ptr)
+		     : [i] "r"(incr), [b] "r"(ptr)
+		     : "memory");
+	return result;
+}
+
+static __plt_always_inline uint64_t
+roc_atomic64_add_sync(int64_t incr, int64_t *ptr)
+{
+	uint64_t result;
+
+	/* Atomic add with ordering */
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE "ldadda %x[i], %x[r], [%[b]]"
+		     : [r] "=r"(result), "+m"(*ptr)
+		     : [i] "r"(incr), [b] "r"(ptr)
+		     : "memory");
+	return result;
+}
+
+static __plt_always_inline uint64_t
+roc_lmt_submit_ldeor(plt_iova_t io_address)
+{
+	uint64_t result;
+
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE "ldeor xzr, %x[rf], [%[rs]]"
+		     : [rf] "=r"(result)
+		     : [rs] "r"(io_address));
+	return result;
+}
+
+static __plt_always_inline uint64_t
+roc_lmt_submit_ldeorl(plt_iova_t io_address)
+{
+	uint64_t result;
+
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE "ldeorl xzr,%x[rf],[%[rs]]"
+		     : [rf] "=r"(result)
+		     : [rs] "r"(io_address));
+	return result;
+}
+
+static __plt_always_inline void
+roc_lmt_submit_steor(uint64_t data, plt_iova_t io_address)
+{
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE
+		     "steor %x[d], [%[rs]]" ::[d] "r"(data),
+		     [rs] "r"(io_address));
+}
+
+static __plt_always_inline void
+roc_lmt_submit_steorl(uint64_t data, plt_iova_t io_address)
+{
+	asm volatile(PLT_CPU_FEATURE_PREAMBLE
+		     "steorl %x[d], [%[rs]]" ::[d] "r"(data),
+		     [rs] "r"(io_address));
+}
+
+static __plt_always_inline void
+roc_lmt_mov(void *out, const void *in, const uint32_t lmtext)
+{
+	volatile const __uint128_t *src128 = (const __uint128_t *)in;
+	volatile __uint128_t *dst128 = (__uint128_t *)out;
+
+	dst128[0] = src128[0];
+	dst128[1] = src128[1];
+	/* lmtext receives following value:
+	 * 1: NIX_SUBDC_EXT needed i.e. tx vlan case
+	 * 2: NIX_SUBDC_EXT + NIX_SUBDC_MEM i.e. tstamp case
+	 */
+	if (lmtext) {
+		dst128[2] = src128[2];
+		if (lmtext > 1)
+			dst128[3] = src128[3];
+	}
+}
+
+static __plt_always_inline void
+roc_lmt_mov_seg(void *out, const void *in, const uint16_t segdw)
+{
+	volatile const __uint128_t *src128 = (const __uint128_t *)in;
+	volatile __uint128_t *dst128 = (__uint128_t *)out;
+	uint8_t i;
+
+	for (i = 0; i < segdw; i++)
+		dst128[i] = src128[i];
+}
+
+static __plt_always_inline void
+roc_lmt_mov_one(void *out, const void *in)
+{
+	volatile const __uint128_t *src128 = (const __uint128_t *)in;
+	volatile __uint128_t *dst128 = (__uint128_t *)out;
+
+	*dst128 = *src128;
+}
+
+/* Non volatile version of roc_lmt_mov_seg() */
+static __plt_always_inline void
+roc_lmt_mov_seg_nv(void *out, const void *in, const uint16_t segdw)
+{
+	const __uint128_t *src128 = (const __uint128_t *)in;
+	__uint128_t *dst128 = (__uint128_t *)out;
+	uint8_t i;
+
+	for (i = 0; i < segdw; i++)
+		dst128[i] = src128[i];
+}
+
+#endif /* _ROC_IO_H_ */
diff --git a/drivers/common/cnxk/roc_io_generic.h b/drivers/common/cnxk/roc_io_generic.h
new file mode 100644
index 0000000..c1689b6
--- /dev/null
+++ b/drivers/common/cnxk/roc_io_generic.h
@@ -0,0 +1,122 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#ifndef _ROC_IO_GENERIC_H_
+#define _ROC_IO_GENERIC_H_
+
+#define ROC_LMT_BASE_ID_GET(lmt_addr, lmt_id) (lmt_id = 0)
+
+#define roc_load_pair(val0, val1, addr)                                        \
+	do {                                                                   \
+		val0 = plt_read64((void *)(addr));                             \
+		val1 = plt_read64((uint8_t *)(addr) + 8);                      \
+	} while (0)
+
+#define roc_store_pair(val0, val1, addr)                                       \
+	do {                                                                   \
+		plt_write64(val0, (void *)(addr));                             \
+		plt_write64(val1, (((uint8_t *)(addr)) + 8));                  \
+	} while (0)
+
+#define roc_prefetch_store_keep(ptr)                                           \
+	do {                                                                   \
+	} while (0)
+
+static __plt_always_inline void
+roc_atomic128_cas_noreturn(uint64_t swap0, uint64_t swap1, uint64_t ptr)
+{
+	PLT_SET_USED(swap0);
+	PLT_SET_USED(swap1);
+	PLT_SET_USED(ptr);
+}
+
+static __plt_always_inline uint64_t
+roc_atomic64_cas(uint64_t compare, uint64_t swap, int64_t *ptr)
+{
+	PLT_SET_USED(swap);
+	PLT_SET_USED(ptr);
+
+	return compare;
+}
+
+static inline uint64_t
+roc_atomic64_add_nosync(int64_t incr, int64_t *ptr)
+{
+	PLT_SET_USED(ptr);
+	PLT_SET_USED(incr);
+
+	return 0;
+}
+
+static inline uint64_t
+roc_atomic64_add_sync(int64_t incr, int64_t *ptr)
+{
+	PLT_SET_USED(ptr);
+	PLT_SET_USED(incr);
+
+	return 0;
+}
+
+static inline uint64_t
+roc_lmt_submit_ldeor(plt_iova_t io_address)
+{
+	PLT_SET_USED(io_address);
+
+	return 0;
+}
+
+static __plt_always_inline uint64_t
+roc_lmt_submit_ldeorl(plt_iova_t io_address)
+{
+	PLT_SET_USED(io_address);
+
+	return 0;
+}
+
+static inline void
+roc_lmt_submit_steor(uint64_t data, plt_iova_t io_address)
+{
+	PLT_SET_USED(data);
+	PLT_SET_USED(io_address);
+}
+
+static inline void
+roc_lmt_submit_steorl(uint64_t data, plt_iova_t io_address)
+{
+	PLT_SET_USED(data);
+	PLT_SET_USED(io_address);
+}
+
+static __plt_always_inline void
+roc_lmt_mov(void *out, const void *in, const uint32_t lmtext)
+{
+	PLT_SET_USED(in);
+	PLT_SET_USED(lmtext);
+	memset(out, 0, sizeof(__uint128_t) * (lmtext ? lmtext > 1 ? 4 : 3 : 2));
+}
+
+static __plt_always_inline void
+roc_lmt_mov_seg(void *out, const void *in, const uint16_t segdw)
+{
+	PLT_SET_USED(out);
+	PLT_SET_USED(in);
+	PLT_SET_USED(segdw);
+}
+
+static __plt_always_inline void
+roc_lmt_mov_one(void *out, const void *in)
+{
+	PLT_SET_USED(out);
+	PLT_SET_USED(in);
+}
+
+static __plt_always_inline void
+roc_lmt_mov_seg_nv(void *out, const void *in, const uint16_t segdw)
+{
+	PLT_SET_USED(out);
+	PLT_SET_USED(in);
+	PLT_SET_USED(segdw);
+}
+
+#endif /* _ROC_IO_GENERIC_H_ */
diff --git a/drivers/common/cnxk/roc_model.c b/drivers/common/cnxk/roc_model.c
new file mode 100644
index 0000000..bc255b5
--- /dev/null
+++ b/drivers/common/cnxk/roc_model.c
@@ -0,0 +1,204 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#include "roc_api.h"
+#include "roc_priv.h"
+
+struct roc_model *roc_model;
+
+/* RoC and CPU IDs and revisions */
+#define VENDOR_ARM    0x41 /* 'A' */
+#define VENDOR_CAVIUM 0x43 /* 'C' */
+
+#define SOC_PART_CN10K 0xD49
+
+#define PART_106XX  0xB9
+#define PART_105XX  0xBA
+#define PART_105XXN 0xBC
+#define PART_98XX   0xB1
+#define PART_96XX   0xB2
+#define PART_95XX   0xB3
+#define PART_95XXN  0xB4
+#define PART_95XXMM 0xB5
+#define PART_95O    0xB6
+
+#define MODEL_IMPL_BITS	  8
+#define MODEL_IMPL_SHIFT  24
+#define MODEL_IMPL_MASK	  ((1 << MODEL_IMPL_BITS) - 1)
+#define MODEL_PART_BITS	  12
+#define MODEL_PART_SHIFT  4
+#define MODEL_PART_MASK	  ((1 << MODEL_PART_BITS) - 1)
+#define MODEL_MAJOR_BITS  4
+#define MODEL_MAJOR_SHIFT 20
+#define MODEL_MAJOR_MASK  ((1 << MODEL_MAJOR_BITS) - 1)
+#define MODEL_MINOR_BITS  4
+#define MODEL_MINOR_SHIFT 0
+#define MODEL_MINOR_MASK  ((1 << MODEL_MINOR_BITS) - 1)
+
+static const struct model_db {
+	uint32_t impl;
+	uint32_t part;
+	uint32_t major;
+	uint32_t minor;
+	uint64_t flag;
+	char name[ROC_MODEL_STR_LEN_MAX];
+} model_db[] = {
+	{VENDOR_ARM, PART_106XX, 0, 0, ROC_MODEL_CN106XX, "cn10ka"},
+	{VENDOR_ARM, PART_105XX, 0, 0, ROC_MODEL_CNF105XX, "cnf10ka"},
+	{VENDOR_ARM, PART_105XXN, 0, 0, ROC_MODEL_CNF105XXN, "cnf10kb"},
+	{VENDOR_CAVIUM, PART_98XX, 0, 0, ROC_MODEL_CN98xx_A0, "cn98xx_a0"},
+	{VENDOR_CAVIUM, PART_96XX, 0, 0, ROC_MODEL_CN96xx_A0, "cn96xx_a0"},
+	{VENDOR_CAVIUM, PART_96XX, 0, 1, ROC_MODEL_CN96xx_B0, "cn96xx_b0"},
+	{VENDOR_CAVIUM, PART_96XX, 2, 0, ROC_MODEL_CN96xx_C0, "cn96xx_c0"},
+	{VENDOR_CAVIUM, PART_95XX, 0, 0, ROC_MODEL_CNF95xx_A0, "cnf95xx_a0"},
+	{VENDOR_CAVIUM, PART_95XX, 1, 0, ROC_MODEL_CNF95xx_B0, "cnf95xx_b0"},
+	{VENDOR_CAVIUM, PART_95XXN, 0, 0, ROC_MODEL_CNF95XXN_A0, "cnf95xxn_a0"},
+	{VENDOR_CAVIUM, PART_95O, 0, 0, ROC_MODEL_CNF95XXO_A0, "cnf95O_a0"},
+	{VENDOR_CAVIUM, PART_95XXMM, 0, 0, ROC_MODEL_CNF95XXMM_A0,
+	 "cnf95xxmm_a0"}
+};
+
+static uint32_t
+cn10k_part_get(void)
+{
+	uint32_t soc = 0x0;
+	char buf[BUFSIZ];
+	char *ptr;
+	FILE *fd;
+
+	/* Read the CPU compatible variant */
+	fd = fopen("/proc/device-tree/compatible", "r");
+	if (!fd) {
+		plt_err("Failed to open /proc/device-tree/compatible");
+		goto err;
+	}
+
+	if (fgets(buf, sizeof(buf), fd) == NULL) {
+		plt_err("Failed to read from /proc/device-tree/compatible");
+		goto fclose;
+	}
+	ptr = strchr(buf, ',');
+	if (!ptr) {
+		plt_err("Malformed 'CPU compatible': <%s>", buf);
+		goto fclose;
+	}
+	ptr++;
+	if (strcmp("cn10ka", ptr) == 0) {
+		soc = PART_106XX;
+	} else if (strcmp("cnf10ka", ptr) == 0) {
+		soc = PART_105XX;
+	} else if (strcmp("cnf10kb", ptr) == 0) {
+		soc = PART_105XXN;
+	} else {
+		plt_err("Unidentified 'CPU compatible': <%s>", ptr);
+		goto fclose;
+	}
+
+fclose:
+	fclose(fd);
+
+err:
+	return soc;
+}
+
+static bool
+populate_model(struct roc_model *model, uint32_t midr)
+{
+	uint32_t impl, major, part, minor;
+	bool found = false;
+	size_t i;
+
+	impl = (midr >> MODEL_IMPL_SHIFT) & MODEL_IMPL_MASK;
+	part = (midr >> MODEL_PART_SHIFT) & MODEL_PART_MASK;
+	major = (midr >> MODEL_MAJOR_SHIFT) & MODEL_MAJOR_MASK;
+	minor = (midr >> MODEL_MINOR_SHIFT) & MODEL_MINOR_MASK;
+
+	/* Update part number for cn10k from device-tree */
+	if (part == SOC_PART_CN10K)
+		part = cn10k_part_get();
+
+	for (i = 0; i < PLT_DIM(model_db); i++)
+		if (model_db[i].impl == impl && model_db[i].part == part &&
+		    model_db[i].major == major && model_db[i].minor == minor) {
+			model->flag = model_db[i].flag;
+			strncpy(model->name, model_db[i].name,
+				ROC_MODEL_STR_LEN_MAX - 1);
+			found = true;
+			break;
+		}
+
+	if (!found) {
+		model->flag = 0;
+		strncpy(model->name, "unknown", ROC_MODEL_STR_LEN_MAX - 1);
+		plt_err("Invalid RoC model (impl=0x%x, part=0x%x)", impl, part);
+	}
+
+	return found;
+}
+
+static int
+midr_get(unsigned long *val)
+{
+	const char *file =
+		"/sys/devices/system/cpu/cpu0/regs/identification/midr_el1";
+	int rc = UTIL_ERR_FS;
+	char buf[BUFSIZ];
+	char *end = NULL;
+	FILE *f;
+
+	if (val == NULL)
+		goto err;
+	f = fopen(file, "r");
+	if (f == NULL)
+		goto err;
+
+	if (fgets(buf, sizeof(buf), f) == NULL)
+		goto fclose;
+
+	*val = strtoul(buf, &end, 0);
+	if ((buf[0] == '\0') || (end == NULL) || (*end != '\n'))
+		goto fclose;
+
+	rc = 0;
+fclose:
+	fclose(f);
+err:
+	return rc;
+}
+
+static void
+detect_invalid_config(void)
+{
+#ifdef ROC_PLATFORM_CN9K
+#ifdef ROC_PLATFORM_CN10K
+	PLT_STATIC_ASSERT(0);
+#endif
+#endif
+}
+
+int
+roc_model_init(struct roc_model *model)
+{
+	int rc = UTIL_ERR_PARAM;
+	unsigned long midr;
+
+	detect_invalid_config();
+
+	if (!model)
+		goto err;
+
+	rc = midr_get(&midr);
+	if (rc)
+		goto err;
+
+	rc = UTIL_ERR_INVALID_MODEL;
+	if (!populate_model(model, midr))
+		goto err;
+
+	rc = 0;
+	plt_info("RoC Model: %s", model->name);
+	roc_model = model;
+err:
+	return rc;
+}
diff --git a/drivers/common/cnxk/roc_model.h b/drivers/common/cnxk/roc_model.h
new file mode 100644
index 0000000..fb774ac
--- /dev/null
+++ b/drivers/common/cnxk/roc_model.h
@@ -0,0 +1,128 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#ifndef _ROC_MODEL_H_
+#define _ROC_MODEL_H_
+
+#include <stdbool.h>
+
+extern struct roc_model *roc_model;
+
+struct roc_model {
+#define ROC_MODEL_CN96xx_A0    BIT_ULL(0)
+#define ROC_MODEL_CN96xx_B0    BIT_ULL(1)
+#define ROC_MODEL_CN96xx_C0    BIT_ULL(2)
+#define ROC_MODEL_CNF95xx_A0   BIT_ULL(4)
+#define ROC_MODEL_CNF95xx_B0   BIT_ULL(6)
+#define ROC_MODEL_CNF95XXMM_A0 BIT_ULL(8)
+#define ROC_MODEL_CNF95XXN_A0  BIT_ULL(12)
+#define ROC_MODEL_CNF95XXO_A0  BIT_ULL(13)
+#define ROC_MODEL_CN98xx_A0    BIT_ULL(16)
+#define ROC_MODEL_CN106XX      BIT_ULL(20)
+#define ROC_MODEL_CNF105XX     BIT_ULL(21)
+#define ROC_MODEL_CNF105XXN    BIT_ULL(22)
+
+	uint64_t flag;
+#define ROC_MODEL_STR_LEN_MAX 128
+	char name[ROC_MODEL_STR_LEN_MAX];
+} __plt_cache_aligned;
+
+#define ROC_MODEL_CN96xx_Ax (ROC_MODEL_CN96xx_A0 | ROC_MODEL_CN96xx_B0)
+#define ROC_MODEL_CN9K                                                         \
+	(ROC_MODEL_CN96xx_Ax | ROC_MODEL_CN96xx_C0 | ROC_MODEL_CNF95xx_A0 |    \
+	 ROC_MODEL_CNF95xx_B0 | ROC_MODEL_CNF95XXMM_A0 |                       \
+	 ROC_MODEL_CNF95XXO_A0 | ROC_MODEL_CNF95XXN_A0 | ROC_MODEL_CN98xx_A0)
+
+#define ROC_MODEL_CN10K                                                        \
+	(ROC_MODEL_CN106XX | ROC_MODEL_CNF105XX | ROC_MODEL_CNF105XXN)
+
+/* Runtime variants */
+static inline uint64_t
+roc_model_runtime_is_cn9k(void)
+{
+	return (roc_model->flag & (ROC_MODEL_CN9K));
+}
+
+static inline uint64_t
+roc_model_runtime_is_cn10k(void)
+{
+	return (roc_model->flag & (ROC_MODEL_CN10K));
+}
+
+/* Compile time variants */
+#ifdef ROC_PLATFORM_CN9K
+#define roc_model_constant_is_cn9k()  1
+#define roc_model_constant_is_cn10k() 0
+#else
+#define roc_model_constant_is_cn9k()  0
+#define roc_model_constant_is_cn10k() 1
+#endif
+
+/*
+ * Compile time variants to enable optimized version check when the library
+ * configured for specific platform version else to fallback to runtime.
+ */
+static inline uint64_t
+roc_model_is_cn9k(void)
+{
+#ifdef ROC_PLATFORM_CN9K
+	return 1;
+#endif
+#ifdef ROC_PLATFORM_CN10K
+	return 0;
+#endif
+	return roc_model_runtime_is_cn9k();
+}
+
+static inline uint64_t
+roc_model_is_cn10k(void)
+{
+#ifdef ROC_PLATFORM_CN10K
+	return 1;
+#endif
+#ifdef ROC_PLATFORM_CN9K
+	return 0;
+#endif
+	return roc_model_runtime_is_cn10k();
+}
+
+static inline uint64_t
+roc_model_is_cn96_A0(void)
+{
+	return roc_model->flag & ROC_MODEL_CN96xx_A0;
+}
+
+static inline uint64_t
+roc_model_is_cn96_Ax(void)
+{
+	return (roc_model->flag & ROC_MODEL_CN96xx_Ax);
+}
+
+static inline uint64_t
+roc_model_is_cn95_A0(void)
+{
+	return roc_model->flag & ROC_MODEL_CNF95xx_A0;
+}
+
+static inline uint64_t
+roc_model_is_cn10ka(void)
+{
+	return roc_model->flag & ROC_MODEL_CN106XX;
+}
+
+static inline uint64_t
+roc_model_is_cnf10ka(void)
+{
+	return roc_model->flag & ROC_MODEL_CNF105XX;
+}
+
+static inline uint64_t
+roc_model_is_cnf10kb(void)
+{
+	return roc_model->flag & ROC_MODEL_CNF105XXN;
+}
+
+int roc_model_init(struct roc_model *model);
+
+#endif
diff --git a/drivers/common/cnxk/roc_platform.c b/drivers/common/cnxk/roc_platform.c
index 6ddbc3b..5baec95 100644
--- a/drivers/common/cnxk/roc_platform.c
+++ b/drivers/common/cnxk/roc_platform.c
@@ -3,3 +3,31 @@ 
  */
 
 #include "roc_api.h"
+
+int
+roc_plt_init(void)
+{
+	const struct rte_memzone *mz;
+
+	mz = rte_memzone_lookup(PLT_MODEL_MZ_NAME);
+	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+		if (mz == NULL) {
+			mz = rte_memzone_reserve(PLT_MODEL_MZ_NAME,
+						 sizeof(struct roc_model),
+						 SOCKET_ID_ANY, 0);
+			if (mz == NULL) {
+				plt_err("Failed to reserve mem for roc_model");
+				return -ENOMEM;
+			}
+			roc_model_init(mz->addr);
+		}
+	} else {
+		if (mz == NULL) {
+			plt_err("Failed to lookup mem for roc_model");
+			return -ENOMEM;
+		}
+		roc_model = mz->addr;
+	}
+
+	return 0;
+}
diff --git a/drivers/common/cnxk/roc_platform.h b/drivers/common/cnxk/roc_platform.h
index 6d498b2..1d06435 100644
--- a/drivers/common/cnxk/roc_platform.h
+++ b/drivers/common/cnxk/roc_platform.h
@@ -131,6 +131,13 @@ 
 
 #define plt_strlcpy rte_strlcpy
 
+/* Log */
+#define plt_err(fmt, args...)                                                  \
+	RTE_LOG(ERR, PMD, "%s():%u " fmt "\n", __func__, __LINE__, ##args)
+#define plt_info(fmt, args...) RTE_LOG(INFO, PMD, fmt "\n", ##args)
+#define plt_warn(fmt, args...) RTE_LOG(WARNING, PMD, fmt "\n", ##args)
+#define plt_print(fmt, args...) RTE_LOG(INFO, PMD, fmt "\n", ##args)
+
 #ifdef __cplusplus
 #define CNXK_PCI_ID(subsystem_dev, dev)				\
 	{							\
@@ -151,4 +158,7 @@ 
 	}
 #endif
 
+__rte_internal
+int roc_plt_init(void);
+
 #endif /* _ROC_PLATFORM_H_ */
diff --git a/drivers/common/cnxk/roc_priv.h b/drivers/common/cnxk/roc_priv.h
new file mode 100644
index 0000000..9c905d4
--- /dev/null
+++ b/drivers/common/cnxk/roc_priv.h
@@ -0,0 +1,11 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#ifndef _ROC_PRIV_H_
+#define _ROC_PRIV_H_
+
+/* Utils */
+#include "roc_util_priv.h"
+
+#endif /* _ROC_PRIV_H_ */
diff --git a/drivers/common/cnxk/roc_util_priv.h b/drivers/common/cnxk/roc_util_priv.h
new file mode 100644
index 0000000..abad5c4
--- /dev/null
+++ b/drivers/common/cnxk/roc_util_priv.h
@@ -0,0 +1,14 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#ifndef _ROC_UTIL_PRIV_H_
+#define _ROC_UTIL_PRIV_H_
+
+enum util_err_status {
+	UTIL_ERR_PARAM = -6000,
+	UTIL_ERR_FS,
+	UTIL_ERR_INVALID_MODEL,
+};
+
+#endif /* _ROC_UTIL_PRIV_H_ */
diff --git a/drivers/common/cnxk/roc_utils.c b/drivers/common/cnxk/roc_utils.c
new file mode 100644
index 0000000..c48f027
--- /dev/null
+++ b/drivers/common/cnxk/roc_utils.c
@@ -0,0 +1,35 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#include "roc_api.h"
+#include "roc_priv.h"
+
+const char *
+roc_error_msg_get(int errorcode)
+{
+	const char *err_msg;
+
+	switch (errorcode) {
+	case UTIL_ERR_PARAM:
+		err_msg = "Invalid parameter";
+		break;
+	case UTIL_ERR_FS:
+		err_msg = "file operation failed";
+		break;
+	case UTIL_ERR_INVALID_MODEL:
+		err_msg = "Invalid RoC model";
+		break;
+	default:
+		/**
+		 * Handle general error (as defined in linux errno.h)
+		 */
+		if (abs(errorcode) < 300)
+			err_msg = strerror(abs(errorcode));
+		else
+			err_msg = "Unknown error code";
+		break;
+	}
+
+	return err_msg;
+}
diff --git a/drivers/common/cnxk/roc_utils.h b/drivers/common/cnxk/roc_utils.h
new file mode 100644
index 0000000..634810e
--- /dev/null
+++ b/drivers/common/cnxk/roc_utils.h
@@ -0,0 +1,13 @@ 
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(C) 2021 Marvell.
+ */
+
+#ifndef _ROC_UTILS_H_
+#define _ROC_UTILS_H_
+
+#include "roc_platform.h"
+
+/* Utils */
+const char *__roc_api roc_error_msg_get(int errorcode);
+
+#endif /* _ROC_UTILS_H_ */
diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
index dc012a1..1798b48 100644
--- a/drivers/common/cnxk/version.map
+++ b/drivers/common/cnxk/version.map
@@ -1,4 +1,9 @@ 
 INTERNAL {
+	global:
+
+	roc_error_msg_get;
+	roc_model;
+	roc_plt_init;
 
 	local: *;
 };