/*
 * Copyright 2020 Broadcom
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT brcm_iproc_pax_dma_v2

#include <arch/cpu.h>
#include <cache.h>
#include <errno.h>
#include <init.h>
#include <kernel.h>
#include <linker/sections.h>
#include <soc.h>
#include <string.h>
#include <toolchain.h>
#include <zephyr/types.h>
#include <drivers/dma.h>
#include <drivers/pcie/endpoint/pcie_ep.h>
#include "dma_iproc_pax_v2.h"

#define LOG_LEVEL CONFIG_DMA_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(dma_iproc_pax_v2);

#define PAX_DMA_DEV_NAME(dev)	((dev)->name)

#define PAX_DMA_DEV_CFG(dev)	\
			((struct dma_iproc_pax_cfg *)(dev)->config)

#define PAX_DMA_DEV_DATA(dev)	\
			((struct dma_iproc_pax_data *)(dev)->data)

/* Driver runtime data for PAX DMA and RM */
static struct dma_iproc_pax_data pax_dma_data;

DEVICE_DECLARE(dma_iproc_pax);

/**
 * @brief Opaque/packet id allocator, range 0 to 31
 */
static inline uint32_t reset_pkt_id(struct dma_iproc_pax_ring_data *ring)
{
	return ring->pkt_id = 0x0;
}

static inline uint32_t alloc_pkt_id(struct dma_iproc_pax_ring_data *ring)
{
	ring->pkt_id = (ring->pkt_id + 1) % 32;
	return ring->pkt_id;
}

static inline uint32_t curr_pkt_id(struct dma_iproc_pax_ring_data *ring)
{
	return ring->pkt_id;
}

static inline uint32_t curr_toggle_val(struct dma_iproc_pax_ring_data *ring)
{
	return ring->curr.toggle;
}

/**
 * @brief Populate header descriptor
 */
static inline void rm_write_header_desc(void *desc, uint32_t toggle,
				  uint32_t opq, uint32_t bdcount,
				  uint64_t pci_addr)
{
	struct rm_header *r = (struct rm_header *)desc;

	r->opq = opq;
	r->bdf = 0x0;
	r->res1 = 0x0;
	/* DMA descriptor count init vlaue */
	r->bdcount = bdcount;
	r->prot = 0x0;
	r->res2 = 0x0;
	/* No packet extension, start and end set to '1' */
	r->start = 1;
	r->end = 1;
	/* RM header type */
	r->type = PAX_DMA_TYPE_RM_HEADER;
	r->pcie_addr_msb = PAX_DMA_PCI_ADDR_HI_MSB8(pci_addr);
	r->res3 = 0x0;
	r->res4 = 0x0;
#ifdef CONFIG_DMA_IPROC_PAX_TOGGLE_MODE
	r->toggle = toggle;
#elif CONFIG_DMA_IPROC_PAX_DOORBELL_MODE
	r->toggle = 0;
#endif
}

/**
 * @brief Populate pcie descriptor
 */
static inline void rm_write_pcie_desc(void *desc,
			     uint32_t toggle,
			     uint64_t pci_addr)
{
	struct pcie_desc *pcie = (struct pcie_desc *)desc;

	pcie->pcie_addr_lsb = pci_addr;
	pcie->res1 = 0x0;
	/* PCIE header type */
	pcie->type = PAX_DMA_TYPE_PCIE_DESC;
#ifdef CONFIG_DMA_IPROC_PAX_TOGGLE_MODE
	pcie->toggle = toggle;
#elif CONFIG_DMA_IPROC_PAX_DOORBELL_MODE
	pcie->toggle = 0;
#endif
}

/**
 * @brief Populate src/destionation descriptor
 */
static inline void rm_write_src_dst_desc(void *desc_ptr,
				bool is_mega,
				uint32_t toggle,
				uint64_t axi_addr,
				uint32_t size,
				enum pax_dma_dir direction)
{
	struct src_dst_desc *desc;

	desc = (struct src_dst_desc *)desc_ptr;
	desc->axi_addr = axi_addr;
	desc->length = size;
#ifdef CONFIG_DMA_IPROC_PAX_TOGGLE_MODE
	desc->toggle = toggle;
#elif CONFIG_DMA_IPROC_PAX_DOORBELL_MODE
	desc->toggle = 0;
#endif

	if (direction == CARD_TO_HOST) {
		desc->type = is_mega ?
			     PAX_DMA_TYPE_MEGA_SRC_DESC : PAX_DMA_TYPE_SRC_DESC;
	} else {
		desc->type = is_mega ?
			     PAX_DMA_TYPE_MEGA_DST_DESC : PAX_DMA_TYPE_DST_DESC;
	}
}

#ifdef CONFIG_DMA_IPROC_PAX_TOGGLE_MODE
static void init_toggle(void *desc, uint32_t toggle)
{
	struct rm_header *r = (struct rm_header *)desc;

	r->toggle = toggle;
}
#endif

/**
 * @brief Return current descriptor memory address and
 *        increment to point to next descriptor memory address.
 */
static inline void *get_curr_desc_addr(struct dma_iproc_pax_ring_data *ring)
{
	struct next_ptr_desc *nxt;
	uintptr_t curr;

	curr = (uintptr_t)ring->curr.write_ptr;
	/* if hit next table ptr, skip to next location, flip toggle */
	nxt = (struct next_ptr_desc *)curr;
	if (nxt->type == PAX_DMA_TYPE_NEXT_PTR) {
		LOG_DBG("hit next_ptr@0x%lx %d, next_table@0x%lx\n",
			curr, nxt->toggle, (uintptr_t)nxt->addr);
		uintptr_t last = (uintptr_t)ring->bd +
			     PAX_DMA_RM_DESC_RING_SIZE * PAX_DMA_NUM_BD_BUFFS;
		nxt->toggle = ring->curr.toggle;
		ring->curr.toggle = (ring->curr.toggle == 0) ? 1 : 0;
		/* move to next addr, wrap around if hits end */
		curr += PAX_DMA_RM_DESC_BDWIDTH;
		if (curr == last) {
			curr = (uintptr_t)ring->bd;
			LOG_DBG("hit end of desc:0x%lx, wrap to 0x%lx\n",
				last, curr);
		}
		ring->descs_inflight++;
	}

	ring->curr.write_ptr = (void *)(curr + PAX_DMA_RM_DESC_BDWIDTH);
	ring->descs_inflight++;

	return (void *)curr;
}

/**
 * @brief Populate next ptr descriptor
 */
static void rm_write_next_table_desc(void *desc, void *next_ptr,
				     uint32_t toggle)
{
	struct next_ptr_desc *nxt = (struct next_ptr_desc *)desc;

	nxt->addr = (uintptr_t)next_ptr;
	nxt->type = PAX_DMA_TYPE_NEXT_PTR;
	nxt->toggle = toggle;
}

static void prepare_ring(struct dma_iproc_pax_ring_data *ring)
{
	uintptr_t curr, next, last;
	int buff_count = PAX_DMA_NUM_BD_BUFFS;
#ifdef CONFIG_DMA_IPROC_PAX_TOGGLE_MODE
	uint32_t toggle;
#endif

	/* zero out descriptor area */
	memset(ring->bd, 0x0, PAX_DMA_RM_DESC_RING_SIZE * PAX_DMA_NUM_BD_BUFFS);
	memset(ring->cmpl, 0x0, PAX_DMA_RM_CMPL_RING_SIZE);

	/* start with first buffer, valid toggle is 0x1 */
#ifdef CONFIG_DMA_IPROC_PAX_TOGGLE_MODE
	toggle = 0x1;
#endif
	curr = (uintptr_t)ring->bd;
	next = curr + PAX_DMA_RM_DESC_RING_SIZE;
	last = curr + PAX_DMA_RM_DESC_RING_SIZE * PAX_DMA_NUM_BD_BUFFS;
	do {
#ifdef CONFIG_DMA_IPROC_PAX_TOGGLE_MODE
		init_toggle((void *)curr, toggle);
		/* Place next_table desc as last BD entry on each buffer */
		rm_write_next_table_desc(PAX_DMA_NEXT_TBL_ADDR((void *)curr),
					 (void *)next, toggle);
#elif CONFIG_DMA_IPROC_PAX_DOORBELL_MODE
		/* Place next_table desc as last BD entry on each buffer */
		rm_write_next_table_desc(PAX_DMA_NEXT_TBL_ADDR((void *)curr),
					 (void *)next, 0);
#endif

#ifdef CONFIG_DMA_IPROC_PAX_TOGGLE_MODE
		/* valid toggle flips for each buffer */
		toggle = toggle ? 0x0 : 0x1;
#endif
		curr += PAX_DMA_RM_DESC_RING_SIZE;
		next += PAX_DMA_RM_DESC_RING_SIZE;
		/* last entry, chain back to first buffer */
		if (next == last) {
			next = (uintptr_t)ring->bd;
		}

	} while (--buff_count);

	dma_mb();

	/* start programming from first RM header */
	ring->curr.write_ptr = ring->bd;
	/* valid toggle starts with 1 after reset */
	ring->curr.toggle = 1;
	/* completion read offset */
	ring->curr.cmpl_rd_offs = 0;
	/* inflight descs */
	ring->descs_inflight = 0;

	/* init sync data for the ring */
	ring->curr.sync_data.signature = PAX_DMA_WRITE_SYNC_SIGNATURE;
	ring->curr.sync_data.ring = ring->idx;
	/* pkt id for active dma xfer */
	ring->curr.sync_data.opaque = 0x0;
	/* pkt count for active dma xfer */
	ring->curr.sync_data.total_pkts = 0x0;
}

static int init_rm(struct dma_iproc_pax_data *pd)
{
	int ret = -ETIMEDOUT, timeout = 1000;

	k_mutex_lock(&pd->dma_lock, K_FOREVER);
	/* Wait for Ring Manager ready */
	do {
		LOG_DBG("Waiting for RM HW init\n");
		if ((sys_read32(RM_COMM_REG(pd, RM_COMM_MAIN_HW_INIT_DONE)) &
		    RM_COMM_MAIN_HW_INIT_DONE_MASK)) {
			ret = 0;
			break;
		}
		k_sleep(K_MSEC(1));
	} while (--timeout);
	k_mutex_unlock(&pd->dma_lock);

	if (!timeout) {
		LOG_WRN("RM HW Init timedout!\n");
	} else {
		LOG_INF("PAX DMA RM HW Init Done\n");
	}

	return ret;
}

static void rm_cfg_start(struct dma_iproc_pax_data *pd)
{
	uint32_t val;

	k_mutex_lock(&pd->dma_lock, K_FOREVER);

	/* set config done 0, enable toggle mode */
	val = sys_read32(RM_COMM_REG(pd, RM_COMM_CONTROL));
	val &= ~RM_COMM_CONTROL_CONFIG_DONE;
	sys_write32(val, RM_COMM_REG(pd, RM_COMM_CONTROL));

	val &= ~(RM_COMM_CONTROL_MODE_MASK << RM_COMM_CONTROL_MODE_SHIFT);

#ifdef CONFIG_DMA_IPROC_PAX_DOORBELL_MODE
	val |= (RM_COMM_CONTROL_MODE_DOORBELL <<
		RM_COMM_CONTROL_MODE_SHIFT);
#elif CONFIG_DMA_IPROC_PAX_TOGGLE_MODE
	val |= (RM_COMM_CONTROL_MODE_ALL_BD_TOGGLE <<
		RM_COMM_CONTROL_MODE_SHIFT);
#endif
	sys_write32(val, RM_COMM_REG(pd, RM_COMM_CONTROL));
	sys_write32(RM_COMM_MSI_DISABLE_MASK,
		    RM_COMM_REG(pd, RM_COMM_MSI_DISABLE));

	val = sys_read32(RM_COMM_REG(pd, RM_COMM_AXI_READ_BURST_THRESHOLD));
	val &= ~(RM_COMM_THRESHOLD_CFG_RD_FIFO_MAX_THRESHOLD_MASK <<
		 RM_COMM_THRESHOLD_CFG_RD_FIFO_MAX_THRESHOLD_SHIFT);
	val |= RM_COMM_THRESHOLD_CFG_RD_FIFO_MAX_THRESHOLD_SHIFT_VAL <<
	       RM_COMM_THRESHOLD_CFG_RD_FIFO_MAX_THRESHOLD_SHIFT;
	sys_write32(val, RM_COMM_REG(pd, RM_COMM_AXI_READ_BURST_THRESHOLD));

	val = sys_read32(RM_COMM_REG(pd, RM_COMM_FIFO_FULL_THRESHOLD));
	val &= ~(RM_COMM_PKT_ALIGNMENT_BD_FIFO_FULL_THRESHOLD_MASK <<
		 RM_COMM_PKT_ALIGNMENT_BD_FIFO_FULL_THRESHOLD_SHIFT);
	val |= RM_COMM_PKT_ALIGNMENT_BD_FIFO_FULL_THRESHOLD_VAL <<
	       RM_COMM_PKT_ALIGNMENT_BD_FIFO_FULL_THRESHOLD_SHIFT;

	val &= ~(RM_COMM_BD_FIFO_FULL_THRESHOLD_MASK <<
		 RM_COMM_BD_FIFO_FULL_THRESHOLD_SHIFT);
	val |= RM_COMM_BD_FIFO_FULL_THRESHOLD_VAL <<
	       RM_COMM_BD_FIFO_FULL_THRESHOLD_SHIFT;
	sys_write32(val, RM_COMM_REG(pd, RM_COMM_FIFO_FULL_THRESHOLD));

	/* Enable Line interrupt */
	val = sys_read32(RM_COMM_REG(pd, RM_COMM_CONTROL));
	val |= RM_COMM_CONTROL_LINE_INTR_EN;
	sys_write32(val, RM_COMM_REG(pd, RM_COMM_CONTROL));

	/* Enable AE_TIMEOUT */
	sys_write32(RM_COMM_AE_TIMEOUT_VAL,
		    RM_COMM_REG(pd, RM_COMM_AE_TIMEOUT));
	val = sys_read32(RM_COMM_REG(pd, RM_COMM_CONTROL));
	val |= RM_COMM_CONTROL_AE_TIMEOUT_EN;
	sys_write32(val, RM_COMM_REG(pd, RM_COMM_CONTROL));

	/* AE (Acceleration Engine) grouping to group '0' */
	val = sys_read32(RM_COMM_REG(pd, RM_AE0_AE_CONTROL));
	val &= ~RM_AE_CTRL_AE_GROUP_MASK;
	sys_write32(val, RM_COMM_REG(pd, RM_AE0_AE_CONTROL));
	val |= RM_AE_CONTROL_ACTIVE;
	sys_write32(val, RM_COMM_REG(pd, RM_AE0_AE_CONTROL));

	/* AXI read/write channel enable */
	val = sys_read32(RM_COMM_REG(pd, RM_COMM_AXI_CONTROL));
	val |= (RM_COMM_AXI_CONTROL_RD_CH_EN | RM_COMM_AXI_CONTROL_WR_CH_EN);
	sys_write32(val, RM_COMM_REG(pd, RM_COMM_AXI_CONTROL));

	/* Tune RM control programming for 4 rings */
	sys_write32(RM_COMM_TIMER_CONTROL0_VAL,
		    RM_COMM_REG(pd, RM_COMM_TIMER_CONTROL_0));
	sys_write32(RM_COMM_TIMER_CONTROL1_VAL,
		    RM_COMM_REG(pd, RM_COMM_TIMER_CONTROL_1));
	val = sys_read32(RM_COMM_REG(pd, RM_COMM_BURST_LENGTH));
	val |= RM_COMM_BD_FETCH_CACHE_ALIGNED_DISABLED;
	val |= RM_COMM_VALUE_FOR_DDR_ADDR_GEN_VAL <<
	       RM_COMM_VALUE_FOR_DDR_ADDR_GEN_SHIFT;
	val |= RM_COMM_VALUE_FOR_TOGGLE_VAL << RM_COMM_VALUE_FOR_TOGGLE_SHIFT;
	sys_write32(val, RM_COMM_REG(pd, RM_COMM_BURST_LENGTH));

	val = sys_read32(RM_COMM_REG(pd, RM_COMM_BD_FETCH_MODE_CONTROL));
	val |= RM_COMM_DISABLE_GRP_BD_FIFO_FLOW_CONTROL_FOR_PKT_ALIGNMENT;
	val |= RM_COMM_DISABLE_PKT_ALIGNMENT_BD_FIFO_FLOW_CONTROL;
	sys_write32(val, RM_COMM_REG(pd, RM_COMM_BD_FETCH_MODE_CONTROL));

	/* Set Sequence max count to the max supported value */
	val = sys_read32(RM_COMM_REG(pd, RM_COMM_MASK_SEQUENCE_MAX_COUNT));
	val = (val | RING_MASK_SEQ_MAX_COUNT_MASK);
	sys_write32(val, RM_COMM_REG(pd, RM_COMM_MASK_SEQUENCE_MAX_COUNT));

	k_mutex_unlock(&pd->dma_lock);
}

static void rm_ring_clear_stats(struct dma_iproc_pax_data *pd,
				enum ring_idx idx)
{
	/* Read ring Tx, Rx, and Outstanding counts to clear */
	sys_read32(RM_RING_REG(pd, idx, RING_NUM_REQ_RECV_LS));
	sys_read32(RM_RING_REG(pd, idx, RING_NUM_REQ_RECV_MS));
	sys_read32(RM_RING_REG(pd, idx, RING_NUM_REQ_TRANS_LS));
	sys_read32(RM_RING_REG(pd, idx, RING_NUM_REQ_TRANS_MS));
	sys_read32(RM_RING_REG(pd, idx, RING_NUM_REQ_OUTSTAND));
}

static void rm_cfg_finish(struct dma_iproc_pax_data *pd)
{
	uint32_t val;

	k_mutex_lock(&pd->dma_lock, K_FOREVER);

	/* set Ring config done */
	val = sys_read32(RM_COMM_REG(pd, RM_COMM_CONTROL));
	val |= RM_COMM_CONTROL_CONFIG_DONE;
	sys_write32(val, RM_COMM_REG(pd, RM_COMM_CONTROL));

	k_mutex_unlock(&pd->dma_lock);
}

static inline void write_doorbell(struct dma_iproc_pax_data *pd,
				  enum ring_idx idx)
{
	struct dma_iproc_pax_ring_data *ring = &(pd->ring[idx]);

	sys_write32(ring->descs_inflight,
		    RM_RING_REG(pd, idx, RING_DOORBELL_BD_WRITE_COUNT));
	ring->descs_inflight = 0;
}

static inline void set_ring_active(struct dma_iproc_pax_data *pd,
				   enum ring_idx idx,
				   bool active)
{
	uint32_t val;

	val = sys_read32(RM_RING_REG(pd, idx, RING_CONTROL));
	if (active)
		val |= RING_CONTROL_ACTIVE;
	else
		val &= ~RING_CONTROL_ACTIVE;
	sys_write32(val, RM_RING_REG(pd, idx, RING_CONTROL));
}

static int init_ring(struct dma_iproc_pax_data *pd, enum ring_idx idx)
{
	uint32_t val;
	uintptr_t desc = (uintptr_t)pd->ring[idx].bd;
	uintptr_t cmpl = (uintptr_t)pd->ring[idx].cmpl;
	int timeout = 5000, ret = 0;

	k_mutex_lock(&pd->dma_lock, K_FOREVER);

	/*  Read cmpl write ptr incase previous dma stopped */
	sys_read32(RM_RING_REG(pd, idx, RING_CMPL_WRITE_PTR));

	/* Inactivate ring */
	sys_write32(0x0, RM_RING_REG(pd, idx, RING_CONTROL));

	/* set Ring config done */
	val = sys_read32(RM_COMM_REG(pd, RM_COMM_CONTROL));
	val |= RM_COMM_CONTROL_CONFIG_DONE;
	sys_write32(val,  RM_COMM_REG(pd, RM_COMM_CONTROL));
	/* Flush ring before loading new descriptor */
	sys_write32(RING_CONTROL_FLUSH, RM_RING_REG(pd, idx,
						    RING_CONTROL));
	do {
		if (sys_read32(RM_RING_REG(pd, idx, RING_FLUSH_DONE)) &
		    RING_FLUSH_DONE_MASK)
			break;
		k_busy_wait(1);
	} while (--timeout);

	if (!timeout) {
		LOG_WRN("Ring %d flush timedout!\n", idx);
		ret = -ETIMEDOUT;
		goto err;
	}

	/* clear ring after flush */
	sys_write32(0x0, RM_RING_REG(pd, idx, RING_CONTROL));

	/* Clear Ring config done */
	val = sys_read32(RM_COMM_REG(pd, RM_COMM_CONTROL));
	val &= ~(RM_COMM_CONTROL_CONFIG_DONE);
	sys_write32(val,  RM_COMM_REG(pd, RM_COMM_CONTROL));
	/* ring group id set to '0' */
	val = sys_read32(RM_COMM_REG(pd, RM_COMM_CTRL_REG(idx)));
	val &= ~RING_COMM_CTRL_AE_GROUP_MASK;
	sys_write32(val, RM_COMM_REG(pd, RM_COMM_CTRL_REG(idx)));

	/* DDR update control, set timeout value */
	val = RING_DDR_CONTROL_COUNT(RING_DDR_CONTROL_COUNT_VAL) |
	      RING_DDR_CONTROL_TIMER(RING_DDR_CONTROL_TIMER_VAL) |
	      RING_DDR_CONTROL_ENABLE;

	sys_write32(val, RM_RING_REG(pd, idx, RING_CMPL_WR_PTR_DDR_CONTROL));
	/* Disable Ring MSI Timeout */
	sys_write32(RING_DISABLE_MSI_TIMEOUT_VALUE,
		    RM_RING_REG(pd, idx, RING_DISABLE_MSI_TIMEOUT));

	/* BD and CMPL desc queue start address */
	sys_write32((uint32_t)desc, RM_RING_REG(pd, idx, RING_BD_START_ADDR));
	sys_write32((uint32_t)cmpl, RM_RING_REG(pd, idx, RING_CMPL_START_ADDR));
	val = sys_read32(RM_RING_REG(pd, idx, RING_BD_READ_PTR));

	/* keep ring inactive after init to avoid BD poll */
#ifdef CONFIG_DMA_IPROC_PAX_TOGGLE_MODE
	set_ring_active(pd, idx, false);
#elif CONFIG_DMA_IPROC_PAX_DOORBELL_MODE
	set_ring_active(pd, idx, true);
#endif

#if !defined(CONFIG_DMA_IPROC_PAX_POLL_MODE)
	/* Enable ring completion interrupt */
	sys_write32(0x0, RM_RING_REG(pd, idx,
				     RING_COMPLETION_INTERRUPT_STAT_MASK));
#endif
	rm_ring_clear_stats(pd, idx);
err:
	k_mutex_unlock(&pd->dma_lock);

	return ret;
}

static int poll_on_write_sync(const struct device *dev,
			      struct dma_iproc_pax_ring_data *ring)
{
	struct dma_iproc_pax_cfg *cfg = PAX_DMA_DEV_CFG(dev);
	const struct device *pcidev;
	struct dma_iproc_pax_write_sync_data sync_rd, *recv, *sent;
	uint64_t pci_addr;
	uint32_t *pci32, *axi32;
	uint32_t zero_init = 0, timeout = PAX_DMA_MAX_SYNC_WAIT;
	int ret;

	pcidev = device_get_binding(cfg->pcie_dev_name);
	if (!pcidev) {
		LOG_ERR("Cannot get pcie device\n");
		return -EINVAL;
	}

	recv = &sync_rd;
	sent = &(ring->curr.sync_data);
	/* form host pci sync address */
	pci32 = (uint32_t *)&pci_addr;
	pci32[0] = ring->sync_pci.addr_lo;
	pci32[1] = ring->sync_pci.addr_hi;
	axi32 = (uint32_t *)&sync_rd;

	do {
		ret = pcie_ep_xfer_data_memcpy(pcidev, pci_addr,
					       (uintptr_t *)axi32, 4,
					       PCIE_OB_LOWMEM, HOST_TO_DEVICE);

		if (memcmp((void *)recv, (void *)sent, 4) == 0) {
			/* clear the sync word */
			ret = pcie_ep_xfer_data_memcpy(pcidev, pci_addr,
						       (uintptr_t *)&zero_init,
						       4, PCIE_OB_LOWMEM,
						       DEVICE_TO_HOST);
			dma_mb();
			ret = 0;
			break;
		}
		k_busy_wait(1);
	} while (--timeout);

	if (!timeout) {
		LOG_ERR("[ring %d]: not recvd write sync!\n", ring->idx);
		ret = -ETIMEDOUT;
	}

	return ret;
}

static int process_cmpl_event(const struct device *dev,
			      enum ring_idx idx, uint32_t pl_len)
{
	struct dma_iproc_pax_data *pd = PAX_DMA_DEV_DATA(dev);
	uint32_t wr_offs, rd_offs, ret = 0;
	struct dma_iproc_pax_ring_data *ring = &(pd->ring[idx]);
	struct cmpl_pkt *c;
	uint32_t is_outstanding;

	/* cmpl read offset, unprocessed cmpl location */
	rd_offs = ring->curr.cmpl_rd_offs;

	wr_offs = sys_read32(RM_RING_REG(pd, idx,
					 RING_CMPL_WRITE_PTR));

	/* Update read ptr to "processed" */
	ring->curr.cmpl_rd_offs = wr_offs;

	/*
	 * Ensure consistency of completion descriptor
	 * The completion desc is updated by RM via AXI stream
	 * CPU need to ensure the memory operations are completed
	 * before reading cmpl area, by a "dsb"
	 * If Dcache enabled, need to invalidate the cachelines to
	 * read updated cmpl desc. The cache API also issues dsb.
	 */
	dma_mb();

	/* Decode cmpl pkt id to verify */
	c = (struct cmpl_pkt *)((uintptr_t)ring->cmpl +
	    PAX_DMA_CMPL_DESC_SIZE * PAX_DMA_CURR_CMPL_IDX(wr_offs));

	LOG_DBG("RING%d WR_PTR:%d opq:%d, rm_status:%x dma_status:%x\n",
		idx, wr_offs, c->opq, c->rm_status, c->dma_status);

	is_outstanding = sys_read32(RM_RING_REG(pd, idx,
						RING_NUM_REQ_OUTSTAND));
	if ((ring->curr.opq != c->opq) && (is_outstanding != 0)) {
		LOG_ERR("RING%d: pkt id should be %d, rcvd %d outst=%d\n",
			idx, ring->curr.opq, c->opq, is_outstanding);
		ret = -EIO;
	}
	/* check for completion AE timeout */
	if (c->rm_status == RM_COMPLETION_AE_TIMEOUT) {
		LOG_ERR("RING%d WR_PTR:%d rm_status:%x AE Timeout!\n",
			idx, wr_offs, c->rm_status);
		/* TBD: Issue full card reset to restore operations */
		LOG_ERR("Needs Card Reset to recover!\n");
		ret = -ETIMEDOUT;
	}

	if (ring->dma_callback) {
		ring->dma_callback(dev, ring->callback_arg, idx, ret);
	}

	/* clear total packet count and non header bd count */
	ring->total_pkt_count = 0;

	return ret;
}

#ifdef CONFIG_DMA_IPROC_PAX_POLL_MODE
static int peek_ring_cmpl(const struct device *dev,
			  enum ring_idx idx, uint32_t pl_len)
{
	struct dma_iproc_pax_data *pd = PAX_DMA_DEV_DATA(dev);
	uint32_t wr_offs, rd_offs, timeout = PAX_DMA_MAX_POLL_WAIT;
	struct dma_iproc_pax_ring_data *ring = &(pd->ring[idx]);

	/* cmpl read offset, unprocessed cmpl location */
	rd_offs = ring->curr.cmpl_rd_offs;

	/* poll write_ptr until cmpl received for all buffers */
	do {
		wr_offs = sys_read32(RM_RING_REG(pd, idx,
						 RING_CMPL_WRITE_PTR));
		if (PAX_DMA_GET_CMPL_COUNT(wr_offs, rd_offs) >= pl_len)
			break;
		k_busy_wait(1);
	} while (--timeout);

	if (timeout == 0) {
		LOG_ERR("RING%d timeout, rcvd %d, expected %d!\n",
			idx, PAX_DMA_GET_CMPL_COUNT(wr_offs, rd_offs), pl_len);
		/* More debug info on current dma instance */
		LOG_ERR("WR_PTR:%x RD_PTR%x\n", wr_offs, rd_offs);
		return  -ETIMEDOUT;
	}

	return process_cmpl_event(dev, idx, pl_len);
}
#else
static void rm_isr(void *arg)
{
	uint32_t status, err_stat, idx;
	const struct device *dev = arg;
	struct dma_iproc_pax_data *pd = PAX_DMA_DEV_DATA(dev);

	err_stat =
	sys_read32(RM_COMM_REG(pd,
			       RM_COMM_AE_INTERFACE_GROUP_0_INTERRUPT_MASK));
	sys_write32(err_stat,
		    RM_COMM_REG(pd,
				RM_COMM_AE_INTERFACE_GROUP_0_INTERRUPT_CLEAR));

	/* alert waiting thread to process, for each completed ring */
	for (idx = PAX_DMA_RING0; idx < PAX_DMA_RINGS_MAX; idx++) {
		status =
		sys_read32(RM_RING_REG(pd, idx,
				       RING_COMPLETION_INTERRUPT_STAT));
		sys_write32(status,
			    RM_RING_REG(pd, idx,
					RING_COMPLETION_INTERRUPT_STAT_CLEAR));
		if (status & 0x1) {
			k_sem_give(&pd->ring[idx].alert);
		}
	}
}
#endif

static int dma_iproc_pax_init(const struct device *dev)
{
	struct dma_iproc_pax_cfg *cfg = PAX_DMA_DEV_CFG(dev);
	struct dma_iproc_pax_data *pd = PAX_DMA_DEV_DATA(dev);
	int r;
	uintptr_t mem_aligned;

	pd->dma_base = cfg->dma_base;
	pd->rm_comm_base = cfg->rm_comm_base;
	pd->used_rings = (cfg->use_rings < PAX_DMA_RINGS_MAX) ?
			 cfg->use_rings : PAX_DMA_RINGS_MAX;

	/* dma/rm access lock */
	k_mutex_init(&pd->dma_lock);

	/* Ring Manager H/W init */
	if (init_rm(pd)) {
		return -ETIMEDOUT;
	}

	/* common rm config */
	rm_cfg_start(pd);

	/* individual ring config */
	for (r = 0; r < pd->used_rings; r++) {
		/* per-ring mutex lock */
		k_mutex_init(&pd->ring[r].lock);
		/* Init alerts */
		k_sem_init(&pd->ring[r].alert, 0, 1);

		pd->ring[r].idx = r;
		pd->ring[r].ring_base = cfg->rm_base +
					PAX_DMA_RING_ADDR_OFFSET(r);
		LOG_DBG("RING%d,VERSION:0x%x\n", pd->ring[r].idx,
			sys_read32(RM_RING_REG(pd, r, RING_VER)));

		/* Allocate for 2 BD buffers + cmpl buffer + payload struct */
		pd->ring[r].ring_mem = (void *)((uintptr_t)cfg->bd_memory_base +
					r * PAX_DMA_PER_RING_ALLOC_SIZE);
		if (!pd->ring[r].ring_mem) {
			LOG_ERR("RING%d failed to alloc desc memory!\n", r);
			return -ENOMEM;
		}
		/* Find 8K aligned address within allocated region */
		mem_aligned = ((uintptr_t)pd->ring[r].ring_mem +
			       PAX_DMA_RING_ALIGN - 1) &
			       ~(PAX_DMA_RING_ALIGN - 1);

		pd->ring[r].cmpl = (void *)mem_aligned;
		pd->ring[r].bd = (void *)(mem_aligned +
					  PAX_DMA_RM_CMPL_RING_SIZE);
		pd->ring[r].payload = (void *)((uintptr_t)pd->ring[r].bd +
				      PAX_DMA_RM_DESC_RING_SIZE *
				      PAX_DMA_NUM_BD_BUFFS);

		LOG_DBG("Ring%d,allocated Mem:0x%p Size %d\n",
			pd->ring[r].idx,
			pd->ring[r].ring_mem,
			PAX_DMA_PER_RING_ALLOC_SIZE);
		LOG_DBG("Ring%d,BD:0x%p, CMPL:0x%p, PL:0x%p\n",
			pd->ring[r].idx,
			pd->ring[r].bd,
			pd->ring[r].cmpl,
			pd->ring[r].payload);

		/* Prepare ring desc table */
		prepare_ring(&(pd->ring[r]));

		/* initialize ring */
		init_ring(pd, r);
	}

	/* set ring config done */
	rm_cfg_finish(pd);

#ifndef CONFIG_DMA_IPROC_PAX_POLL_MODE
	/* Register and enable RM interrupt */
	IRQ_CONNECT(DT_INST_IRQN(0),
		    DT_INST_IRQ(0, priority),
		    rm_isr,
		    DEVICE_GET(dma_iproc_pax),
		    0);
	irq_enable(DT_INST_IRQN(0));
#else
	LOG_INF("%s PAX DMA rings in poll mode!\n", PAX_DMA_DEV_NAME(dev));
#endif
	LOG_INF("%s RM setup %d rings\n", PAX_DMA_DEV_NAME(dev),
		pd->used_rings);

	return 0;
}

static int dma_iproc_pax_gen_desc(struct dma_iproc_pax_ring_data *ring,
				  bool is_mega,
				  uint64_t pci_addr,
				  uint64_t axi_addr,
				  uint32_t length,
				  enum pax_dma_dir dir,
				  uint32_t *non_hdr_bd_count)
{
	struct rm_header *hdr;

	if (*non_hdr_bd_count == 0) {
		/* Generate Header BD */
		ring->current_hdr = (uintptr_t)get_curr_desc_addr(ring);
		rm_write_header_desc((void *)ring->current_hdr,
				     curr_toggle_val(ring),
				     curr_pkt_id(ring),
				     PAX_DMA_RM_DESC_BDCOUNT,
				     pci_addr);
		ring->total_pkt_count++;
	}

	rm_write_pcie_desc(get_curr_desc_addr(ring),
			   curr_toggle_val(ring), pci_addr);
	*non_hdr_bd_count = *non_hdr_bd_count + 1;
	rm_write_src_dst_desc(get_curr_desc_addr(ring),
			      is_mega, curr_toggle_val(ring),
			      axi_addr, length, dir);
	*non_hdr_bd_count = *non_hdr_bd_count + 1;

	/* Update Header BD with bd count */
	hdr = (struct rm_header *)ring->current_hdr;
	hdr->bdcount = *non_hdr_bd_count;
	if (*non_hdr_bd_count == MAX_BD_COUNT_PER_HEADER) {
		*non_hdr_bd_count = 0;
	}

	return 0;
}

static int dma_iproc_pax_gen_packets(const struct device *dev,
				     struct dma_iproc_pax_ring_data *ring,
				     uint32_t direction,
				     struct dma_block_config *config,
				     uint32_t *non_hdr_bd_count)
{
	uint32_t outstanding, remaining_len;
	uint32_t offset, curr, mega_len;
	uint64_t axi_addr;
	uint64_t pci_addr;
	enum pax_dma_dir dir;

	switch (direction) {
	case MEMORY_TO_PERIPHERAL:
		pci_addr = config->dest_address;
		axi_addr = config->source_address;
		dir = CARD_TO_HOST;
		break;
	case PERIPHERAL_TO_MEMORY:
		axi_addr = config->dest_address;
		pci_addr = config->source_address;
		dir = HOST_TO_CARD;
		break;
	default:
		LOG_ERR("not supported transfer direction");
		return -EINVAL;
	}

	outstanding = config->block_size;
	offset = 0;
	while (outstanding) {
		curr = MIN(outstanding, PAX_DMA_MAX_SZ_PER_BD);
		mega_len = curr / PAX_DMA_MEGA_LENGTH_MULTIPLE;
		remaining_len = curr % PAX_DMA_MEGA_LENGTH_MULTIPLE;
		pci_addr = pci_addr + offset;
		axi_addr = axi_addr + offset;

		if (mega_len) {
			dma_iproc_pax_gen_desc(ring, true, pci_addr,
					       axi_addr, mega_len, dir,
					       non_hdr_bd_count);
			offset = offset + mega_len *
				PAX_DMA_MEGA_LENGTH_MULTIPLE;
		}

		if (remaining_len) {
			pci_addr = pci_addr + offset;
			axi_addr = axi_addr + offset;
			dma_iproc_pax_gen_desc(ring, false, pci_addr, axi_addr,
					       remaining_len, dir,
					       non_hdr_bd_count);
			offset = offset + remaining_len;
		}

		outstanding =  outstanding - curr;
	}

	return 0;
}

#ifdef CONFIG_DMA_IPROC_PAX_POLL_MODE
static void set_pkt_count(const struct device *dev,
			  enum ring_idx idx,
			  uint32_t pl_len)
{
	/* Nothing needs to be programmed here in poll mode */
}

static int wait_for_pkt_completion(const struct device *dev,
				   enum ring_idx idx,
				   uint32_t pl_len)
{
	/* poll for completion */
	return peek_ring_cmpl(dev, idx, pl_len);
}
#else
static void set_pkt_count(const struct device *dev,
			  enum ring_idx idx,
			  uint32_t pl_len)
{
	struct dma_iproc_pax_data *pd = PAX_DMA_DEV_DATA(dev);
	uint32_t val;

	/* program packet count for interrupt assertion */
	val = sys_read32(RM_RING_REG(pd, idx,
				     RING_CMPL_WR_PTR_DDR_CONTROL));
	val &= ~RING_DDR_CONTROL_COUNT_MASK;
	val |= RING_DDR_CONTROL_COUNT(pl_len);
	sys_write32(val, RM_RING_REG(pd, idx,
				     RING_CMPL_WR_PTR_DDR_CONTROL));
}

static int wait_for_pkt_completion(const struct device *dev,
				   enum ring_idx idx,
				   uint32_t pl_len)
{
	struct dma_iproc_pax_data *pd = PAX_DMA_DEV_DATA(dev);
	struct dma_iproc_pax_ring_data *ring;

	ring = &(pd->ring[idx]);
	/* wait for sg dma completion alert */
	if (k_sem_take(&ring->alert, K_MSEC(PAX_DMA_TIMEOUT)) != 0) {
		LOG_ERR("PAX DMA [ring %d] Timeout!\n", idx);
		return -ETIMEDOUT;
	}

	return process_cmpl_event(dev, idx, pl_len);
}
#endif

static int dma_iproc_pax_process_dma_blocks(const struct device *dev,
					    enum ring_idx idx,
					    struct dma_config *config)
{
	struct dma_iproc_pax_data *pd = PAX_DMA_DEV_DATA(dev);
	struct dma_iproc_pax_cfg *cfg = PAX_DMA_DEV_CFG(dev);
	int ret = 0;
	struct dma_iproc_pax_ring_data *ring;
	uint32_t toggle_bit, non_hdr_bd_count = 0;
	struct dma_block_config sync_pl;
	struct dma_iproc_pax_addr64 sync;
	struct dma_block_config *block_config = config->head_block;

	if (block_config == NULL) {
		LOG_ERR("head_block is NULL\n");
		return -EINVAL;
	}

	ring = &(pd->ring[idx]);

	/*
	 * Host sync buffer isn't ready at zephyr/driver init-time
	 * Read the host address location once at first DMA write
	 * on that ring.
	 */
	if ((ring->sync_pci.addr_lo == 0x0) &&
	    (ring->sync_pci.addr_hi == 0x0)) {
		/* populate sync data location */
		LOG_DBG("sync addr loc 0x%x\n", cfg->scr_addr_loc);
		sync.addr_lo = sys_read32(cfg->scr_addr_loc + 4);
		sync.addr_hi = sys_read32(cfg->scr_addr_loc);
		ring->sync_pci.addr_lo = sync.addr_lo + idx * 4;
		ring->sync_pci.addr_hi = sync.addr_hi;
		LOG_DBG("ring:%d,sync addr:0x%x.0x%x\n", idx,
			ring->sync_pci.addr_hi,
			ring->sync_pci.addr_lo);
	}

	/* account extra sync packet */
	ring->curr.sync_data.opaque = ring->curr.opq;
	ring->curr.sync_data.total_pkts = config->block_count;
	memcpy((void *)&ring->sync_loc,
	       (void *)&(ring->curr.sync_data), 4);
	sync_pl.dest_address = ring->sync_pci.addr_lo |
			   (uint64_t)ring->sync_pci.addr_hi << 32;
	sync_pl.source_address = (uintptr_t)&ring->sync_loc;
	sync_pl.block_size = 4; /* 4-bytes */

	/* current toggle bit */
	toggle_bit = ring->curr.toggle;
	/* current opq value for cmpl check */
	ring->curr.opq = curr_pkt_id(ring);

	/* Form descriptors for total block counts */
	while (block_config != NULL) {
		ret = dma_iproc_pax_gen_packets(dev, ring,
						config->channel_direction,
						block_config,
						&non_hdr_bd_count);
		if (ret)
			goto err;
		block_config = block_config->next_block;
	}

	/* Append write sync payload descriptors */
	dma_iproc_pax_gen_packets(dev, ring, MEMORY_TO_PERIPHERAL, &sync_pl,
				  &non_hdr_bd_count);

	alloc_pkt_id(ring);
err:
	return ret;
}

static int dma_iproc_pax_configure(const struct device *dev, uint32_t channel,
				   struct dma_config *cfg)
{
	struct dma_iproc_pax_data *pd = PAX_DMA_DEV_DATA(dev);
	struct dma_iproc_pax_ring_data *ring;
	int ret = 0;

	if (channel >= PAX_DMA_RINGS_MAX) {
		LOG_ERR("Invalid ring/channel %d\n", channel);
		return -EINVAL;
	}

	ring = &(pd->ring[channel]);
	k_mutex_lock(&ring->lock, K_FOREVER);

	if (ring->ring_active) {
		ret = -EBUSY;
		goto err;
	}

	if (cfg->block_count >= RM_V2_MAX_BLOCK_COUNT) {
		LOG_ERR("Dma block count[%d] supported exceeds limit[%d]\n",
			cfg->block_count, RM_V2_MAX_BLOCK_COUNT);
		ret = -ENOTSUP;
		goto err;
	}

	ring->ring_active = 1;
	ret = dma_iproc_pax_process_dma_blocks(dev, channel, cfg);

	if (ret) {
		ring->ring_active = 0;
		goto err;
	}

	ring->dma_callback = cfg->dma_callback;
	ring->callback_arg = cfg->user_data;
err:
	k_mutex_unlock(&ring->lock);
	return ret;
}

static int dma_iproc_pax_transfer_start(const struct device *dev,
					uint32_t channel)
{
	int ret = 0;
	struct dma_iproc_pax_data *pd = PAX_DMA_DEV_DATA(dev);
	struct dma_iproc_pax_ring_data *ring;

	if (channel >= PAX_DMA_RINGS_MAX) {
		LOG_ERR("Invalid ring %d\n", channel);
		return -EINVAL;
	}

	ring = &(pd->ring[channel]);
	set_pkt_count(dev, channel, ring->total_pkt_count);

#ifdef CONFIG_DMA_IPROC_PAX_DOORBELL_MODE
	write_doorbell(pd, channel);
#elif CONFIG_DMA_IPROC_PAX_TOGGLE_MODE
	/* activate the ring */
	set_ring_active(pd, channel, true);
#endif

	ret = wait_for_pkt_completion(dev, channel, ring->total_pkt_count);
	if (ret) {
		goto err_ret;
	}

	ret = poll_on_write_sync(dev, ring);

err_ret:
	k_mutex_lock(&ring->lock, K_FOREVER);
	ring->ring_active = 0;
	k_mutex_unlock(&ring->lock);

#ifdef CONFIG_DMA_IPROC_PAX_TOGGLE_MODE
	/* deactivate the ring until next active transfer */
	set_ring_active(pd, channel, false);
#endif
	return ret;
}

static int dma_iproc_pax_transfer_stop(const struct device *dev,
				       uint32_t channel)
{
	return 0;
}

static const struct dma_driver_api pax_dma_driver_api = {
	.config = dma_iproc_pax_configure,
	.start = dma_iproc_pax_transfer_start,
	.stop = dma_iproc_pax_transfer_stop,
};

static const struct dma_iproc_pax_cfg pax_dma_cfg = {
	.dma_base = DT_INST_REG_ADDR_BY_NAME(0, dme_regs),
	.rm_base = DT_INST_REG_ADDR_BY_NAME(0, rm_ring_regs),
	.rm_comm_base = DT_INST_REG_ADDR_BY_NAME(0, rm_comm_regs),
	.use_rings = DT_INST_PROP(0, dma_channels),
	.bd_memory_base = (void *)DT_INST_PROP_BY_IDX(0, bd_memory, 0),
	.scr_addr_loc = DT_INST_PROP(0, scr_addr_loc),
	.pcie_dev_name = DT_INST_PROP_BY_PHANDLE(0, pcie_ep, label),
};

DEVICE_AND_API_INIT(dma_iproc_pax,
		    DT_INST_LABEL(0),
		    &dma_iproc_pax_init,
		    &pax_dma_data,
		    &pax_dma_cfg,
		    POST_KERNEL,
		    CONFIG_KERNEL_INIT_PRIORITY_DEVICE,
		    &pax_dma_driver_api);
