// SPDX-License-Identifier: GPL-2.0-only
/*
 * ISHTP DMA I/F functions
 *
 * Copyright (c) 2003-2016, Intel Corporation.
 */

#include <linux/slab.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include "ishtp-dev.h"
#include "client.h"

/**
 * ishtp_cl_alloc_dma_buf() - Allocate DMA RX and TX buffer
 * @dev: ishtp device
 *
 * Allocate RX and TX DMA buffer once during bus setup.
 * It allocates 1MB, RX and TX DMA buffer, which are divided
 * into slots.
 */
void	ishtp_cl_alloc_dma_buf(struct ishtp_device *dev)
{
	dma_addr_t	h;

	if (dev->ishtp_host_dma_tx_buf)
		return;

	dev->ishtp_host_dma_tx_buf_size = 1024*1024;
	dev->ishtp_host_dma_rx_buf_size = 1024*1024;

	/* Allocate Tx buffer and init usage bitmap */
	dev->ishtp_host_dma_tx_buf = dma_alloc_coherent(dev->devc,
					dev->ishtp_host_dma_tx_buf_size,
					&h, GFP_KERNEL);
	if (dev->ishtp_host_dma_tx_buf)
		dev->ishtp_host_dma_tx_buf_phys = h;

	dev->ishtp_dma_num_slots = dev->ishtp_host_dma_tx_buf_size /
						DMA_SLOT_SIZE;

	dev->ishtp_dma_tx_map = kcalloc(dev->ishtp_dma_num_slots,
					sizeof(uint8_t),
					GFP_KERNEL);
	spin_lock_init(&dev->ishtp_dma_tx_lock);

	/* Allocate Rx buffer */
	dev->ishtp_host_dma_rx_buf = dma_alloc_coherent(dev->devc,
					dev->ishtp_host_dma_rx_buf_size,
					 &h, GFP_KERNEL);

	if (dev->ishtp_host_dma_rx_buf)
		dev->ishtp_host_dma_rx_buf_phys = h;
}

/**
 * ishtp_cl_free_dma_buf() - Free DMA RX and TX buffer
 * @dev: ishtp device
 *
 * Free DMA buffer when all clients are released. This is
 * only happens during error path in ISH built in driver
 * model
 */
void	ishtp_cl_free_dma_buf(struct ishtp_device *dev)
{
	dma_addr_t	h;

	if (dev->ishtp_host_dma_tx_buf) {
		h = dev->ishtp_host_dma_tx_buf_phys;
		dma_free_coherent(dev->devc, dev->ishtp_host_dma_tx_buf_size,
				  dev->ishtp_host_dma_tx_buf, h);
	}

	if (dev->ishtp_host_dma_rx_buf) {
		h = dev->ishtp_host_dma_rx_buf_phys;
		dma_free_coherent(dev->devc, dev->ishtp_host_dma_rx_buf_size,
				  dev->ishtp_host_dma_rx_buf, h);
	}

	kfree(dev->ishtp_dma_tx_map);
	dev->ishtp_host_dma_tx_buf = NULL;
	dev->ishtp_host_dma_rx_buf = NULL;
	dev->ishtp_dma_tx_map = NULL;
}

/*
 * ishtp_cl_get_dma_send_buf() - Get a DMA memory slot
 * @dev:	ishtp device
 * @size:	Size of memory to get
 *
 * Find and return free address of "size" bytes in dma tx buffer.
 * the function will mark this address as "in-used" memory.
 *
 * Return: NULL when no free buffer else a buffer to copy
 */
void *ishtp_cl_get_dma_send_buf(struct ishtp_device *dev,
				uint32_t size)
{
	unsigned long	flags;
	int i, j, free;
	/* additional slot is needed if there is rem */
	int required_slots = (size / DMA_SLOT_SIZE)
		+ 1 * (size % DMA_SLOT_SIZE != 0);

	if (!dev->ishtp_dma_tx_map) {
		dev_err(dev->devc, "Fail to allocate Tx map\n");
		return NULL;
	}

	spin_lock_irqsave(&dev->ishtp_dma_tx_lock, flags);
	for (i = 0; i <= (dev->ishtp_dma_num_slots - required_slots); i++) {
		free = 1;
		for (j = 0; j < required_slots; j++)
			if (dev->ishtp_dma_tx_map[i+j]) {
				free = 0;
				i += j;
				break;
			}
		if (free) {
			/* mark memory as "caught" */
			for (j = 0; j < required_slots; j++)
				dev->ishtp_dma_tx_map[i+j] = 1;
			spin_unlock_irqrestore(&dev->ishtp_dma_tx_lock, flags);
			return (i * DMA_SLOT_SIZE) +
				(unsigned char *)dev->ishtp_host_dma_tx_buf;
		}
	}
	spin_unlock_irqrestore(&dev->ishtp_dma_tx_lock, flags);
	dev_err(dev->devc, "No free DMA buffer to send msg\n");
	return NULL;
}

/*
 * ishtp_cl_release_dma_acked_mem() - Release DMA memory slot
 * @dev:	ishtp device
 * @msg_addr:	message address of slot
 * @size:	Size of memory to get
 *
 * Release_dma_acked_mem - returnes the acked memory to free list.
 * (from msg_addr, size bytes long)
 */
void ishtp_cl_release_dma_acked_mem(struct ishtp_device *dev,
				    void *msg_addr,
				    uint8_t size)
{
	unsigned long	flags;
	int acked_slots = (size / DMA_SLOT_SIZE)
		+ 1 * (size % DMA_SLOT_SIZE != 0);
	int i, j;

	if ((msg_addr - dev->ishtp_host_dma_tx_buf) % DMA_SLOT_SIZE) {
		dev_err(dev->devc, "Bad DMA Tx ack address\n");
		return;
	}

	if (!dev->ishtp_dma_tx_map) {
		dev_err(dev->devc, "Fail to allocate Tx map\n");
		return;
	}

	i = (msg_addr - dev->ishtp_host_dma_tx_buf) / DMA_SLOT_SIZE;
	spin_lock_irqsave(&dev->ishtp_dma_tx_lock, flags);
	for (j = 0; j < acked_slots; j++) {
		if ((i + j) >= dev->ishtp_dma_num_slots ||
					!dev->ishtp_dma_tx_map[i+j]) {
			/* no such slot, or memory is already free */
			spin_unlock_irqrestore(&dev->ishtp_dma_tx_lock, flags);
			dev_err(dev->devc, "Bad DMA Tx ack address\n");
			return;
		}
		dev->ishtp_dma_tx_map[i+j] = 0;
	}
	spin_unlock_irqrestore(&dev->ishtp_dma_tx_lock, flags);
}
