diff --git a/drivers/ml/cnxk/cn10k_ml_ocm.c b/drivers/ml/cnxk/cn10k_ml_ocm.c
index dc315cce10..749ddeb344 100644
--- a/drivers/ml/cnxk/cn10k_ml_ocm.c
+++ b/drivers/ml/cnxk/cn10k_ml_ocm.c
@@ -435,6 +435,9 @@ cn10k_ml_ocm_free_pages(struct cnxk_ml_dev *cnxk_mldev, uint16_t model_id, uint1
 
 			for (j = 0; j < local_model->nb_layers; j++) {
 				local_layer = &local_model->layer[j];
+				if (local_layer->type != ML_CNXK_LAYER_TYPE_MRVL)
+					continue;
+
 				if (local_layer != layer &&
 				    local_layer->glow.ocm_map.ocm_reserved) {
 					if (IS_BIT_SET(local_layer->glow.ocm_map.tilemask, tile_id))
diff --git a/drivers/ml/cnxk/cn10k_ml_ops.c b/drivers/ml/cnxk/cn10k_ml_ops.c
index 65eaaf030d..a471e98fbf 100644
--- a/drivers/ml/cnxk/cn10k_ml_ops.c
+++ b/drivers/ml/cnxk/cn10k_ml_ops.c
@@ -725,6 +725,9 @@ cn10k_ml_model_load(struct cnxk_ml_dev *cnxk_mldev, struct rte_ml_model_params *
 	if (ret != 0)
 		return ret;
 
+	/* Set model sub type */
+	model->subtype = ML_CNXK_MODEL_SUBTYPE_GLOW_MRVL;
+
 	/* Copy metadata to internal buffer */
 	rte_memcpy(&model->glow.metadata, params->addr, sizeof(struct cn10k_ml_model_metadata));
 	cn10k_ml_model_metadata_update(&model->glow.metadata);
@@ -746,6 +749,7 @@ cn10k_ml_model_load(struct cnxk_ml_dev *cnxk_mldev, struct rte_ml_model_params *
 
 	/* Load layer and get the index */
 	layer = &model->layer[0];
+	layer->type = ML_CNXK_LAYER_TYPE_MRVL;
 	ret = cn10k_ml_layer_load(cnxk_mldev, model->model_id, NULL, params->addr, params->size,
 				  &layer->index);
 	if (ret != 0) {
@@ -969,7 +973,7 @@ cn10k_ml_layer_start(void *device, uint16_t model_id, const char *layer_name)
 	if (ret < 0) {
 		cn10k_ml_layer_stop(device, model_id, layer_name);
 	} else {
-		if (cn10k_mldev->cache_model_data)
+		if (cn10k_mldev->cache_model_data && model->type == ML_CNXK_MODEL_TYPE_GLOW)
 			ret = cn10k_ml_cache_model_data(cnxk_mldev, layer);
 	}
 
diff --git a/drivers/ml/cnxk/cnxk_ml_model.h b/drivers/ml/cnxk/cnxk_ml_model.h
index f618e5aa5f..f100eca203 100644
--- a/drivers/ml/cnxk/cnxk_ml_model.h
+++ b/drivers/ml/cnxk/cnxk_ml_model.h
@@ -11,6 +11,10 @@
 
 #include "cn10k_ml_model.h"
 
+#ifdef RTE_MLDEV_CNXK_ENABLE_MVTVM
+#include "mvtvm_ml_model.h"
+#endif
+
 #include "cnxk_ml_io.h"
 
 struct cnxk_ml_dev;
@@ -18,6 +22,48 @@ struct cnxk_ml_model;
 struct cnxk_ml_qp;
 struct cnxk_ml_req;
 
+/* Model type */
+enum cnxk_ml_model_type {
+	/* Unknown model type */
+	ML_CNXK_MODEL_TYPE_UNKNOWN,
+
+	/* Invalid model type */
+	ML_CNXK_MODEL_TYPE_INVALID,
+
+	/* Glow compiled model, for MLIP target */
+	ML_CNXK_MODEL_TYPE_GLOW,
+
+	/* TVM compiled model, for ARM64 / ARM64 + MLIP target */
+	ML_CNXK_MODEL_TYPE_TVM,
+};
+
+/* Model subtype */
+enum cnxk_ml_model_subtype {
+	/* Marvell Glow model */
+	ML_CNXK_MODEL_SUBTYPE_GLOW_MRVL,
+
+	/* TVM model with single MRVL region */
+	ML_CNXK_MODEL_SUBTYPE_TVM_MRVL,
+
+	/* TVM model with LLVM regions only */
+	ML_CNXK_MODEL_SUBTYPE_TVM_LLVM,
+
+	/* TVM hybrid model, with both MRVL and LLVM regions or (> 1) MRVL regions*/
+	ML_CNXK_MODEL_SUBTYPE_TVM_HYBRID,
+};
+
+/* Layer type */
+enum cnxk_ml_layer_type {
+	/* MRVL layer, for MLIP target*/
+	ML_CNXK_LAYER_TYPE_UNKNOWN = 0,
+
+	/* MRVL layer, for MLIP target*/
+	ML_CNXK_LAYER_TYPE_MRVL,
+
+	/* LLVM layer, for ARM64 target*/
+	ML_CNXK_LAYER_TYPE_LLVM,
+};
+
 /* Model state */
 enum cnxk_ml_model_state {
 	/* Unknown state */
@@ -53,6 +99,9 @@ struct cnxk_ml_layer {
 	/* Name*/
 	char name[RTE_ML_STR_MAX];
 
+	/* Type */
+	enum cnxk_ml_layer_type type;
+
 	/* Model handle */
 	struct cnxk_ml_model *model;
 
@@ -83,14 +132,27 @@ struct cnxk_ml_model {
 	/* Device reference */
 	struct cnxk_ml_dev *cnxk_mldev;
 
+	/* Type */
+	enum cnxk_ml_model_type type;
+
+	/* Model subtype */
+	enum cnxk_ml_model_subtype subtype;
+
 	/* ID */
 	uint16_t model_id;
 
 	/* Name */
 	char name[RTE_ML_STR_MAX];
 
-	/* Model specific data - glow */
-	struct cn10k_ml_model_data glow;
+	union {
+		/* Model specific data - glow */
+		struct cn10k_ml_model_data glow;
+
+#ifdef RTE_MLDEV_CNXK_ENABLE_MVTVM
+		/* Model type specific data - mvtvm */
+		struct mvtvm_ml_model_data mvtvm;
+#endif
+	};
 
 	/* Batch size */
 	uint32_t batch_size;
diff --git a/drivers/ml/cnxk/cnxk_ml_ops.c b/drivers/ml/cnxk/cnxk_ml_ops.c
index c3639320a5..ea6f59a70f 100644
--- a/drivers/ml/cnxk/cnxk_ml_ops.c
+++ b/drivers/ml/cnxk/cnxk_ml_ops.c
@@ -1217,6 +1217,8 @@ cnxk_ml_io_quantize(struct rte_ml_dev *dev, uint16_t model_id, struct rte_ml_buf
 	struct cnxk_ml_model *model;
 	uint8_t *lcl_dbuffer;
 	uint8_t *lcl_qbuffer;
+	uint64_t d_offset;
+	uint64_t q_offset;
 	uint32_t i;
 	int ret;
 
@@ -1229,17 +1231,31 @@ cnxk_ml_io_quantize(struct rte_ml_dev *dev, uint16_t model_id, struct rte_ml_buf
 		return -EINVAL;
 	}
 
-	info = &model->layer[0].info;
+	if (model->type == ML_CNXK_MODEL_TYPE_GLOW)
+		info = cn10k_ml_model_io_info_get(model, 0);
 
-	lcl_dbuffer = dbuffer[0]->addr;
-	lcl_qbuffer = qbuffer[0]->addr;
+	if (info == NULL)
+		return -EINVAL;
+
+	d_offset = 0;
+	q_offset = 0;
 	for (i = 0; i < info->nb_inputs; i++) {
+		if (model->type == ML_CNXK_MODEL_TYPE_TVM) {
+			lcl_dbuffer = dbuffer[i]->addr;
+			lcl_qbuffer = qbuffer[i]->addr;
+		} else {
+			lcl_dbuffer = RTE_PTR_ADD(dbuffer[0]->addr, d_offset);
+			lcl_qbuffer = RTE_PTR_ADD(qbuffer[0]->addr, q_offset);
+		}
+
 		ret = cnxk_ml_io_quantize_single(&info->input[i], lcl_dbuffer, lcl_qbuffer);
 		if (ret < 0)
 			return ret;
 
-		lcl_dbuffer += info->input[i].sz_d;
-		lcl_qbuffer += info->input[i].sz_q;
+		if (model->type == ML_CNXK_MODEL_TYPE_GLOW) {
+			d_offset += info->input[i].sz_d;
+			q_offset += info->input[i].sz_q;
+		}
 	}
 
 	return 0;
@@ -1253,6 +1269,8 @@ cnxk_ml_io_dequantize(struct rte_ml_dev *dev, uint16_t model_id, struct rte_ml_b
 	struct cnxk_ml_model *model;
 	uint8_t *lcl_qbuffer;
 	uint8_t *lcl_dbuffer;
+	uint64_t q_offset;
+	uint64_t d_offset;
 	uint32_t i;
 	int ret;
 
@@ -1265,17 +1283,31 @@ cnxk_ml_io_dequantize(struct rte_ml_dev *dev, uint16_t model_id, struct rte_ml_b
 		return -EINVAL;
 	}
 
-	info = &model->layer[model->nb_layers - 1].info;
+	if (model->type == ML_CNXK_MODEL_TYPE_GLOW)
+		info = cn10k_ml_model_io_info_get(model, model->nb_layers - 1);
 
-	lcl_qbuffer = qbuffer[0]->addr;
-	lcl_dbuffer = dbuffer[0]->addr;
+	if (info == NULL)
+		return -EINVAL;
+
+	q_offset = 0;
+	d_offset = 0;
 	for (i = 0; i < info->nb_outputs; i++) {
+		if (model->type == ML_CNXK_MODEL_TYPE_TVM) {
+			lcl_qbuffer = qbuffer[i]->addr;
+			lcl_dbuffer = dbuffer[i]->addr;
+		} else {
+			lcl_qbuffer = RTE_PTR_ADD(qbuffer[0]->addr, q_offset);
+			lcl_dbuffer = RTE_PTR_ADD(dbuffer[0]->addr, d_offset);
+		}
+
 		ret = cnxk_ml_io_dequantize_single(&info->output[i], lcl_qbuffer, lcl_dbuffer);
 		if (ret < 0)
 			return ret;
 
-		lcl_qbuffer += info->output[i].sz_q;
-		lcl_dbuffer += info->output[i].sz_d;
+		if (model->type == ML_CNXK_MODEL_TYPE_GLOW) {
+			q_offset += info->output[i].sz_q;
+			d_offset += info->output[i].sz_d;
+		}
 	}
 
 	return 0;
diff --git a/drivers/ml/cnxk/meson.build b/drivers/ml/cnxk/meson.build
index 7570186177..12b73ee3be 100644
--- a/drivers/ml/cnxk/meson.build
+++ b/drivers/ml/cnxk/meson.build
@@ -66,6 +66,7 @@ dpdk_conf.set('RTE_MLDEV_CNXK_ENABLE_MVTVM', 1)
 
 driver_sdk_headers += files(
         'mvtvm_ml_ops.h',
+        'mvtvm_ml_model.h',
 )
 
 sources += files(
diff --git a/drivers/ml/cnxk/mvtvm_ml_model.h b/drivers/ml/cnxk/mvtvm_ml_model.h
new file mode 100644
index 0000000000..1f6b435be0
--- /dev/null
+++ b/drivers/ml/cnxk/mvtvm_ml_model.h
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2023 Marvell.
+ */
+
+#ifndef _MVTVM_ML_MODEL_H_
+#define _MVTVM_ML_MODEL_H_
+
+#include <tvmdp.h>
+
+#include <rte_mldev.h>
+
+#include "cnxk_ml_io.h"
+
+/* Maximum number of objects per model */
+#define ML_MVTVM_MODEL_OBJECT_MAX 3
+
+/* Objects list */
+extern char mvtvm_object_list[ML_MVTVM_MODEL_OBJECT_MAX][RTE_ML_STR_MAX];
+
+/* Model object structure */
+struct mvtvm_ml_model_object {
+	/* Name */
+	char name[RTE_ML_STR_MAX];
+
+	/* Temporary buffer */
+	uint8_t *buffer;
+
+	/* Buffer size */
+	int64_t size;
+};
+
+struct mvtvm_ml_model_data {
+	/* Model metadata */
+	struct tvmdp_model_metadata metadata;
+
+	/* Model objects */
+	struct tvmdp_model_object object;
+
+	/* TVM runtime callbacks */
+	struct tvmrt_glow_callback cb;
+
+	/* Model I/O info */
+	struct cnxk_ml_io_info info;
+};
+
+#endif /* _MVTVM_ML_MODEL_H_ */
