diff --git a/MAINTAINERS b/MAINTAINERS
index 6412209bff..8cdb3e215d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1438,6 +1438,10 @@ ML common code
 M: Srikanth Yalavarthi <syalavarthi@marvell.com>
 F: drivers/common/ml/

+Marvell ML CNXK
+M: Srikanth Yalavarthi <syalavarthi@marvell.com>
+F: drivers/common/cnxk/hw/ml.h
+F: drivers/common/cnxk/roc_ml*

 Packet processing
 -----------------
diff --git a/drivers/common/cnxk/hw/ml.h b/drivers/common/cnxk/hw/ml.h
new file mode 100644
index 0000000000..3ead42b807
--- /dev/null
+++ b/drivers/common/cnxk/hw/ml.h
@@ -0,0 +1,170 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Marvell.
+ */
+
+#ifndef __ML_HW_H__
+#define __ML_HW_H__
+
+#include <stdint.h>
+
+/* Constants */
+#define ML_ANBX_NR 0x3
+
+/* Base offsets */
+#define ML_MLAB_BLK_OFFSET 0x20000000 /* CNF10KB */
+#define ML_AXI_START_ADDR  0x800000000
+
+/* MLW register offsets / ML_PF_BAR0 */
+#define ML_CFG			 0x10000
+#define ML_MLR_BASE		 0x10008
+#define ML_AXI_BRIDGE_CTRL(a)	 (0x10020 | (uint64_t)(a) << 3)
+#define ML_JOB_MGR_CTRL		 0x10060
+#define ML_CORE_INT_LO		 0x10140
+#define ML_CORE_INT_HI		 0x10160
+#define ML_JCMDQ_IN(a)		 (0x11000 | (uint64_t)(a) << 3) /* CN10KA */
+#define ML_JCMDQ_STATUS		 0x11010			/* CN10KA */
+#define ML_STGX_STATUS(a)	 (0x11020 | (uint64_t)(a) << 3) /* CNF10KB */
+#define ML_STG_CONTROL		 0x11100			/* CNF10KB */
+#define ML_PNB_CMD_TYPE		 0x113a0			/* CNF10KB */
+#define ML_SCRATCH(a)		 (0x14000 | (uint64_t)(a) << 3)
+#define ML_ANBX_BACKP_DISABLE(a) (0x18000 | (uint64_t)(a) << 12) /* CN10KA */
+#define ML_ANBX_NCBI_P_OVR(a)	 (0x18010 | (uint64_t)(a) << 12) /* CN10KA */
+#define ML_ANBX_NCBI_NP_OVR(a)	 (0x18020 | (uint64_t)(a) << 12) /* CN10KA */
+
+/* MLIP configuration register offsets / ML_PF_BAR0 */
+#define ML_SW_RST_CTRL		      0x12084000
+#define ML_A35_0_RST_VECTOR_BASE_W(a) (0x12084014 + (a) * (0x04))
+#define ML_A35_1_RST_VECTOR_BASE_W(a) (0x1208401c + (a) * (0x04))
+
+/* MLW scratch register offsets */
+#define ML_SCRATCH_WORK_PTR	      (ML_SCRATCH(0))
+#define ML_SCRATCH_FW_CTRL	      (ML_SCRATCH(1))
+#define ML_SCRATCH_DBG_BUFFER_HEAD_C0 (ML_SCRATCH(2))
+#define ML_SCRATCH_DBG_BUFFER_TAIL_C0 (ML_SCRATCH(3))
+#define ML_SCRATCH_DBG_BUFFER_HEAD_C1 (ML_SCRATCH(4))
+#define ML_SCRATCH_DBG_BUFFER_TAIL_C1 (ML_SCRATCH(5))
+#define ML_SCRATCH_EXCEPTION_SP_C0    (ML_SCRATCH(6))
+#define ML_SCRATCH_EXCEPTION_SP_C1    (ML_SCRATCH(7))
+
+/* ML job completion structure */
+struct ml_jce_s {
+	/* WORD 0 */
+	union ml_jce_w0 {
+		struct {
+			uint64_t rsvd_0_3 : 4;
+
+			/* Reserved for future architecture */
+			uint64_t ggrp_h : 2;
+
+			/* Tag type */
+			uint64_t ttype : 2;
+
+			/* Physical function number */
+			uint64_t pf_func : 16;
+
+			/* Unused [7] + Guest Group [6:0] */
+			uint64_t ggrp : 8;
+
+			/* Tag */
+			uint64_t tag : 32;
+		} s;
+		uint64_t u64;
+	} w0;
+
+	/* WORD 1 */
+	union ml_jce_w1 {
+		struct {
+			/* Work queue pointer */
+			uint64_t wqp : 53;
+			uint64_t rsvd_53_63 : 11;
+
+		} s;
+		uint64_t u64;
+	} w1;
+};
+
+/* ML job command structure */
+struct ml_job_cmd_s {
+	/* WORD 0 */
+	union ml_job_cmd_w0 {
+		struct {
+			uint64_t rsvd_0_63;
+		} s;
+		uint64_t u64;
+	} w0;
+
+	/* WORD 1 */
+	union ml_job_cmd_w1 {
+		struct {
+			/* Job pointer */
+			uint64_t jobptr : 53;
+			uint64_t rsvd_53_63 : 11;
+		} s;
+		uint64_t u64;
+	} w1;
+};
+
+/* ML A35 0 RST vector base structure */
+union ml_a35_0_rst_vector_base_s {
+	struct {
+		/* Base address */
+		uint64_t addr : 37;
+		uint64_t rsvd_37_63 : 27;
+	} s;
+
+	struct {
+		/* WORD 0 */
+		uint32_t w0;
+
+		/* WORD 1 */
+		uint32_t w1;
+	} w;
+
+	uint64_t u64;
+};
+
+/* ML A35 1 RST vector base structure */
+union ml_a35_1_rst_vector_base_s {
+	struct {
+		/* Base address */
+		uint64_t addr : 37;
+		uint64_t rsvd_37_63 : 27;
+	} s;
+
+	struct {
+		/* WORD 0 */
+		uint32_t w0;
+
+		/* WORD 1 */
+		uint32_t w1;
+	} w;
+
+	uint64_t u64;
+};
+
+/* Work pointer scratch register */
+union ml_scratch_work_ptr_s {
+	struct {
+		/* Work pointer */
+		uint64_t work_ptr : 37;
+		uint64_t rsvd_37_63 : 27;
+	} s;
+	uint64_t u64;
+};
+
+/* Firmware control scratch register */
+union ml_scratch_fw_ctrl_s {
+	struct {
+		uint64_t rsvd_0_15 : 16;
+
+		/* Valid job bit */
+		uint64_t valid : 1;
+
+		/* Done status bit */
+		uint64_t done : 1;
+		uint64_t rsvd_18_63 : 46;
+	} s;
+	uint64_t u64;
+};
+
+#endif /* __ML_HW_H__ */
diff --git a/drivers/common/cnxk/meson.build b/drivers/common/cnxk/meson.build
index 849735921c..b4aa0a050c 100644
--- a/drivers/common/cnxk/meson.build
+++ b/drivers/common/cnxk/meson.build
@@ -26,6 +26,7 @@ sources = files(
         'roc_irq.c',
         'roc_ie_ot.c',
         'roc_mbox.c',
+        'roc_ml.c',
         'roc_model.c',
         'roc_nix.c',
         'roc_nix_bpf.c',
diff --git a/drivers/common/cnxk/roc_api.h b/drivers/common/cnxk/roc_api.h
index 072f16d77d..fdddf8c6c7 100644
--- a/drivers/common/cnxk/roc_api.h
+++ b/drivers/common/cnxk/roc_api.h
@@ -34,6 +34,7 @@
 /* HW structure definition */
 #include "hw/cpt.h"
 #include "hw/dpi.h"
+#include "hw/ml.h"
 #include "hw/nix.h"
 #include "hw/npa.h"
 #include "hw/npc.h"
@@ -106,4 +107,7 @@
 /* NIX Inline dev */
 #include "roc_nix_inl.h"

+/* ML */
+#include "roc_ml.h"
+
 #endif /* _ROC_API_H_ */
diff --git a/drivers/common/cnxk/roc_constants.h b/drivers/common/cnxk/roc_constants.h
index 0495965daa..ddaef133b8 100644
--- a/drivers/common/cnxk/roc_constants.h
+++ b/drivers/common/cnxk/roc_constants.h
@@ -50,6 +50,8 @@
 #define PCI_DEVID_CN10K_RVU_CPT_PF 0xA0F2
 #define PCI_DEVID_CN10K_RVU_CPT_VF 0xA0F3

+#define PCI_DEVID_CN10K_ML_PF 0xA092
+
 #define PCI_SUBSYSTEM_DEVID_CN10KA  0xB900
 #define PCI_SUBSYSTEM_DEVID_CN10KAS 0xB900
 #define PCI_SUBSYSTEM_DEVID_CNF10KA 0xBA00
diff --git a/drivers/common/cnxk/roc_dev_priv.h b/drivers/common/cnxk/roc_dev_priv.h
index 302dc0feb0..55700dc851 100644
--- a/drivers/common/cnxk/roc_dev_priv.h
+++ b/drivers/common/cnxk/roc_dev_priv.h
@@ -89,6 +89,7 @@ struct dev {
 	struct dev_ops *ops;
 	void *roc_nix;
 	void *roc_cpt;
+	void *roc_ml;
 	bool disable_shared_lmt; /* false(default): shared lmt mode enabled */
 	const struct plt_memzone *lmt_mz;
 } __plt_cache_aligned;
diff --git a/drivers/common/cnxk/roc_ml.c b/drivers/common/cnxk/roc_ml.c
new file mode 100644
index 0000000000..1950258f58
--- /dev/null
+++ b/drivers/common/cnxk/roc_ml.c
@@ -0,0 +1,626 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Marvell.
+ */
+
+#include "roc_api.h"
+#include "roc_priv.h"
+
+#define TIME_SEC_IN_MS 10000
+
+static int
+roc_ml_reg_wait_to_clear(struct roc_ml *roc_ml, uint64_t offset, uint64_t mask)
+{
+	uint64_t start_cycle;
+	uint64_t wait_cycles;
+	uint64_t reg_val;
+
+	wait_cycles = (ROC_ML_TIMEOUT_MS * plt_tsc_hz()) / TIME_SEC_IN_MS;
+	start_cycle = plt_tsc_cycles();
+	do {
+		reg_val = roc_ml_reg_read64(roc_ml, offset);
+
+		if (!(reg_val & mask))
+			return 0;
+	} while (plt_tsc_cycles() - start_cycle < wait_cycles);
+
+	return -ETIME;
+}
+
+uint64_t
+roc_ml_reg_read64(struct roc_ml *roc_ml, uint64_t offset)
+{
+	struct ml *ml = roc_ml_to_ml_priv(roc_ml);
+
+	return plt_read64(PLT_PTR_ADD(ml->ml_reg_addr, offset));
+}
+
+void
+roc_ml_reg_write64(struct roc_ml *roc_ml, uint64_t val, uint64_t offset)
+{
+	struct ml *ml = roc_ml_to_ml_priv(roc_ml);
+
+	plt_write64(val, PLT_PTR_ADD(ml->ml_reg_addr, offset));
+}
+
+uint32_t
+roc_ml_reg_read32(struct roc_ml *roc_ml, uint64_t offset)
+{
+	struct ml *ml = roc_ml_to_ml_priv(roc_ml);
+
+	return plt_read32(PLT_PTR_ADD(ml->ml_reg_addr, offset));
+}
+
+void
+roc_ml_reg_write32(struct roc_ml *roc_ml, uint32_t val, uint64_t offset)
+{
+	struct ml *ml = roc_ml_to_ml_priv(roc_ml);
+
+	plt_write32(val, PLT_PTR_ADD(ml->ml_reg_addr, offset));
+}
+
+void
+roc_ml_reg_save(struct roc_ml *roc_ml, uint64_t offset)
+{
+	struct ml *ml = roc_ml_to_ml_priv(roc_ml);
+
+	if (offset == ML_MLR_BASE) {
+		ml->ml_mlr_base =
+			FIELD_GET(ROC_ML_MLR_BASE_BASE, roc_ml_reg_read64(roc_ml, offset));
+		ml->ml_mlr_base_saved = true;
+	}
+}
+
+void *
+roc_ml_addr_ap2mlip(struct roc_ml *roc_ml, void *addr)
+{
+	struct ml *ml = roc_ml_to_ml_priv(roc_ml);
+	uint64_t ml_mlr_base;
+
+	ml_mlr_base = (ml->ml_mlr_base_saved) ? ml->ml_mlr_base :
+						FIELD_GET(ROC_ML_MLR_BASE_BASE,
+							  roc_ml_reg_read64(roc_ml, ML_MLR_BASE));
+	return PLT_PTR_ADD(addr, ML_AXI_START_ADDR - ml_mlr_base);
+}
+
+void *
+roc_ml_addr_mlip2ap(struct roc_ml *roc_ml, void *addr)
+{
+	struct ml *ml = roc_ml_to_ml_priv(roc_ml);
+	uint64_t ml_mlr_base;
+
+	ml_mlr_base = (ml->ml_mlr_base_saved) ? ml->ml_mlr_base :
+						FIELD_GET(ROC_ML_MLR_BASE_BASE,
+							  roc_ml_reg_read64(roc_ml, ML_MLR_BASE));
+	return PLT_PTR_ADD(addr, ml_mlr_base - ML_AXI_START_ADDR);
+}
+
+uint64_t
+roc_ml_addr_pa_to_offset(struct roc_ml *roc_ml, uint64_t phys_addr)
+{
+	struct ml *ml = roc_ml_to_ml_priv(roc_ml);
+
+	if (roc_model_is_cn10ka())
+		return phys_addr - ml->pci_dev->mem_resource[0].phys_addr;
+	else
+		return phys_addr - ml->pci_dev->mem_resource[0].phys_addr - ML_MLAB_BLK_OFFSET;
+}
+
+uint64_t
+roc_ml_addr_offset_to_pa(struct roc_ml *roc_ml, uint64_t offset)
+{
+	struct ml *ml = roc_ml_to_ml_priv(roc_ml);
+
+	if (roc_model_is_cn10ka())
+		return ml->pci_dev->mem_resource[0].phys_addr + offset;
+	else
+		return ml->pci_dev->mem_resource[0].phys_addr + ML_MLAB_BLK_OFFSET + offset;
+}
+
+void
+roc_ml_scratch_write_job(struct roc_ml *roc_ml, void *work_ptr)
+{
+	union ml_scratch_work_ptr_s reg_work_ptr;
+	union ml_scratch_fw_ctrl_s reg_fw_ctrl;
+
+	reg_work_ptr.u64 = 0;
+	reg_work_ptr.s.work_ptr = PLT_U64_CAST(roc_ml_addr_ap2mlip(roc_ml, work_ptr));
+
+	reg_fw_ctrl.u64 = 0;
+	reg_fw_ctrl.s.valid = 1;
+
+	roc_ml_reg_write64(roc_ml, reg_work_ptr.u64, ML_SCRATCH_WORK_PTR);
+	roc_ml_reg_write64(roc_ml, reg_fw_ctrl.u64, ML_SCRATCH_FW_CTRL);
+}
+
+bool
+roc_ml_scratch_is_valid_bit_set(struct roc_ml *roc_ml)
+{
+	union ml_scratch_fw_ctrl_s reg_fw_ctrl;
+
+	reg_fw_ctrl.u64 = roc_ml_reg_read64(roc_ml, ML_SCRATCH_FW_CTRL);
+
+	if (reg_fw_ctrl.s.valid == 1)
+		return true;
+
+	return false;
+}
+
+bool
+roc_ml_scratch_is_done_bit_set(struct roc_ml *roc_ml)
+{
+	union ml_scratch_fw_ctrl_s reg_fw_ctrl;
+
+	reg_fw_ctrl.u64 = roc_ml_reg_read64(roc_ml, ML_SCRATCH_FW_CTRL);
+
+	if (reg_fw_ctrl.s.done == 1)
+		return true;
+
+	return false;
+}
+
+bool
+roc_ml_scratch_enqueue(struct roc_ml *roc_ml, void *work_ptr)
+{
+	union ml_scratch_work_ptr_s reg_work_ptr;
+	union ml_scratch_fw_ctrl_s reg_fw_ctrl;
+	bool ret = false;
+
+	reg_work_ptr.u64 = 0;
+	reg_work_ptr.s.work_ptr = PLT_U64_CAST(roc_ml_addr_ap2mlip(roc_ml, work_ptr));
+
+	reg_fw_ctrl.u64 = 0;
+	reg_fw_ctrl.s.valid = 1;
+
+	if (plt_spinlock_trylock(&roc_ml->sp_spinlock) != 0) {
+		bool valid = roc_ml_scratch_is_valid_bit_set(roc_ml);
+		bool done = roc_ml_scratch_is_done_bit_set(roc_ml);
+
+		if (valid == done) {
+			roc_ml_clk_force_on(roc_ml);
+			roc_ml_dma_stall_off(roc_ml);
+
+			roc_ml_reg_write64(roc_ml, reg_work_ptr.u64, ML_SCRATCH_WORK_PTR);
+			roc_ml_reg_write64(roc_ml, reg_fw_ctrl.u64, ML_SCRATCH_FW_CTRL);
+
+			ret = true;
+		}
+		plt_spinlock_unlock(&roc_ml->sp_spinlock);
+	}
+
+	return ret;
+}
+
+bool
+roc_ml_scratch_dequeue(struct roc_ml *roc_ml, void *work_ptr)
+{
+	union ml_scratch_work_ptr_s reg_work_ptr;
+	bool ret = false;
+
+	if (plt_spinlock_trylock(&roc_ml->sp_spinlock) != 0) {
+		bool valid = roc_ml_scratch_is_valid_bit_set(roc_ml);
+		bool done = roc_ml_scratch_is_done_bit_set(roc_ml);
+
+		if (valid && done) {
+			reg_work_ptr.u64 = roc_ml_reg_read64(roc_ml, ML_SCRATCH_WORK_PTR);
+			if (work_ptr ==
+			    roc_ml_addr_mlip2ap(roc_ml, PLT_PTR_CAST(reg_work_ptr.u64))) {
+				roc_ml_dma_stall_on(roc_ml);
+				roc_ml_clk_force_off(roc_ml);
+
+				roc_ml_reg_write64(roc_ml, 0, ML_SCRATCH_WORK_PTR);
+				roc_ml_reg_write64(roc_ml, 0, ML_SCRATCH_FW_CTRL);
+				ret = true;
+			}
+		}
+		plt_spinlock_unlock(&roc_ml->sp_spinlock);
+	}
+
+	return ret;
+}
+
+void
+roc_ml_scratch_queue_reset(struct roc_ml *roc_ml)
+{
+	if (plt_spinlock_trylock(&roc_ml->sp_spinlock) != 0) {
+		roc_ml_dma_stall_on(roc_ml);
+		roc_ml_clk_force_off(roc_ml);
+		roc_ml_reg_write64(roc_ml, 0, ML_SCRATCH_WORK_PTR);
+		roc_ml_reg_write64(roc_ml, 0, ML_SCRATCH_FW_CTRL);
+		plt_spinlock_unlock(&roc_ml->sp_spinlock);
+	}
+}
+
+bool
+roc_ml_jcmdq_enqueue_lf(struct roc_ml *roc_ml, struct ml_job_cmd_s *job_cmd)
+{
+	bool ret = false;
+
+	if (FIELD_GET(ROC_ML_JCMDQ_STATUS_AVAIL_COUNT,
+		      roc_ml_reg_read64(roc_ml, ML_JCMDQ_STATUS)) != 0) {
+		roc_ml_reg_write64(roc_ml, job_cmd->w0.u64, ML_JCMDQ_IN(0));
+		roc_ml_reg_write64(roc_ml, job_cmd->w1.u64, ML_JCMDQ_IN(1));
+		ret = true;
+	}
+
+	return ret;
+}
+
+bool
+roc_ml_jcmdq_enqueue_sl(struct roc_ml *roc_ml, struct ml_job_cmd_s *job_cmd)
+{
+	bool ret = false;
+
+	if (plt_spinlock_trylock(&roc_ml->fp_spinlock) != 0) {
+		if (FIELD_GET(ROC_ML_JCMDQ_STATUS_AVAIL_COUNT,
+			      roc_ml_reg_read64(roc_ml, ML_JCMDQ_STATUS)) != 0) {
+			roc_ml_reg_write64(roc_ml, job_cmd->w0.u64, ML_JCMDQ_IN(0));
+			roc_ml_reg_write64(roc_ml, job_cmd->w1.u64, ML_JCMDQ_IN(1));
+			ret = true;
+		}
+		plt_spinlock_unlock(&roc_ml->fp_spinlock);
+	}
+
+	return ret;
+}
+
+void
+roc_ml_clk_force_on(struct roc_ml *roc_ml)
+{
+	uint64_t reg_val = 0;
+
+	reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
+	reg_val |= ROC_ML_CFG_MLIP_CLK_FORCE;
+	roc_ml_reg_write64(roc_ml, reg_val, ML_CFG);
+}
+
+void
+roc_ml_clk_force_off(struct roc_ml *roc_ml)
+{
+	uint64_t reg_val = 0;
+
+	roc_ml_reg_write64(roc_ml, 0, ML_SCRATCH_WORK_PTR);
+
+	reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
+	reg_val &= ~ROC_ML_CFG_MLIP_CLK_FORCE;
+	roc_ml_reg_write64(roc_ml, reg_val, ML_CFG);
+}
+
+void
+roc_ml_dma_stall_on(struct roc_ml *roc_ml)
+{
+	uint64_t reg_val = 0;
+
+	reg_val = roc_ml_reg_read64(roc_ml, ML_JOB_MGR_CTRL);
+	reg_val |= ROC_ML_JOB_MGR_CTRL_STALL_ON_IDLE;
+	roc_ml_reg_write64(roc_ml, reg_val, ML_JOB_MGR_CTRL);
+}
+
+void
+roc_ml_dma_stall_off(struct roc_ml *roc_ml)
+{
+	uint64_t reg_val = 0;
+
+	reg_val = roc_ml_reg_read64(roc_ml, ML_JOB_MGR_CTRL);
+	reg_val &= ~ROC_ML_JOB_MGR_CTRL_STALL_ON_IDLE;
+	roc_ml_reg_write64(roc_ml, reg_val, ML_JOB_MGR_CTRL);
+}
+
+bool
+roc_ml_mlip_is_enabled(struct roc_ml *roc_ml)
+{
+	uint64_t reg_val;
+
+	reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
+
+	if ((reg_val & ROC_ML_CFG_MLIP_ENA) != 0)
+		return true;
+
+	return false;
+}
+
+int
+roc_ml_mlip_reset(struct roc_ml *roc_ml, bool force)
+{
+	uint64_t reg_val;
+
+	/* Force reset */
+	if (force) {
+		/* Set ML(0)_CFG[ENA] = 0. */
+		reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
+		reg_val &= ~ROC_ML_CFG_ENA;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_CFG);
+
+		/* Set ML(0)_CFG[MLIP_ENA] = 0. */
+		reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
+		reg_val &= ~ROC_ML_CFG_MLIP_ENA;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_CFG);
+
+		/* Clear ML_MLR_BASE */
+		roc_ml_reg_write64(roc_ml, 0, ML_MLR_BASE);
+	}
+
+	if (roc_model_is_cn10ka()) {
+		/* Wait for all active jobs to finish.
+		 * ML_CFG[ENA] : When set, MLW will accept job commands. This
+		 * bit can be cleared at any time. If [BUSY] is set, software
+		 * must wait until [BUSY] == 0 before setting this bit.
+		 */
+		roc_ml_reg_wait_to_clear(roc_ml, ML_CFG, ROC_ML_CFG_BUSY);
+
+		/* (1) Set ML(0)_AXI_BRIDGE_CTRL(0..1)[FENCE] = 1 to instruct
+		 * the AXI bridge not to accept any new transactions from MLIP.
+		 */
+		reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(0));
+		reg_val |= ROC_ML_AXI_BRIDGE_CTRL_FENCE;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(0));
+
+		reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(1));
+		reg_val |= ROC_ML_AXI_BRIDGE_CTRL_FENCE;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(1));
+
+		/* (2) Wait until ML(0)_AXI_BRIDGE_CTRL(0..1)[BUSY] = 0 which
+		 * indicates that there is no outstanding transactions on
+		 * AXI-NCB paths.
+		 */
+		roc_ml_reg_wait_to_clear(roc_ml, ML_AXI_BRIDGE_CTRL(0),
+					 ROC_ML_AXI_BRIDGE_CTRL_BUSY);
+		roc_ml_reg_wait_to_clear(roc_ml, ML_AXI_BRIDGE_CTRL(1),
+					 ROC_ML_AXI_BRIDGE_CTRL_BUSY);
+
+		/* (3) Wait until ML(0)_JOB_MGR_CTRL[BUSY] = 0 which indicates
+		 * that there are no pending jobs in the MLW's job manager.
+		 */
+		roc_ml_reg_wait_to_clear(roc_ml, ML_JOB_MGR_CTRL, ROC_ML_JOB_MGR_CTRL_BUSY);
+
+		/* (4) Set ML(0)_CFG[ENA] = 0. */
+		reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
+		reg_val &= ~ROC_ML_CFG_ENA;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_CFG);
+
+		/* (5) Set ML(0)_CFG[MLIP_ENA] = 0. */
+		reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
+		reg_val &= ~ROC_ML_CFG_MLIP_ENA;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_CFG);
+
+		/* (6) Set ML(0)_AXI_BRIDGE_CTRL(0..1)[FENCE] = 0.*/
+		reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(0));
+		reg_val &= ~ROC_ML_AXI_BRIDGE_CTRL_FENCE;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(0));
+		roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(1));
+	}
+
+	if (roc_model_is_cnf10kb()) {
+		/* (1) Clear MLAB(0)_CFG[ENA]. Any new jobs will bypass the job
+		 * execution stages and their completions will be returned to
+		 * PSM.
+		 */
+		reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
+		reg_val &= ~ROC_ML_CFG_ENA;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_CFG);
+
+		/* (2) Quiesce the ACC and DMA AXI interfaces: For each of the
+		 * two MLAB(0)_AXI_BRIDGE_CTRL(0..1) registers:
+		 *
+		 * (a) Set MLAB(0)_AXI_BRIDGE_CTRL(0..1)[FENCE] to block new AXI
+		 * commands from MLIP.
+		 *
+		 * (b) Poll MLAB(0)_AXI_BRIDGE_CTRL(0..1)[BUSY] == 0.
+		 */
+		reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(0));
+		reg_val |= ROC_ML_AXI_BRIDGE_CTRL_FENCE;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(0));
+
+		roc_ml_reg_wait_to_clear(roc_ml, ML_AXI_BRIDGE_CTRL(0),
+					 ROC_ML_AXI_BRIDGE_CTRL_BUSY);
+
+		reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(1));
+		reg_val |= ROC_ML_AXI_BRIDGE_CTRL_FENCE;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(1));
+
+		roc_ml_reg_wait_to_clear(roc_ml, ML_AXI_BRIDGE_CTRL(1),
+					 ROC_ML_AXI_BRIDGE_CTRL_BUSY);
+
+		/* (3) Clear MLAB(0)_CFG[MLIP_ENA] to reset MLIP.
+		 */
+		reg_val = roc_ml_reg_read64(roc_ml, ML_CFG);
+		reg_val &= ~ROC_ML_CFG_MLIP_ENA;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_CFG);
+
+cnf10kb_mlip_reset_stage_4a:
+		/* (4) Flush any outstanding jobs in MLAB's job execution
+		 * stages:
+		 *
+		 * (a) Wait for completion stage to clear:
+		 *   - Poll MLAB(0)_STG(0..2)_STATUS[VALID] == 0.
+		 */
+		roc_ml_reg_wait_to_clear(roc_ml, ML_STGX_STATUS(0), ROC_ML_STG_STATUS_VALID);
+		roc_ml_reg_wait_to_clear(roc_ml, ML_STGX_STATUS(1), ROC_ML_STG_STATUS_VALID);
+		roc_ml_reg_wait_to_clear(roc_ml, ML_STGX_STATUS(2), ROC_ML_STG_STATUS_VALID);
+
+cnf10kb_mlip_reset_stage_4b:
+		/* (4b) Clear job run stage: Poll
+		 * MLAB(0)_STG_CONTROL[RUN_TO_COMP] == 0.
+		 */
+		roc_ml_reg_wait_to_clear(roc_ml, ML_STG_CONTROL, ROC_ML_STG_CONTROL_RUN_TO_COMP);
+
+		/* (4b) Clear job run stage: If MLAB(0)_STG(1)_STATUS[VALID] ==
+		 * 1:
+		 *     - Set MLAB(0)_STG_CONTROL[RUN_TO_COMP].
+		 *     - Poll MLAB(0)_STG_CONTROL[RUN_TO_COMP] == 0.
+		 *     - Repeat step (a) to clear job completion stage.
+		 */
+		reg_val = roc_ml_reg_read64(roc_ml, ML_STGX_STATUS(1));
+		if (reg_val & ROC_ML_STG_STATUS_VALID) {
+			reg_val = roc_ml_reg_read64(roc_ml, ML_STG_CONTROL);
+			reg_val |= ROC_ML_STG_CONTROL_RUN_TO_COMP;
+			roc_ml_reg_write64(roc_ml, reg_val, ML_STG_CONTROL);
+
+			roc_ml_reg_wait_to_clear(roc_ml, ML_STG_CONTROL,
+						 ROC_ML_STG_CONTROL_RUN_TO_COMP);
+
+			goto cnf10kb_mlip_reset_stage_4a;
+		}
+
+		/* (4c) Clear job fetch stage: Poll
+		 * MLAB(0)_STG_CONTROL[FETCH_TO_RUN] == 0.
+		 */
+		roc_ml_reg_wait_to_clear(roc_ml, ML_STG_CONTROL, ROC_ML_STG_CONTROL_FETCH_TO_RUN);
+
+		/* (4c) Clear job fetch stage: If
+		 * MLAB(0)_STG(0..2)_STATUS[VALID] == 1:
+		 *     - Set MLAB(0)_STG_CONTROL[FETCH_TO_RUN].
+		 *     - Poll MLAB(0)_STG_CONTROL[FETCH_TO_RUN] == 0.
+		 *     - Repeat step (b) to clear job run and completion stages.
+		 */
+		reg_val = (roc_ml_reg_read64(roc_ml, ML_STGX_STATUS(0)) |
+			   roc_ml_reg_read64(roc_ml, ML_STGX_STATUS(1)) |
+			   roc_ml_reg_read64(roc_ml, ML_STGX_STATUS(2)));
+
+		if (reg_val & ROC_ML_STG_STATUS_VALID) {
+			reg_val = roc_ml_reg_read64(roc_ml, ML_STG_CONTROL);
+			reg_val |= ROC_ML_STG_CONTROL_RUN_TO_COMP;
+			roc_ml_reg_write64(roc_ml, reg_val, ML_STG_CONTROL);
+
+			roc_ml_reg_wait_to_clear(roc_ml, ML_STG_CONTROL,
+						 ROC_ML_STG_CONTROL_RUN_TO_COMP);
+
+			goto cnf10kb_mlip_reset_stage_4b;
+		}
+
+		/* (5) Reset the ACC and DMA AXI interfaces: For each of the two
+		 * MLAB(0)_AXI_BRIDGE_CTRL(0..1) registers:
+		 *
+		 * (5a) Set and then clear
+		 * MLAB(0)_AXI_BRIDGE_CTRL(0..1)[FLUSH_WRITE_DATA].
+		 *
+		 * (5b) Clear MLAB(0)_AXI_BRIDGE_CTRL(0..1)[FENCE].
+		 */
+		reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(0));
+		reg_val |= ROC_ML_AXI_BRIDGE_CTRL_FLUSH_WRITE_DATA;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(0));
+
+		reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(0));
+		reg_val &= ~ROC_ML_AXI_BRIDGE_CTRL_FLUSH_WRITE_DATA;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(0));
+
+		reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(0));
+		reg_val &= ~ROC_ML_AXI_BRIDGE_CTRL_FENCE;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(0));
+
+		reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(1));
+		reg_val |= ROC_ML_AXI_BRIDGE_CTRL_FLUSH_WRITE_DATA;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(1));
+
+		reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(1));
+		reg_val &= ~ROC_ML_AXI_BRIDGE_CTRL_FLUSH_WRITE_DATA;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(1));
+
+		reg_val = roc_ml_reg_read64(roc_ml, ML_AXI_BRIDGE_CTRL(1));
+		reg_val &= ~ROC_ML_AXI_BRIDGE_CTRL_FENCE;
+		roc_ml_reg_write64(roc_ml, reg_val, ML_AXI_BRIDGE_CTRL(1));
+	}
+
+	return 0;
+}
+
+int
+roc_ml_dev_init(struct roc_ml *roc_ml)
+{
+	struct plt_pci_device *pci_dev;
+	struct dev *dev;
+	struct ml *ml;
+
+	if (roc_ml == NULL || roc_ml->pci_dev == NULL)
+		return -EINVAL;
+
+	PLT_STATIC_ASSERT(sizeof(struct ml) <= ROC_ML_MEM_SZ);
+
+	ml = roc_ml_to_ml_priv(roc_ml);
+	memset(ml, 0, sizeof(*ml));
+	pci_dev = roc_ml->pci_dev;
+	dev = &ml->dev;
+
+	ml->pci_dev = pci_dev;
+	dev->roc_ml = roc_ml;
+
+	ml->ml_reg_addr = ml->pci_dev->mem_resource[0].addr;
+	ml->ml_mlr_base = 0;
+	ml->ml_mlr_base_saved = false;
+
+	plt_ml_dbg("ML: PCI Physical Address : 0x%016lx", ml->pci_dev->mem_resource[0].phys_addr);
+	plt_ml_dbg("ML: PCI Virtual Address : 0x%016lx",
+		   PLT_U64_CAST(ml->pci_dev->mem_resource[0].addr));
+
+	plt_spinlock_init(&roc_ml->sp_spinlock);
+	plt_spinlock_init(&roc_ml->fp_spinlock);
+
+	return 0;
+}
+
+int
+roc_ml_dev_fini(struct roc_ml *roc_ml)
+{
+	struct ml *ml = roc_ml_to_ml_priv(roc_ml);
+
+	if (ml == NULL)
+		return -EINVAL;
+
+	return 0;
+}
+
+int
+roc_ml_blk_init(struct roc_bphy *roc_bphy, struct roc_ml *roc_ml)
+{
+	struct dev *dev;
+	struct ml *ml;
+
+	if ((roc_ml == NULL) || (roc_bphy == NULL))
+		return -EINVAL;
+
+	PLT_STATIC_ASSERT(sizeof(struct ml) <= ROC_ML_MEM_SZ);
+
+	ml = roc_ml_to_ml_priv(roc_ml);
+	memset(ml, 0, sizeof(*ml));
+
+	dev = &ml->dev;
+
+	ml->pci_dev = roc_bphy->pci_dev;
+	dev->roc_ml = roc_ml;
+
+	plt_ml_dbg(
+		"MLAB: Physical Address : 0x%016lx",
+		PLT_PTR_ADD_U64_CAST(ml->pci_dev->mem_resource[0].phys_addr, ML_MLAB_BLK_OFFSET));
+	plt_ml_dbg("MLAB: Virtual Address : 0x%016lx",
+		   PLT_PTR_ADD_U64_CAST(ml->pci_dev->mem_resource[0].addr, ML_MLAB_BLK_OFFSET));
+
+	ml->ml_reg_addr = PLT_PTR_ADD(ml->pci_dev->mem_resource[0].addr, ML_MLAB_BLK_OFFSET);
+	ml->ml_mlr_base = 0;
+	ml->ml_mlr_base_saved = false;
+
+	plt_spinlock_init(&roc_ml->sp_spinlock);
+	plt_spinlock_init(&roc_ml->fp_spinlock);
+
+	return 0;
+}
+
+int
+roc_ml_blk_fini(struct roc_bphy *roc_bphy, struct roc_ml *roc_ml)
+{
+	struct ml *ml;
+
+	if ((roc_ml == NULL) || (roc_bphy == NULL))
+		return -EINVAL;
+
+	ml = roc_ml_to_ml_priv(roc_ml);
+
+	if (ml == NULL)
+		return -EINVAL;
+
+	return 0;
+}
+
+uint16_t
+roc_ml_sso_pf_func_get(void)
+{
+	return idev_sso_pffunc_get();
+}
diff --git a/drivers/common/cnxk/roc_ml.h b/drivers/common/cnxk/roc_ml.h
new file mode 100644
index 0000000000..3cd82be6a6
--- /dev/null
+++ b/drivers/common/cnxk/roc_ml.h
@@ -0,0 +1,152 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Marvell.
+ */
+
+#ifndef _ROC_ML_H_
+#define _ROC_ML_H_
+
+#include "roc_api.h"
+
+#define ROC_ML_MEM_SZ	  (6 * 1024)
+#define ROC_ML_TIMEOUT_MS 10000
+
+/* ML_CFG */
+#define ROC_ML_CFG_JD_SIZE	  GENMASK_ULL(1, 0)
+#define ROC_ML_CFG_MLIP_ENA	  BIT_ULL(2)
+#define ROC_ML_CFG_BUSY		  BIT_ULL(3)
+#define ROC_ML_CFG_WRAP_CLK_FORCE BIT_ULL(4)
+#define ROC_ML_CFG_MLIP_CLK_FORCE BIT_ULL(5)
+#define ROC_ML_CFG_ENA		  BIT_ULL(6)
+
+/* ML_MLR_BASE */
+#define ROC_ML_MLR_BASE_BASE GENMASK_ULL(51, 0)
+
+/* ML_STG_STATUS */
+#define ROC_ML_STG_STATUS_VALID		BIT_ULL(0)
+#define ROC_ML_STG_STATUS_ADDR_ERR	BIT_ULL(1)
+#define ROC_ML_STG_STATUS_DMA_ERR	BIT_ULL(2)
+#define ROC_ML_STG_STATUS_TIMEOUT	BIT_ULL(3)
+#define ROC_ML_STG_STATUS_NFAT_ERR	BIT_ULL(4)
+#define ROC_ML_STG_STATUS_JOB_ERR	BIT_ULL(5)
+#define ROC_ML_STG_STATUS_ELAPSED_TICKS GENMASK_ULL(47, 6)
+
+/* ML_STG_CONTROL */
+#define ROC_ML_STG_CONTROL_FETCH_TO_RUN BIT_ULL(0)
+#define ROC_ML_STG_CONTROL_RUN_TO_COMP	BIT_ULL(1)
+
+/* ML_AXI_BRIDGE */
+#define ROC_ML_AXI_BRIDGE_CTRL_AXI_RESP_CTRL	      BIT_ULL(0)
+#define ROC_ML_AXI_BRIDGE_CTRL_BRIDGE_CTRL_MODE	      BIT_ULL(1)
+#define ROC_ML_AXI_BRIDGE_CTRL_FORCE_AXI_ID	      GENMASK_ULL(11, 2)
+#define ROC_ML_AXI_BRIDGE_CTRL_CSR_WR_BLK	      BIT_ULL(13)
+#define ROC_ML_AXI_BRIDGE_CTRL_NCB_WR_BLK	      BIT_ULL(14)
+#define ROC_ML_AXI_BRIDGE_CTRL_CSR_RD_BLK	      BIT_ULL(15)
+#define ROC_ML_AXI_BRIDGE_CTRL_NCB_RD_BLK	      BIT_ULL(16)
+#define ROC_ML_AXI_BRIDGE_CTRL_FENCE		      BIT_ULL(17)
+#define ROC_ML_AXI_BRIDGE_CTRL_BUSY		      BIT_ULL(18)
+#define ROC_ML_AXI_BRIDGE_CTRL_FORCE_WRESP_OK	      BIT_ULL(19)
+#define ROC_ML_AXI_BRIDGE_CTRL_FORCE_RRESP_OK	      BIT_ULL(20)
+#define ROC_ML_AXI_BRIDGE_CTRL_CSR_FORCE_CMPLT	      BIT_ULL(21)
+#define ROC_ML_AXI_BRIDGE_CTRL_WR_CNT_GEAR	      GENMASK_ULL(25, 22)
+#define ROC_ML_AXI_BRIDGE_CTRL_RD_GEAR		      GENMASK_ULL(28, 26)
+#define ROC_ML_AXI_BRIDGE_CTRL_CSR_CUTTHROUGH_MODE    BIT_ULL(29)
+#define ROC_ML_AXI_BRIDGE_CTRL_GAA_WRITE_CREDITS      GENMASK_ULL(33, 30)
+#define ROC_ML_AXI_BRIDGE_CTRL_GAA_READ_CREDITS	      GENMASK_ULL(37, 34)
+#define ROC_ML_AXI_BRIDGE_CTRL_GAA_LOAD_WRITE_CREDITS BIT_ULL(38)
+#define ROC_ML_AXI_BRIDGE_CTRL_GAA_LOAD_READ_CREDITS  BIT_ULL(39)
+#define ROC_ML_AXI_BRIDGE_CTRL_FLUSH_WRITE_DATA	      BIT_ULL(40)
+
+/* ML_JOB_MGR_CTRL */
+#define ROC_ML_JOB_MGR_CTRL_STALL_ON_ERR     BIT_ULL(0)
+#define ROC_ML_JOB_MGR_CTRL_PF_OVERRIDE	     BIT_ULL(1)
+#define ROC_ML_JOB_MGR_CTRL_PF_FUNC_OVERRIDE GENMASK_ULL(19, 4)
+#define ROC_ML_JOB_MGR_CTRL_BUSY	     BIT_ULL(20)
+#define ROC_ML_JOB_MGR_CTRL_STALL_ON_IDLE    BIT_ULL(21)
+
+/* ML_JCMDQ_STATUS */
+#define ROC_ML_JCMDQ_STATUS_AVAIL_COUNT GENMASK_ULL(4, 0)
+
+/* ML_ANBX_BACKP_DISABLE */
+#define ROC_ML_ANBX_BACKP_DISABLE_EXTMSTR_B_BACKP_DISABLE BIT_ULL(0)
+#define ROC_ML_ANBX_BACKP_DISABLE_EXTMSTR_R_BACKP_DISABLE BIT_ULL(1)
+
+/* ML_ANBX_NCBI_P_OVR */
+#define ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_MSH_DST_OVR_VLD	 BIT_ULL(0)
+#define ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_MSH_DST_OVR	 GENMASK_ULL(11, 1)
+#define ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_NS_OVR_VLD	 BIT_ULL(12)
+#define ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_NS_OVR		 BIT_ULL(13)
+#define ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_PADDR_OVR_VLD	 BIT_ULL(14)
+#define ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_PADDR_OVR		 BIT_ULL(15)
+#define ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_RO_OVR_VLD	 BIT_ULL(16)
+#define ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_RO_OVR		 BIT_ULL(17)
+#define ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_MPADID_VAL_OVR_VLD BIT_ULL(18)
+#define ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_MPADID_VAL_OVR	 BIT_ULL(19)
+#define ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_MPAMDID_OVR_VLD	 BIT_ULL(20)
+#define ML_ANBX_NCBI_P_OVR_ANB_NCBI_P_MPAMDID_OVR	 BIT_ULL(21)
+
+/* ML_ANBX_NCBI_NP_OVR */
+#define ML_ANBX_NCBI_NP_OVR_ANB_NCBI_NP_MSH_DST_OVR_VLD	   BIT_ULL(0)
+#define ML_ANBX_NCBI_NP_OVR_ANB_NCBI_NP_MSH_DST_OVR	   GENMASK_ULL(11, 1)
+#define ML_ANBX_NCBI_NP_OVR_ANB_NCBI_NP_NS_OVR_VLD	   BIT_ULL(12)
+#define ML_ANBX_NCBI_NP_OVR_ANB_NCBI_NP_NS_OVR		   BIT_ULL(13)
+#define ML_ANBX_NCBI_NP_OVR_ANB_NCBI_NP_PADDR_OVR_VLD	   BIT_ULL(14)
+#define ML_ANBX_NCBI_NP_OVR_ANB_NCBI_NP_PADDR_OVR	   BIT_ULL(15)
+#define ML_ANBX_NCBI_NP_OVR_ANB_NCBI_NP_RO_OVR_VLD	   BIT_ULL(16)
+#define ML_ANBX_NCBI_NP_OVR_ANB_NCBI_NP_RO_OVR		   BIT_ULL(17)
+#define ML_ANBX_NCBI_NP_OVR_ANB_NCBI_NP_MPADID_VAL_OVR_VLD BIT_ULL(18)
+#define ML_ANBX_NCBI_NP_OVR_ANB_NCBI_NP_MPADID_VAL_OVR	   BIT_ULL(19)
+#define ML_ANBX_NCBI_NP_OVR_ANB_NCBI_NP_MPAMDID_OVR_VLD	   BIT_ULL(20)
+#define ML_ANBX_NCBI_NP_OVR_ANB_NCBI_NP_MPAMDID_OVR	   BIT_ULL(21)
+
+/* ML_SW_RST_CTRL */
+#define ROC_ML_SW_RST_CTRL_ACC_RST  BIT_ULL(0)
+#define ROC_ML_SW_RST_CTRL_CMPC_RST BIT_ULL(1)
+
+struct roc_ml {
+	struct plt_pci_device *pci_dev;
+	plt_spinlock_t sp_spinlock;
+	plt_spinlock_t fp_spinlock;
+	uint8_t reserved[ROC_ML_MEM_SZ] __plt_cache_aligned;
+} __plt_cache_aligned;
+
+/* Register read and write functions */
+uint64_t __roc_api roc_ml_reg_read64(struct roc_ml *roc_ml, uint64_t offset);
+void __roc_api roc_ml_reg_write64(struct roc_ml *roc_ml, uint64_t val, uint64_t offset);
+uint32_t __roc_api roc_ml_reg_read32(struct roc_ml *roc_ml, uint64_t offset);
+void __roc_api roc_ml_reg_write32(struct roc_ml *roc_ml, uint32_t val, uint64_t offset);
+void __roc_api roc_ml_reg_save(struct roc_ml *roc_ml, uint64_t offset);
+
+/* Address translation functions */
+uint64_t __roc_api roc_ml_addr_pa_to_offset(struct roc_ml *roc_ml, uint64_t phys_addr);
+uint64_t __roc_api roc_ml_addr_offset_to_pa(struct roc_ml *roc_ml, uint64_t offset);
+void *__roc_api roc_ml_addr_ap2mlip(struct roc_ml *roc_ml, void *addr);
+void *__roc_api roc_ml_addr_mlip2ap(struct roc_ml *roc_ml, void *addr);
+
+/* Scratch and JCMDQ functions */
+void __roc_api roc_ml_scratch_write_job(struct roc_ml *roc_ml, void *jd);
+bool __roc_api roc_ml_scratch_is_valid_bit_set(struct roc_ml *roc_ml);
+bool __roc_api roc_ml_scratch_is_done_bit_set(struct roc_ml *roc_ml);
+bool __roc_api roc_ml_scratch_enqueue(struct roc_ml *roc_ml, void *work_ptr);
+bool __roc_api roc_ml_scratch_dequeue(struct roc_ml *roc_ml, void *work_ptr);
+void __roc_api roc_ml_scratch_queue_reset(struct roc_ml *roc_ml);
+bool __roc_api roc_ml_jcmdq_enqueue_lf(struct roc_ml *roc_ml, struct ml_job_cmd_s *job_cmd);
+bool __roc_api roc_ml_jcmdq_enqueue_sl(struct roc_ml *roc_ml, struct ml_job_cmd_s *job_cmd);
+
+/* Device management functions */
+void __roc_api roc_ml_clk_force_on(struct roc_ml *roc_ml);
+void __roc_api roc_ml_clk_force_off(struct roc_ml *roc_ml);
+void __roc_api roc_ml_dma_stall_on(struct roc_ml *roc_ml);
+void __roc_api roc_ml_dma_stall_off(struct roc_ml *roc_ml);
+bool __roc_api roc_ml_mlip_is_enabled(struct roc_ml *roc_ml);
+int __roc_api roc_ml_mlip_reset(struct roc_ml *roc_ml, bool force);
+
+/* Device / block  functions */
+int __roc_api roc_ml_dev_init(struct roc_ml *roc_ml);
+int __roc_api roc_ml_dev_fini(struct roc_ml *roc_ml);
+int __roc_api roc_ml_blk_init(struct roc_bphy *roc_bphy, struct roc_ml *roc_ml);
+int __roc_api roc_ml_blk_fini(struct roc_bphy *roc_bphy, struct roc_ml *roc_ml);
+
+/* Utility functions */
+uint16_t __roc_api roc_ml_sso_pf_func_get(void);
+
+#endif /*_ROC_ML_H_*/
diff --git a/drivers/common/cnxk/roc_ml_priv.h b/drivers/common/cnxk/roc_ml_priv.h
new file mode 100644
index 0000000000..ad5fe90bab
--- /dev/null
+++ b/drivers/common/cnxk/roc_ml_priv.h
@@ -0,0 +1,24 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Marvell.
+ */
+
+#ifndef _ROC_ML_PRIV_H_
+#define _ROC_ML_PRIV_H_
+
+#include "roc_api.h"
+
+struct ml {
+	struct plt_pci_device *pci_dev;
+	struct dev dev;
+	uint8_t *ml_reg_addr;
+	uint64_t ml_mlr_base;
+	bool ml_mlr_base_saved;
+} __plt_cache_aligned;
+
+static inline struct ml *
+roc_ml_to_ml_priv(struct roc_ml *roc_ml)
+{
+	return (struct ml *)&roc_ml->reserved[0];
+}
+
+#endif /* _ROC_ML_PRIV_H_ */
diff --git a/drivers/common/cnxk/roc_platform.c b/drivers/common/cnxk/roc_platform.c
index ce0f9b870c..f91b95ceab 100644
--- a/drivers/common/cnxk/roc_platform.c
+++ b/drivers/common/cnxk/roc_platform.c
@@ -63,6 +63,7 @@ roc_plt_init(void)
 RTE_LOG_REGISTER(cnxk_logtype_base, pmd.cnxk.base, NOTICE);
 RTE_LOG_REGISTER(cnxk_logtype_mbox, pmd.cnxk.mbox, NOTICE);
 RTE_LOG_REGISTER(cnxk_logtype_cpt, pmd.crypto.cnxk, NOTICE);
+RTE_LOG_REGISTER(cnxk_logtype_ml, pmd.ml.cnxk, NOTICE);
 RTE_LOG_REGISTER(cnxk_logtype_npa, pmd.mempool.cnxk, NOTICE);
 RTE_LOG_REGISTER(cnxk_logtype_nix, pmd.net.cnxk, NOTICE);
 RTE_LOG_REGISTER(cnxk_logtype_npc, pmd.net.cnxk.flow, NOTICE);
diff --git a/drivers/common/cnxk/roc_platform.h b/drivers/common/cnxk/roc_platform.h
index 1a48ff3db4..a291ed1c66 100644
--- a/drivers/common/cnxk/roc_platform.h
+++ b/drivers/common/cnxk/roc_platform.h
@@ -233,6 +233,7 @@
 extern int cnxk_logtype_base;
 extern int cnxk_logtype_mbox;
 extern int cnxk_logtype_cpt;
+extern int cnxk_logtype_ml;
 extern int cnxk_logtype_npa;
 extern int cnxk_logtype_nix;
 extern int cnxk_logtype_npc;
@@ -260,6 +261,7 @@ extern int cnxk_logtype_ree;
 #define plt_base_dbg(fmt, ...)	plt_dbg(base, fmt, ##__VA_ARGS__)
 #define plt_cpt_dbg(fmt, ...)	plt_dbg(cpt, fmt, ##__VA_ARGS__)
 #define plt_mbox_dbg(fmt, ...)	plt_dbg(mbox, fmt, ##__VA_ARGS__)
+#define plt_ml_dbg(fmt, ...)	plt_dbg(ml, fmt, ##__VA_ARGS__)
 #define plt_npa_dbg(fmt, ...)	plt_dbg(npa, fmt, ##__VA_ARGS__)
 #define plt_nix_dbg(fmt, ...)	plt_dbg(nix, fmt, ##__VA_ARGS__)
 #define plt_npc_dbg(fmt, ...)	plt_dbg(npc, fmt, ##__VA_ARGS__)
diff --git a/drivers/common/cnxk/roc_priv.h b/drivers/common/cnxk/roc_priv.h
index 122d411fe7..14fe2e452a 100644
--- a/drivers/common/cnxk/roc_priv.h
+++ b/drivers/common/cnxk/roc_priv.h
@@ -47,4 +47,7 @@
 /* REE */
 #include "roc_ree_priv.h"

+/* ML */
+#include "roc_ml_priv.h"
+
 #endif /* _ROC_PRIV_H_ */
diff --git a/drivers/common/cnxk/version.map b/drivers/common/cnxk/version.map
index 17f0ec6b48..f7fe49e0ed 100644
--- a/drivers/common/cnxk/version.map
+++ b/drivers/common/cnxk/version.map
@@ -8,6 +8,7 @@ INTERNAL {
 	cnxk_logtype_base;
 	cnxk_logtype_cpt;
 	cnxk_logtype_mbox;
+	cnxk_logtype_ml;
 	cnxk_logtype_nix;
 	cnxk_logtype_npa;
 	cnxk_logtype_npc;
@@ -96,6 +97,34 @@ INTERNAL {
 	roc_idev_npa_nix_get;
 	roc_idev_num_lmtlines_get;
 	roc_idev_nix_inl_meta_aura_get;
+	roc_ml_reg_read64;
+	roc_ml_reg_write64;
+	roc_ml_reg_read32;
+	roc_ml_reg_write32;
+	roc_ml_reg_save;
+	roc_ml_addr_ap2mlip;
+	roc_ml_addr_mlip2ap;
+	roc_ml_addr_pa_to_offset;
+	roc_ml_addr_offset_to_pa;
+	roc_ml_scratch_write_job;
+	roc_ml_scratch_is_valid_bit_set;
+	roc_ml_scratch_is_done_bit_set;
+	roc_ml_scratch_enqueue;
+	roc_ml_scratch_dequeue;
+	roc_ml_scratch_queue_reset;
+	roc_ml_jcmdq_enqueue_lf;
+	roc_ml_jcmdq_enqueue_sl;
+	roc_ml_clk_force_on;
+	roc_ml_clk_force_off;
+	roc_ml_dma_stall_on;
+	roc_ml_dma_stall_off;
+	roc_ml_mlip_is_enabled;
+	roc_ml_mlip_reset;
+	roc_ml_dev_init;
+	roc_ml_dev_fini;
+	roc_ml_blk_init;
+	roc_ml_blk_fini;
+	roc_ml_sso_pf_func_get;
 	roc_model;
 	roc_se_auth_key_set;
 	roc_se_ciph_key_set;
