// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2006-2007 PA Semi, Inc
 *
 * Common functions for DMA access on PA Semi PWRficient
 */

#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/sched.h>

#include <asm/pasemi_dma.h>

#define MAX_TXCH 64
#define MAX_RXCH 64
#define MAX_FLAGS 64
#define MAX_FUN 8

static struct pasdma_status *dma_status;

static void __iomem *iob_regs;
static void __iomem *mac_regs[6];
static void __iomem *dma_regs;

static int base_hw_irq;

static int num_txch, num_rxch;

static struct pci_dev *dma_pdev;

/* Bitmaps to handle allocation of channels */

static DECLARE_BITMAP(txch_free, MAX_TXCH);
static DECLARE_BITMAP(rxch_free, MAX_RXCH);
static DECLARE_BITMAP(flags_free, MAX_FLAGS);
static DECLARE_BITMAP(fun_free, MAX_FUN);

/* pasemi_read_iob_reg - read IOB register
 * @reg: Register to read (offset into PCI CFG space)
 */
unsigned int pasemi_read_iob_reg(unsigned int reg)
{
	return in_le32(iob_regs+reg);
}
EXPORT_SYMBOL(pasemi_read_iob_reg);

/* pasemi_write_iob_reg - write IOB register
 * @reg: Register to write to (offset into PCI CFG space)
 * @val: Value to write
 */
void pasemi_write_iob_reg(unsigned int reg, unsigned int val)
{
	out_le32(iob_regs+reg, val);
}
EXPORT_SYMBOL(pasemi_write_iob_reg);

/* pasemi_read_mac_reg - read MAC register
 * @intf: MAC interface
 * @reg: Register to read (offset into PCI CFG space)
 */
unsigned int pasemi_read_mac_reg(int intf, unsigned int reg)
{
	return in_le32(mac_regs[intf]+reg);
}
EXPORT_SYMBOL(pasemi_read_mac_reg);

/* pasemi_write_mac_reg - write MAC register
 * @intf: MAC interface
 * @reg: Register to write to (offset into PCI CFG space)
 * @val: Value to write
 */
void pasemi_write_mac_reg(int intf, unsigned int reg, unsigned int val)
{
	out_le32(mac_regs[intf]+reg, val);
}
EXPORT_SYMBOL(pasemi_write_mac_reg);

/* pasemi_read_dma_reg - read DMA register
 * @reg: Register to read (offset into PCI CFG space)
 */
unsigned int pasemi_read_dma_reg(unsigned int reg)
{
	return in_le32(dma_regs+reg);
}
EXPORT_SYMBOL(pasemi_read_dma_reg);

/* pasemi_write_dma_reg - write DMA register
 * @reg: Register to write to (offset into PCI CFG space)
 * @val: Value to write
 */
void pasemi_write_dma_reg(unsigned int reg, unsigned int val)
{
	out_le32(dma_regs+reg, val);
}
EXPORT_SYMBOL(pasemi_write_dma_reg);

static int pasemi_alloc_tx_chan(enum pasemi_dmachan_type type)
{
	int bit;
	int start, limit;

	switch (type & (TXCHAN_EVT0|TXCHAN_EVT1)) {
	case TXCHAN_EVT0:
		start = 0;
		limit = 10;
		break;
	case TXCHAN_EVT1:
		start = 10;
		limit = MAX_TXCH;
		break;
	default:
		start = 0;
		limit = MAX_TXCH;
		break;
	}
retry:
	bit = find_next_bit(txch_free, MAX_TXCH, start);
	if (bit >= limit)
		return -ENOSPC;
	if (!test_and_clear_bit(bit, txch_free))
		goto retry;

	return bit;
}

static void pasemi_free_tx_chan(int chan)
{
	BUG_ON(test_bit(chan, txch_free));
	set_bit(chan, txch_free);
}

static int pasemi_alloc_rx_chan(void)
{
	int bit;
retry:
	bit = find_first_bit(rxch_free, MAX_RXCH);
	if (bit >= MAX_TXCH)
		return -ENOSPC;
	if (!test_and_clear_bit(bit, rxch_free))
		goto retry;

	return bit;
}

static void pasemi_free_rx_chan(int chan)
{
	BUG_ON(test_bit(chan, rxch_free));
	set_bit(chan, rxch_free);
}

/* pasemi_dma_alloc_chan - Allocate a DMA channel
 * @type: Type of channel to allocate
 * @total_size: Total size of structure to allocate (to allow for more
 *		room behind the structure to be used by the client)
 * @offset: Offset in bytes from start of the total structure to the beginning
 *	    of struct pasemi_dmachan. Needed when struct pasemi_dmachan is
 *	    not the first member of the client structure.
 *
 * pasemi_dma_alloc_chan allocates a DMA channel for use by a client. The
 * type argument specifies whether it's a RX or TX channel, and in the case
 * of TX channels which group it needs to belong to (if any).
 *
 * Returns a pointer to the total structure allocated on success, NULL
 * on failure.
 */
void *pasemi_dma_alloc_chan(enum pasemi_dmachan_type type,
			    int total_size, int offset)
{
	void *buf;
	struct pasemi_dmachan *chan;
	int chno;

	BUG_ON(total_size < sizeof(struct pasemi_dmachan));

	buf = kzalloc(total_size, GFP_KERNEL);

	if (!buf)
		return NULL;
	chan = buf + offset;

	chan->priv = buf;

	switch (type & (TXCHAN|RXCHAN)) {
	case RXCHAN:
		chno = pasemi_alloc_rx_chan();
		chan->chno = chno;
		chan->irq = irq_create_mapping(NULL,
					       base_hw_irq + num_txch + chno);
		chan->status = &dma_status->rx_sta[chno];
		break;
	case TXCHAN:
		chno = pasemi_alloc_tx_chan(type);
		chan->chno = chno;
		chan->irq = irq_create_mapping(NULL, base_hw_irq + chno);
		chan->status = &dma_status->tx_sta[chno];
		break;
	}

	chan->chan_type = type;

	return chan;
}
EXPORT_SYMBOL(pasemi_dma_alloc_chan);

/* pasemi_dma_free_chan - Free a previously allocated channel
 * @chan: Channel to free
 *
 * Frees a previously allocated channel. It will also deallocate any
 * descriptor ring associated with the channel, if allocated.
 */
void pasemi_dma_free_chan(struct pasemi_dmachan *chan)
{
	if (chan->ring_virt)
		pasemi_dma_free_ring(chan);

	switch (chan->chan_type & (RXCHAN|TXCHAN)) {
	case RXCHAN:
		pasemi_free_rx_chan(chan->chno);
		break;
	case TXCHAN:
		pasemi_free_tx_chan(chan->chno);
		break;
	}

	kfree(chan->priv);
}
EXPORT_SYMBOL(pasemi_dma_free_chan);

/* pasemi_dma_alloc_ring - Allocate descriptor ring for a channel
 * @chan: Channel for which to allocate
 * @ring_size: Ring size in 64-bit (8-byte) words
 *
 * Allocate a descriptor ring for a channel. Returns 0 on success, errno
 * on failure. The passed in struct pasemi_dmachan is updated with the
 * virtual and DMA addresses of the ring.
 */
int pasemi_dma_alloc_ring(struct pasemi_dmachan *chan, int ring_size)
{
	BUG_ON(chan->ring_virt);

	chan->ring_size = ring_size;

	chan->ring_virt = dma_alloc_coherent(&dma_pdev->dev,
					     ring_size * sizeof(u64),
					     &chan->ring_dma, GFP_KERNEL);

	if (!chan->ring_virt)
		return -ENOMEM;

	return 0;
}
EXPORT_SYMBOL(pasemi_dma_alloc_ring);

/* pasemi_dma_free_ring - Free an allocated descriptor ring for a channel
 * @chan: Channel for which to free the descriptor ring
 *
 * Frees a previously allocated descriptor ring for a channel.
 */
void pasemi_dma_free_ring(struct pasemi_dmachan *chan)
{
	BUG_ON(!chan->ring_virt);

	dma_free_coherent(&dma_pdev->dev, chan->ring_size * sizeof(u64),
			  chan->ring_virt, chan->ring_dma);
	chan->ring_virt = NULL;
	chan->ring_size = 0;
	chan->ring_dma = 0;
}
EXPORT_SYMBOL(pasemi_dma_free_ring);

/* pasemi_dma_start_chan - Start a DMA channel
 * @chan: Channel to start
 * @cmdsta: Additional CCMDSTA/TCMDSTA bits to write
 *
 * Enables (starts) a DMA channel with optional additional arguments.
 */
void pasemi_dma_start_chan(const struct pasemi_dmachan *chan, const u32 cmdsta)
{
	if (chan->chan_type == RXCHAN)
		pasemi_write_dma_reg(PAS_DMA_RXCHAN_CCMDSTA(chan->chno),
				     cmdsta | PAS_DMA_RXCHAN_CCMDSTA_EN);
	else
		pasemi_write_dma_reg(PAS_DMA_TXCHAN_TCMDSTA(chan->chno),
				     cmdsta | PAS_DMA_TXCHAN_TCMDSTA_EN);
}
EXPORT_SYMBOL(pasemi_dma_start_chan);

/* pasemi_dma_stop_chan - Stop a DMA channel
 * @chan: Channel to stop
 *
 * Stops (disables) a DMA channel. This is done by setting the ST bit in the
 * CMDSTA register and waiting on the ACT (active) bit to clear, then
 * finally disabling the whole channel.
 *
 * This function will only try for a short while for the channel to stop, if
 * it doesn't it will return failure.
 *
 * Returns 1 on success, 0 on failure.
 */
#define MAX_RETRIES 5000
int pasemi_dma_stop_chan(const struct pasemi_dmachan *chan)
{
	int reg, retries;
	u32 sta;

	if (chan->chan_type == RXCHAN) {
		reg = PAS_DMA_RXCHAN_CCMDSTA(chan->chno);
		pasemi_write_dma_reg(reg, PAS_DMA_RXCHAN_CCMDSTA_ST);
		for (retries = 0; retries < MAX_RETRIES; retries++) {
			sta = pasemi_read_dma_reg(reg);
			if (!(sta & PAS_DMA_RXCHAN_CCMDSTA_ACT)) {
				pasemi_write_dma_reg(reg, 0);
				return 1;
			}
			cond_resched();
		}
	} else {
		reg = PAS_DMA_TXCHAN_TCMDSTA(chan->chno);
		pasemi_write_dma_reg(reg, PAS_DMA_TXCHAN_TCMDSTA_ST);
		for (retries = 0; retries < MAX_RETRIES; retries++) {
			sta = pasemi_read_dma_reg(reg);
			if (!(sta & PAS_DMA_TXCHAN_TCMDSTA_ACT)) {
				pasemi_write_dma_reg(reg, 0);
				return 1;
			}
			cond_resched();
		}
	}

	return 0;
}
EXPORT_SYMBOL(pasemi_dma_stop_chan);

/* pasemi_dma_alloc_buf - Allocate a buffer to use for DMA
 * @chan: Channel to allocate for
 * @size: Size of buffer in bytes
 * @handle: DMA handle
 *
 * Allocate a buffer to be used by the DMA engine for read/write,
 * similar to dma_alloc_coherent().
 *
 * Returns the virtual address of the buffer, or NULL in case of failure.
 */
void *pasemi_dma_alloc_buf(struct pasemi_dmachan *chan, int size,
			   dma_addr_t *handle)
{
	return dma_alloc_coherent(&dma_pdev->dev, size, handle, GFP_KERNEL);
}
EXPORT_SYMBOL(pasemi_dma_alloc_buf);

/* pasemi_dma_free_buf - Free a buffer used for DMA
 * @chan: Channel the buffer was allocated for
 * @size: Size of buffer in bytes
 * @handle: DMA handle
 *
 * Frees a previously allocated buffer.
 */
void pasemi_dma_free_buf(struct pasemi_dmachan *chan, int size,
			 dma_addr_t *handle)
{
	dma_free_coherent(&dma_pdev->dev, size, handle, GFP_KERNEL);
}
EXPORT_SYMBOL(pasemi_dma_free_buf);

/* pasemi_dma_alloc_flag - Allocate a flag (event) for channel synchronization
 *
 * Allocates a flag for use with channel synchronization (event descriptors).
 * Returns allocated flag (0-63), < 0 on error.
 */
int pasemi_dma_alloc_flag(void)
{
	int bit;

retry:
	bit = find_first_bit(flags_free, MAX_FLAGS);
	if (bit >= MAX_FLAGS)
		return -ENOSPC;
	if (!test_and_clear_bit(bit, flags_free))
		goto retry;

	return bit;
}
EXPORT_SYMBOL(pasemi_dma_alloc_flag);


/* pasemi_dma_free_flag - Deallocates a flag (event)
 * @flag: Flag number to deallocate
 *
 * Frees up a flag so it can be reused for other purposes.
 */
void pasemi_dma_free_flag(int flag)
{
	BUG_ON(test_bit(flag, flags_free));
	BUG_ON(flag >= MAX_FLAGS);
	set_bit(flag, flags_free);
}
EXPORT_SYMBOL(pasemi_dma_free_flag);


/* pasemi_dma_set_flag - Sets a flag (event) to 1
 * @flag: Flag number to set active
 *
 * Sets the flag provided to 1.
 */
void pasemi_dma_set_flag(int flag)
{
	BUG_ON(flag >= MAX_FLAGS);
	if (flag < 32)
		pasemi_write_dma_reg(PAS_DMA_TXF_SFLG0, 1 << flag);
	else
		pasemi_write_dma_reg(PAS_DMA_TXF_SFLG1, 1 << flag);
}
EXPORT_SYMBOL(pasemi_dma_set_flag);

/* pasemi_dma_clear_flag - Sets a flag (event) to 0
 * @flag: Flag number to set inactive
 *
 * Sets the flag provided to 0.
 */
void pasemi_dma_clear_flag(int flag)
{
	BUG_ON(flag >= MAX_FLAGS);
	if (flag < 32)
		pasemi_write_dma_reg(PAS_DMA_TXF_CFLG0, 1 << flag);
	else
		pasemi_write_dma_reg(PAS_DMA_TXF_CFLG1, 1 << flag);
}
EXPORT_SYMBOL(pasemi_dma_clear_flag);

/* pasemi_dma_alloc_fun - Allocate a function engine
 *
 * Allocates a function engine to use for crypto/checksum offload
 * Returns allocated engine (0-8), < 0 on error.
 */
int pasemi_dma_alloc_fun(void)
{
	int bit;

retry:
	bit = find_first_bit(fun_free, MAX_FLAGS);
	if (bit >= MAX_FLAGS)
		return -ENOSPC;
	if (!test_and_clear_bit(bit, fun_free))
		goto retry;

	return bit;
}
EXPORT_SYMBOL(pasemi_dma_alloc_fun);


/* pasemi_dma_free_fun - Deallocates a function engine
 * @flag: Engine number to deallocate
 *
 * Frees up a function engine so it can be used for other purposes.
 */
void pasemi_dma_free_fun(int fun)
{
	BUG_ON(test_bit(fun, fun_free));
	BUG_ON(fun >= MAX_FLAGS);
	set_bit(fun, fun_free);
}
EXPORT_SYMBOL(pasemi_dma_free_fun);


static void *map_onedev(struct pci_dev *p, int index)
{
	struct device_node *dn;
	void __iomem *ret;

	dn = pci_device_to_OF_node(p);
	if (!dn)
		goto fallback;

	ret = of_iomap(dn, index);
	if (!ret)
		goto fallback;

	return ret;
fallback:
	/* This is hardcoded and ugly, but we have some firmware versions
	 * that don't provide the register space in the device tree. Luckily
	 * they are at well-known locations so we can just do the math here.
	 */
	return ioremap(0xe0000000 + (p->devfn << 12), 0x2000);
}

/* pasemi_dma_init - Initialize the PA Semi DMA library
 *
 * This function initializes the DMA library. It must be called before
 * any other function in the library.
 *
 * Returns 0 on success, errno on failure.
 */
int pasemi_dma_init(void)
{
	static DEFINE_SPINLOCK(init_lock);
	struct pci_dev *iob_pdev;
	struct pci_dev *pdev;
	struct resource res;
	struct device_node *dn;
	int i, intf, err = 0;
	unsigned long timeout;
	u32 tmp;

	if (!machine_is(pasemi))
		return -ENODEV;

	spin_lock(&init_lock);

	/* Make sure we haven't already initialized */
	if (dma_pdev)
		goto out;

	iob_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa001, NULL);
	if (!iob_pdev) {
		BUG();
		pr_warn("Can't find I/O Bridge\n");
		err = -ENODEV;
		goto out;
	}
	iob_regs = map_onedev(iob_pdev, 0);

	dma_pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa007, NULL);
	if (!dma_pdev) {
		BUG();
		pr_warn("Can't find DMA controller\n");
		err = -ENODEV;
		goto out;
	}
	dma_regs = map_onedev(dma_pdev, 0);
	base_hw_irq = virq_to_hw(dma_pdev->irq);

	pci_read_config_dword(dma_pdev, PAS_DMA_CAP_TXCH, &tmp);
	num_txch = (tmp & PAS_DMA_CAP_TXCH_TCHN_M) >> PAS_DMA_CAP_TXCH_TCHN_S;

	pci_read_config_dword(dma_pdev, PAS_DMA_CAP_RXCH, &tmp);
	num_rxch = (tmp & PAS_DMA_CAP_RXCH_RCHN_M) >> PAS_DMA_CAP_RXCH_RCHN_S;

	intf = 0;
	for (pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa006, NULL);
	     pdev;
	     pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa006, pdev))
		mac_regs[intf++] = map_onedev(pdev, 0);

	pci_dev_put(pdev);

	for (pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa005, NULL);
	     pdev;
	     pdev = pci_get_device(PCI_VENDOR_ID_PASEMI, 0xa005, pdev))
		mac_regs[intf++] = map_onedev(pdev, 0);

	pci_dev_put(pdev);

	dn = pci_device_to_OF_node(iob_pdev);
	if (dn)
		err = of_address_to_resource(dn, 1, &res);
	if (!dn || err) {
		/* Fallback for old firmware */
		res.start = 0xfd800000;
		res.end = res.start + 0x1000;
	}
	dma_status = ioremap_cache(res.start, resource_size(&res));
	pci_dev_put(iob_pdev);

	for (i = 0; i < MAX_TXCH; i++)
		__set_bit(i, txch_free);

	for (i = 0; i < MAX_RXCH; i++)
		__set_bit(i, rxch_free);

	timeout = jiffies + HZ;
	pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, 0);
	while (pasemi_read_dma_reg(PAS_DMA_COM_RXSTA) & 1) {
		if (time_after(jiffies, timeout)) {
			pr_warn("Warning: Could not disable RX section\n");
			break;
		}
	}

	timeout = jiffies + HZ;
	pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, 0);
	while (pasemi_read_dma_reg(PAS_DMA_COM_TXSTA) & 1) {
		if (time_after(jiffies, timeout)) {
			pr_warn("Warning: Could not disable TX section\n");
			break;
		}
	}

	/* setup resource allocations for the different DMA sections */
	tmp = pasemi_read_dma_reg(PAS_DMA_COM_CFG);
	pasemi_write_dma_reg(PAS_DMA_COM_CFG, tmp | 0x18000000);

	/* enable tx section */
	pasemi_write_dma_reg(PAS_DMA_COM_TXCMD, PAS_DMA_COM_TXCMD_EN);

	/* enable rx section */
	pasemi_write_dma_reg(PAS_DMA_COM_RXCMD, PAS_DMA_COM_RXCMD_EN);

	for (i = 0; i < MAX_FLAGS; i++)
		__set_bit(i, flags_free);

	for (i = 0; i < MAX_FUN; i++)
		__set_bit(i, fun_free);

	/* clear all status flags */
	pasemi_write_dma_reg(PAS_DMA_TXF_CFLG0, 0xffffffff);
	pasemi_write_dma_reg(PAS_DMA_TXF_CFLG1, 0xffffffff);

	pr_info("PA Semi PWRficient DMA library initialized "
		"(%d tx, %d rx channels)\n", num_txch, num_rxch);

out:
	spin_unlock(&init_lock);
	return err;
}
EXPORT_SYMBOL(pasemi_dma_init);
