/*
 * Copyright (c) 2022 Intel Corporation.
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "drivers/dma.h"
#define DT_DRV_COMPAT intel_cavs_gpdma

#define GPDMA_CTL_OFFSET 0x0004
#define GPDMA_CTL_FDCGB BIT(0)

#define GPDMA_CHLLPC_OFFSET(channel) (0x0010 + (channel) * 0x10)
#define GPDMA_CHLLPC_EN BIT(7)
#define GPDMA_CHLLPC_DHRS(x) SET_BITS(6, 0, x)

#define GPDMA_CHLLPL(channel) (0x0018 + (channel) * 0x10)
#define GPDMA_CHLLPU(channel) (0x001c + (channel) * 0x10)

#include "dma_dw_common.h"

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


/* Device run time data */
struct cavs_gpdma_data {
	struct dw_dma_dev_data dw_data;
};

/* Device constant configuration parameters */
struct cavs_gpdma_cfg {
	struct dw_dma_dev_cfg dw_cfg;
	uint32_t shim;
};

/* Disables automatic clock gating (force disable clock gate) */
static void cavs_gpdma_clock_enable(const struct device *dev)
{
	const struct cavs_gpdma_cfg *const dev_cfg = dev->config;
	uint32_t reg = dev_cfg->shim + GPDMA_CTL_OFFSET;

	sys_write32(GPDMA_CTL_FDCGB, reg);
}

static void cavs_gpdma_llp_config(const struct device *dev, uint32_t channel,
				  uint32_t addr)
{
#ifdef CONFIG_DMA_CAVS_GPDMA_HAS_LLP
	const struct cavs_gpdma_cfg *const dev_cfg = dev->config;

	dw_write(dev_cfg->shim, GPDMA_CHLLPC_OFFSET(channel), GPDMA_CHLLPC_DHRS(addr));
#endif
}

static inline void cavs_gpdma_llp_enable(const struct device *dev,
					      uint32_t channel)
{
#ifdef CONFIG_DMA_CAVS_GPDMA_HAS_LLP
	const struct cavs_gpdma_cfg *const dev_cfg = dev->config;
	uint32_t val;

	val = dw_read(dev_cfg->shim, GPDMA_CHLLPC_OFFSET(channel));
	if (!(val & GPDMA_CHLLPC_EN)) {
		dw_write(dev_cfg->shim, GPDMA_CHLLPC_OFFSET(channel), val | GPDMA_CHLLPC_EN);
	}
#endif
}

static inline void cavs_gpdma_llp_disable(const struct device *dev,
					       uint32_t channel)
{
#ifdef CONFIG_DMA_CAVS_GPDMA_HAS_LLP
	const struct cavs_gpdma_cfg *const dev_cfg = dev->config;
	uint32_t val;

	val = dw_read(dev_cfg->shim, GPDMA_CHLLPC_OFFSET(channel));
	dw_write(dev_cfg->shim, GPDMA_CHLLPC_OFFSET(channel), val | GPDMA_CHLLPC_EN);
#endif
}

static inline void cavs_gpdma_llp_read(const struct device *dev,
					    uint32_t channel,
					    uint32_t *llp_l,
					    uint32_t *llp_u)
{
#ifdef CONFIG_DMA_CAVS_GPDMA_HAS_LLP
	const struct cavs_gpdma_cfg *const dev_cfg = dev->config;

	*llp_l = dw_read(dev_cfg->shim, GPDMA_CHLLPL(channel));
	*llp_u = dw_read(dev_cfg->shim, GPDMA_CHLLPU(channel));
#endif
}


static int cavs_gpdma_config(const struct device *dev, uint32_t channel,
		      struct dma_config *cfg)
{
	int res = dw_dma_config(dev, channel, cfg);

	if (res != 0) {
		return res;
	}

	struct dma_block_config *block_cfg = cfg->head_block;

	/* Assume all scatter/gathers are for the same device? */
	switch (cfg->channel_direction) {
	case MEMORY_TO_PERIPHERAL:
		LOG_DBG("%s: dma %s configuring llp for destination %x",
			__func__, dev->name, block_cfg->dest_address);
		cavs_gpdma_llp_config(dev, channel, block_cfg->dest_address);
		break;
	case PERIPHERAL_TO_MEMORY:
		LOG_DBG("%s: dma %s configuring llp for source %x",
			__func__, dev->name, block_cfg->source_address);
		cavs_gpdma_llp_config(dev, channel, block_cfg->source_address);
		break;
	default:
		break;
	}

	return res;
}

static int cavs_gpdma_start(const struct device *dev, uint32_t channel)
{
	int ret;

	cavs_gpdma_llp_enable(dev, channel);
	ret = dw_dma_start(dev, channel);
	if (ret != 0) {
		cavs_gpdma_llp_disable(dev, channel);
	}
	return ret;
}

static int cavs_gpdma_stop(const struct device *dev, uint32_t channel)
{
	int ret;

	ret = dw_dma_stop(dev, channel);
	if (ret == 0) {
		cavs_gpdma_llp_disable(dev, channel);
	}
	return ret;
}

int cavs_gpdma_copy(const struct device *dev, uint32_t channel,
		    uint32_t src, uint32_t dst, size_t size)
{
	struct dw_dma_dev_data *const dev_data = dev->data;
	struct dw_dma_chan_data *chan_data;
	int i = 0;

	if (channel >= DW_MAX_CHAN) {
		return -EINVAL;
	}

	chan_data = &dev_data->chan[channel];

	/* default action is to clear the DONE bit for all LLI making
	 * sure the cache is coherent between DSP and DMAC.
	 */
	for (i = 0; i < chan_data->lli_count; i++) {
		chan_data->lli[i].ctrl_hi &= ~DW_CTLH_DONE(1);
	}

	chan_data->ptr_data.current_ptr += size;
	if (chan_data->ptr_data.current_ptr >= chan_data->ptr_data.end_ptr) {
		chan_data->ptr_data.current_ptr = chan_data->ptr_data.start_ptr +
			(chan_data->ptr_data.current_ptr - chan_data->ptr_data.end_ptr);
	}

	return 0;
}

int cavs_gpdma_init(const struct device *dev)
{
	const struct cavs_gpdma_cfg *const dev_cfg = dev->config;

	/* Disable dynamic clock gating appropriately before initializing */
	cavs_gpdma_clock_enable(dev);

	/* Disable all channels and Channel interrupts */
	int ret = dw_dma_setup(dev);

	if (ret != 0) {
		LOG_ERR("%s: dma %s failed to initialize", __func__, dev->name);
		goto out;
	}

	/* Configure interrupts */
	dev_cfg->dw_cfg.irq_config();

	LOG_INF("%s: dma %s initialized", __func__, dev->name);

out:
	return 0;
}


static const struct dma_driver_api cavs_gpdma_driver_api = {
	.config = cavs_gpdma_config,
	.reload = cavs_gpdma_copy,
	.start = cavs_gpdma_start,
	.stop = cavs_gpdma_stop,
	.suspend = dw_dma_suspend,
	.resume = dw_dma_resume,
	.get_status = dw_dma_get_status,
};


#define CAVS_GPDMA_CHAN_ARB_DATA(inst)					\
	static struct dw_drv_plat_data dmac##inst = {			\
		.chan[0] = {						\
			.class  = 6,					\
			.weight = 0,					\
		},							\
		.chan[1] = {						\
			.class  = 6,					\
			.weight = 0,					\
		},							\
		.chan[2] = {						\
			.class  = 6,					\
			.weight = 0,					\
		},							\
		.chan[3] = {						\
			.class  = 6,					\
			.weight = 0,					\
		},							\
		.chan[4] = {						\
			.class  = 6,					\
			.weight = 0,					\
		},							\
		.chan[5] = {						\
			.class  = 6,					\
			.weight = 0,					\
		},							\
		.chan[6] = {						\
			.class  = 6,					\
			.weight = 0,					\
		},							\
		.chan[7] = {						\
			.class  = 6,					\
			.weight = 0,					\
		},							\
	}

#define CAVS_GPDMA_INIT(inst)						\
	CAVS_GPDMA_CHAN_ARB_DATA(inst);					\
	static void cavs_gpdma##inst##_irq_config(void);		\
									\
	static const struct cavs_gpdma_cfg cavs_gpdma##inst##_config = { \
		.dw_cfg = {						\
			.base = DT_INST_REG_ADDR(inst),			\
			.irq_config = cavs_gpdma##inst##_irq_config,	\
		},							\
		.shim = DT_INST_PROP_BY_IDX(inst, shim, 0),		\
	};								\
									\
	static struct cavs_gpdma_data cavs_gpdma##inst##_data = {	\
		.dw_data = {						\
			.channel_data = &dmac##inst,			\
		},							\
	};								\
									\
									\
	DEVICE_DT_INST_DEFINE(inst,					\
			      &cavs_gpdma_init,				\
			      NULL,					\
			      &cavs_gpdma##inst##_data,			\
			      &cavs_gpdma##inst##_config, POST_KERNEL,	\
			      CONFIG_DMA_INIT_PRIORITY,			\
			      &cavs_gpdma_driver_api);			\
									\
	static void cavs_gpdma##inst##_irq_config(void)			\
	{								\
		IRQ_CONNECT(DT_INST_IRQN(inst),				\
			    DT_INST_IRQ(inst, priority), dw_dma_isr,	\
			    DEVICE_DT_INST_GET(inst),			\
			    DT_INST_IRQ(inst, sense));			\
		irq_enable(DT_INST_IRQN(inst));				\
	}

DT_INST_FOREACH_STATUS_OKAY(CAVS_GPDMA_INIT)
