// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright(c) 2016-2018 Intel Corporation. All rights reserved.
 */
#include <linux/dma-mapping.h>
#include <linux/mei.h>

#include "mei_dev.h"

/**
 * mei_dmam_dscr_alloc() - allocate a managed coherent buffer
 *     for the dma descriptor
 * @dev: mei_device
 * @dscr: dma descriptor
 *
 * Return:
 * * 0       - on success or zero allocation request
 * * -EINVAL - if size is not power of 2
 * * -ENOMEM - of allocation has failed
 */
static int mei_dmam_dscr_alloc(struct mei_device *dev,
			       struct mei_dma_dscr *dscr)
{
	if (!dscr->size)
		return 0;

	if (WARN_ON(!is_power_of_2(dscr->size)))
		return -EINVAL;

	if (dscr->vaddr)
		return 0;

	dscr->vaddr = dmam_alloc_coherent(dev->dev, dscr->size, &dscr->daddr,
					  GFP_KERNEL);
	if (!dscr->vaddr)
		return -ENOMEM;

	return 0;
}

/**
 * mei_dmam_dscr_free() - free a managed coherent buffer
 *     from the dma descriptor
 * @dev: mei_device
 * @dscr: dma descriptor
 */
static void mei_dmam_dscr_free(struct mei_device *dev,
			       struct mei_dma_dscr *dscr)
{
	if (!dscr->vaddr)
		return;

	dmam_free_coherent(dev->dev, dscr->size, dscr->vaddr, dscr->daddr);
	dscr->vaddr = NULL;
}

/**
 * mei_dmam_ring_free() - free dma ring buffers
 * @dev: mei device
 */
void mei_dmam_ring_free(struct mei_device *dev)
{
	int i;

	for (i = 0; i < DMA_DSCR_NUM; i++)
		mei_dmam_dscr_free(dev, &dev->dr_dscr[i]);
}

/**
 * mei_dmam_ring_alloc() - allocate dma ring buffers
 * @dev: mei device
 *
 * Return: -ENOMEM on allocation failure 0 otherwise
 */
int mei_dmam_ring_alloc(struct mei_device *dev)
{
	int i;

	for (i = 0; i < DMA_DSCR_NUM; i++)
		if (mei_dmam_dscr_alloc(dev, &dev->dr_dscr[i]))
			goto err;

	return 0;

err:
	mei_dmam_ring_free(dev);
	return -ENOMEM;
}

/**
 * mei_dma_ring_is_allocated() - check if dma ring is allocated
 * @dev: mei device
 *
 * Return: true if dma ring is allocated
 */
bool mei_dma_ring_is_allocated(struct mei_device *dev)
{
	return !!dev->dr_dscr[DMA_DSCR_HOST].vaddr;
}

static inline
struct hbm_dma_ring_ctrl *mei_dma_ring_ctrl(struct mei_device *dev)
{
	return (struct hbm_dma_ring_ctrl *)dev->dr_dscr[DMA_DSCR_CTRL].vaddr;
}

/**
 * mei_dma_ring_reset() - reset the dma control block
 * @dev: mei device
 */
void mei_dma_ring_reset(struct mei_device *dev)
{
	struct hbm_dma_ring_ctrl *ctrl = mei_dma_ring_ctrl(dev);

	if (!ctrl)
		return;

	memset(ctrl, 0, sizeof(*ctrl));
}

/**
 * mei_dma_copy_from() - copy from dma ring into buffer
 * @dev: mei device
 * @buf: data buffer
 * @offset: offset in slots.
 * @n: number of slots to copy.
 */
static size_t mei_dma_copy_from(struct mei_device *dev, unsigned char *buf,
				u32 offset, u32 n)
{
	unsigned char *dbuf = dev->dr_dscr[DMA_DSCR_DEVICE].vaddr;

	size_t b_offset = offset << 2;
	size_t b_n = n << 2;

	memcpy(buf, dbuf + b_offset, b_n);

	return b_n;
}

/**
 * mei_dma_copy_to() - copy to a buffer to the dma ring
 * @dev: mei device
 * @buf: data buffer
 * @offset: offset in slots.
 * @n: number of slots to copy.
 */
static size_t mei_dma_copy_to(struct mei_device *dev, unsigned char *buf,
			      u32 offset, u32 n)
{
	unsigned char *hbuf = dev->dr_dscr[DMA_DSCR_HOST].vaddr;

	size_t b_offset = offset << 2;
	size_t b_n = n << 2;

	memcpy(hbuf + b_offset, buf, b_n);

	return b_n;
}

/**
 * mei_dma_ring_read() - read data from the ring
 * @dev: mei device
 * @buf: buffer to read into: may be NULL in case of droping the data.
 * @len: length to read.
 */
void mei_dma_ring_read(struct mei_device *dev, unsigned char *buf, u32 len)
{
	struct hbm_dma_ring_ctrl *ctrl = mei_dma_ring_ctrl(dev);
	u32 dbuf_depth;
	u32 rd_idx, rem, slots;

	if (WARN_ON(!ctrl))
		return;

	dev_dbg(dev->dev, "reading from dma %u bytes\n", len);

	if (!len)
		return;

	dbuf_depth = dev->dr_dscr[DMA_DSCR_DEVICE].size >> 2;
	rd_idx = READ_ONCE(ctrl->dbuf_rd_idx) & (dbuf_depth - 1);
	slots = mei_data2slots(len);

	/* if buf is NULL we drop the packet by advancing the pointer.*/
	if (!buf)
		goto out;

	if (rd_idx + slots > dbuf_depth) {
		buf += mei_dma_copy_from(dev, buf, rd_idx, dbuf_depth - rd_idx);
		rem = slots - (dbuf_depth - rd_idx);
		rd_idx = 0;
	} else {
		rem = slots;
	}

	mei_dma_copy_from(dev, buf, rd_idx, rem);
out:
	WRITE_ONCE(ctrl->dbuf_rd_idx, ctrl->dbuf_rd_idx + slots);
}

static inline u32 mei_dma_ring_hbuf_depth(struct mei_device *dev)
{
	return dev->dr_dscr[DMA_DSCR_HOST].size >> 2;
}

/**
 * mei_dma_ring_empty_slots() - calaculate number of empty slots in dma ring
 * @dev: mei_device
 *
 * Return: number of empty slots
 */
u32 mei_dma_ring_empty_slots(struct mei_device *dev)
{
	struct hbm_dma_ring_ctrl *ctrl = mei_dma_ring_ctrl(dev);
	u32 wr_idx, rd_idx, hbuf_depth, empty;

	if (!mei_dma_ring_is_allocated(dev))
		return 0;

	if (WARN_ON(!ctrl))
		return 0;

	/* easier to work in slots */
	hbuf_depth = mei_dma_ring_hbuf_depth(dev);
	rd_idx = READ_ONCE(ctrl->hbuf_rd_idx);
	wr_idx = READ_ONCE(ctrl->hbuf_wr_idx);

	if (rd_idx > wr_idx)
		empty = rd_idx - wr_idx;
	else
		empty = hbuf_depth - (wr_idx - rd_idx);

	return empty;
}

/**
 * mei_dma_ring_write - write data to dma ring host buffer
 *
 * @dev: mei_device
 * @buf: data will be written
 * @len: data length
 */
void mei_dma_ring_write(struct mei_device *dev, unsigned char *buf, u32 len)
{
	struct hbm_dma_ring_ctrl *ctrl = mei_dma_ring_ctrl(dev);
	u32 hbuf_depth;
	u32 wr_idx, rem, slots;

	if (WARN_ON(!ctrl))
		return;

	dev_dbg(dev->dev, "writing to dma %u bytes\n", len);
	hbuf_depth = mei_dma_ring_hbuf_depth(dev);
	wr_idx = READ_ONCE(ctrl->hbuf_wr_idx) & (hbuf_depth - 1);
	slots = mei_data2slots(len);

	if (wr_idx + slots > hbuf_depth) {
		buf += mei_dma_copy_to(dev, buf, wr_idx, hbuf_depth - wr_idx);
		rem = slots - (hbuf_depth - wr_idx);
		wr_idx = 0;
	} else {
		rem = slots;
	}

	mei_dma_copy_to(dev, buf, wr_idx, rem);

	WRITE_ONCE(ctrl->hbuf_wr_idx, ctrl->hbuf_wr_idx + slots);
}
