// SPDX-License-Identifier: GPL-2.0-only
/*
 * arch/arm/mach-netx/xc.c
 *
 * Copyright (c) 2005 Sascha Hauer <s.hauer@pengutronix.de>, Pengutronix
 */

#include <linux/init.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/export.h>

#include <mach/hardware.h>
#include <mach/irqs.h>
#include <mach/netx-regs.h>

#include <mach/xc.h>

static DEFINE_MUTEX(xc_lock);

static int xc_in_use = 0;

struct fw_desc {
	unsigned int ofs;
	unsigned int size;
	unsigned int patch_ofs;
	unsigned int patch_entries;
};

struct fw_header {
	unsigned int magic;
	unsigned int type;
	unsigned int version;
	unsigned int reserved[5];
	struct fw_desc fw_desc[3];
} __attribute__ ((packed));

int xc_stop(struct xc *x)
{
	writel(RPU_HOLD_PC, x->xmac_base + NETX_XMAC_RPU_HOLD_PC_OFS);
	writel(TPU_HOLD_PC, x->xmac_base + NETX_XMAC_TPU_HOLD_PC_OFS);
	writel(XPU_HOLD_PC, x->xpec_base + NETX_XPEC_XPU_HOLD_PC_OFS);
	return 0;
}

int xc_start(struct xc *x)
{
	writel(0, x->xmac_base + NETX_XMAC_RPU_HOLD_PC_OFS);
	writel(0, x->xmac_base + NETX_XMAC_TPU_HOLD_PC_OFS);
	writel(0, x->xpec_base + NETX_XPEC_XPU_HOLD_PC_OFS);
	return 0;
}

int xc_running(struct xc *x)
{
	return (readl(x->xmac_base + NETX_XMAC_RPU_HOLD_PC_OFS) & RPU_HOLD_PC)
	    || (readl(x->xmac_base + NETX_XMAC_TPU_HOLD_PC_OFS) & TPU_HOLD_PC)
	    || (readl(x->xpec_base + NETX_XPEC_XPU_HOLD_PC_OFS) & XPU_HOLD_PC) ?
		0 : 1;
}

int xc_reset(struct xc *x)
{
	writel(0, x->xpec_base + NETX_XPEC_PC_OFS);
	return 0;
}

static int xc_check_ptr(struct xc *x, unsigned long adr, unsigned int size)
{
	if (adr >= NETX_PA_XMAC(x->no) &&
	    adr + size < NETX_PA_XMAC(x->no) + XMAC_MEM_SIZE)
		return 0;

	if (adr >= NETX_PA_XPEC(x->no) &&
	    adr + size < NETX_PA_XPEC(x->no) + XPEC_MEM_SIZE)
		return 0;

	dev_err(x->dev, "Illegal pointer in firmware found. aborting\n");

	return -1;
}

static int xc_patch(struct xc *x, const void *patch, int count)
{
	unsigned int val, adr;
	const unsigned int *data = patch;

	int i;
	for (i = 0; i < count; i++) {
		adr = *data++;
		val = *data++;
		if (xc_check_ptr(x, adr, 4) < 0)
			return -EINVAL;

		writel(val, (void __iomem *)io_p2v(adr));
	}
	return 0;
}

int xc_request_firmware(struct xc *x)
{
	int ret;
	char name[16];
	const struct firmware *fw;
	struct fw_header *head;
	unsigned int size;
	int i;
	const void *src;
	unsigned long dst;

	sprintf(name, "xc%d.bin", x->no);

	ret = request_firmware(&fw, name, x->dev);

	if (ret < 0) {
		dev_err(x->dev, "request_firmware failed\n");
		return ret;
	}

	head = (struct fw_header *)fw->data;
	if (head->magic != 0x4e657458) {
		if (head->magic == 0x5874654e) {
			dev_err(x->dev,
			    "firmware magic is 'XteN'. Endianness problems?\n");
			ret = -ENODEV;
			goto exit_release_firmware;
		}
		dev_err(x->dev, "unrecognized firmware magic 0x%08x\n",
			head->magic);
		ret = -ENODEV;
		goto exit_release_firmware;
	}

	x->type = head->type;
	x->version = head->version;

	ret = -EINVAL;

	for (i = 0; i < 3; i++) {
		src = fw->data + head->fw_desc[i].ofs;
		dst = *(unsigned int *)src;
		src += sizeof (unsigned int);
		size = head->fw_desc[i].size - sizeof (unsigned int);

		if (xc_check_ptr(x, dst, size))
			goto exit_release_firmware;

		memcpy((void *)io_p2v(dst), src, size);

		src = fw->data + head->fw_desc[i].patch_ofs;
		size = head->fw_desc[i].patch_entries;
		ret = xc_patch(x, src, size);
		if (ret < 0)
			goto exit_release_firmware;
	}

	ret = 0;

      exit_release_firmware:
	release_firmware(fw);

	return ret;
}

struct xc *request_xc(int xcno, struct device *dev)
{
	struct xc *x = NULL;

	mutex_lock(&xc_lock);

	if (xcno > 3)
		goto exit;
	if (xc_in_use & (1 << xcno))
		goto exit;

	x = kmalloc(sizeof (struct xc), GFP_KERNEL);
	if (!x)
		goto exit;

	if (!request_mem_region
	    (NETX_PA_XPEC(xcno), XPEC_MEM_SIZE, kobject_name(&dev->kobj)))
		goto exit_free;

	if (!request_mem_region
	    (NETX_PA_XMAC(xcno), XMAC_MEM_SIZE, kobject_name(&dev->kobj)))
		goto exit_release_1;

	if (!request_mem_region
	    (SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE, kobject_name(&dev->kobj)))
		goto exit_release_2;

	x->xpec_base = (void * __iomem)io_p2v(NETX_PA_XPEC(xcno));
	x->xmac_base = (void * __iomem)io_p2v(NETX_PA_XMAC(xcno));
	x->sram_base = ioremap(SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE);
	if (!x->sram_base)
		goto exit_release_3;

	x->irq = NETX_IRQ_XPEC(xcno);

	x->no = xcno;
	x->dev = dev;

	xc_in_use |= (1 << xcno);

	goto exit;

      exit_release_3:
	release_mem_region(SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE);
      exit_release_2:
	release_mem_region(NETX_PA_XMAC(xcno), XMAC_MEM_SIZE);
      exit_release_1:
	release_mem_region(NETX_PA_XPEC(xcno), XPEC_MEM_SIZE);
      exit_free:
	kfree(x);
	x = NULL;
      exit:
	mutex_unlock(&xc_lock);
	return x;
}

void free_xc(struct xc *x)
{
	int xcno = x->no;

	mutex_lock(&xc_lock);

	iounmap(x->sram_base);
	release_mem_region(SRAM_INTERNAL_PHYS(xcno), SRAM_MEM_SIZE);
	release_mem_region(NETX_PA_XMAC(xcno), XMAC_MEM_SIZE);
	release_mem_region(NETX_PA_XPEC(xcno), XPEC_MEM_SIZE);
	xc_in_use &= ~(1 << x->no);
	kfree(x);

	mutex_unlock(&xc_lock);
}

EXPORT_SYMBOL(free_xc);
EXPORT_SYMBOL(request_xc);
EXPORT_SYMBOL(xc_request_firmware);
EXPORT_SYMBOL(xc_reset);
EXPORT_SYMBOL(xc_running);
EXPORT_SYMBOL(xc_start);
EXPORT_SYMBOL(xc_stop);
