// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
/*
 * Freescale DPAA2 Platforms Console Driver
 *
 * Copyright 2015-2016 Freescale Semiconductor Inc.
 * Copyright 2018 NXP
 */

#define pr_fmt(fmt) "dpaa2-console: " fmt

#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/miscdevice.h>
#include <linux/platform_device.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/io.h>

/* MC firmware base low/high registers indexes */
#define MCFBALR_OFFSET 0
#define MCFBAHR_OFFSET 1

/* Bit masks used to get the most/least significant part of the MC base addr */
#define MC_FW_ADDR_MASK_HIGH 0x1FFFF
#define MC_FW_ADDR_MASK_LOW  0xE0000000

#define MC_BUFFER_OFFSET 0x01000000
#define MC_BUFFER_SIZE   (1024 * 1024 * 16)
#define MC_OFFSET_DELTA  MC_BUFFER_OFFSET

#define AIOP_BUFFER_OFFSET 0x06000000
#define AIOP_BUFFER_SIZE   (1024 * 1024 * 16)
#define AIOP_OFFSET_DELTA  0

#define LOG_HEADER_FLAG_BUFFER_WRAPAROUND 0x80000000
#define LAST_BYTE(a) ((a) & ~(LOG_HEADER_FLAG_BUFFER_WRAPAROUND))

/* MC and AIOP Magic words */
#define MAGIC_MC   0x4d430100
#define MAGIC_AIOP 0x41494F50

struct log_header {
	__le32 magic_word;
	char reserved[4];
	__le32 buf_start;
	__le32 buf_length;
	__le32 last_byte;
};

struct console_data {
	void __iomem *map_addr;
	struct log_header __iomem *hdr;
	void __iomem *start_addr;
	void __iomem *end_addr;
	void __iomem *end_of_data;
	void __iomem *cur_ptr;
};

static struct resource mc_base_addr;

static inline void adjust_end(struct console_data *cd)
{
	u32 last_byte = readl(&cd->hdr->last_byte);

	cd->end_of_data = cd->start_addr + LAST_BYTE(last_byte);
}

static u64 get_mc_fw_base_address(void)
{
	u64 mcfwbase = 0ULL;
	u32 __iomem *mcfbaregs;

	mcfbaregs = ioremap(mc_base_addr.start, resource_size(&mc_base_addr));
	if (!mcfbaregs) {
		pr_err("could not map MC Firmware Base registers\n");
		return 0;
	}

	mcfwbase  = readl(mcfbaregs + MCFBAHR_OFFSET) &
			  MC_FW_ADDR_MASK_HIGH;
	mcfwbase <<= 32;
	mcfwbase |= readl(mcfbaregs + MCFBALR_OFFSET) & MC_FW_ADDR_MASK_LOW;
	iounmap(mcfbaregs);

	pr_debug("MC base address at 0x%016llx\n", mcfwbase);
	return mcfwbase;
}

static ssize_t dpaa2_console_size(struct console_data *cd)
{
	ssize_t size;

	if (cd->cur_ptr <= cd->end_of_data)
		size = cd->end_of_data - cd->cur_ptr;
	else
		size = (cd->end_addr - cd->cur_ptr) +
			(cd->end_of_data - cd->start_addr);

	return size;
}

static int dpaa2_generic_console_open(struct inode *node, struct file *fp,
				      u64 offset, u64 size,
				      u32 expected_magic,
				      u32 offset_delta)
{
	u32 read_magic, wrapped, last_byte, buf_start, buf_length;
	struct console_data *cd;
	u64 base_addr;
	int err;

	cd = kmalloc(sizeof(*cd), GFP_KERNEL);
	if (!cd)
		return -ENOMEM;

	base_addr = get_mc_fw_base_address();
	if (!base_addr) {
		err = -EIO;
		goto err_fwba;
	}

	cd->map_addr = ioremap(base_addr + offset, size);
	if (!cd->map_addr) {
		pr_err("cannot map console log memory\n");
		err = -EIO;
		goto err_ioremap;
	}

	cd->hdr = (struct log_header __iomem *)cd->map_addr;
	read_magic = readl(&cd->hdr->magic_word);
	last_byte =  readl(&cd->hdr->last_byte);
	buf_start =  readl(&cd->hdr->buf_start);
	buf_length = readl(&cd->hdr->buf_length);

	if (read_magic != expected_magic) {
		pr_warn("expected = %08x, read = %08x\n",
			expected_magic, read_magic);
		err = -EIO;
		goto err_magic;
	}

	cd->start_addr = cd->map_addr + buf_start - offset_delta;
	cd->end_addr = cd->start_addr + buf_length;

	wrapped = last_byte & LOG_HEADER_FLAG_BUFFER_WRAPAROUND;

	adjust_end(cd);
	if (wrapped && cd->end_of_data != cd->end_addr)
		cd->cur_ptr = cd->end_of_data + 1;
	else
		cd->cur_ptr = cd->start_addr;

	fp->private_data = cd;

	return 0;

err_magic:
	iounmap(cd->map_addr);

err_ioremap:
err_fwba:
	kfree(cd);

	return err;
}

static int dpaa2_mc_console_open(struct inode *node, struct file *fp)
{
	return dpaa2_generic_console_open(node, fp,
					  MC_BUFFER_OFFSET, MC_BUFFER_SIZE,
					  MAGIC_MC, MC_OFFSET_DELTA);
}

static int dpaa2_aiop_console_open(struct inode *node, struct file *fp)
{
	return dpaa2_generic_console_open(node, fp,
					  AIOP_BUFFER_OFFSET, AIOP_BUFFER_SIZE,
					  MAGIC_AIOP, AIOP_OFFSET_DELTA);
}

static int dpaa2_console_close(struct inode *node, struct file *fp)
{
	struct console_data *cd = fp->private_data;

	iounmap(cd->map_addr);
	kfree(cd);
	return 0;
}

static ssize_t dpaa2_console_read(struct file *fp, char __user *buf,
				  size_t count, loff_t *f_pos)
{
	struct console_data *cd = fp->private_data;
	size_t bytes = dpaa2_console_size(cd);
	size_t bytes_end = cd->end_addr - cd->cur_ptr;
	size_t written = 0;
	void *kbuf;
	int err;

	/* Check if we need to adjust the end of data addr */
	adjust_end(cd);

	if (cd->end_of_data == cd->cur_ptr)
		return 0;

	if (count < bytes)
		bytes = count;

	kbuf = kmalloc(bytes, GFP_KERNEL);
	if (!kbuf)
		return -ENOMEM;

	if (bytes > bytes_end) {
		memcpy_fromio(kbuf, cd->cur_ptr, bytes_end);
		if (copy_to_user(buf, kbuf, bytes_end)) {
			err = -EFAULT;
			goto err_free_buf;
		}
		buf += bytes_end;
		cd->cur_ptr = cd->start_addr;
		bytes -= bytes_end;
		written += bytes_end;
	}

	memcpy_fromio(kbuf, cd->cur_ptr, bytes);
	if (copy_to_user(buf, kbuf, bytes)) {
		err = -EFAULT;
		goto err_free_buf;
	}
	cd->cur_ptr += bytes;
	written += bytes;

	kfree(kbuf);
	return written;

err_free_buf:
	kfree(kbuf);

	return err;
}

static const struct file_operations dpaa2_mc_console_fops = {
	.owner          = THIS_MODULE,
	.open           = dpaa2_mc_console_open,
	.release        = dpaa2_console_close,
	.read           = dpaa2_console_read,
};

static struct miscdevice dpaa2_mc_console_dev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "dpaa2_mc_console",
	.fops = &dpaa2_mc_console_fops
};

static const struct file_operations dpaa2_aiop_console_fops = {
	.owner          = THIS_MODULE,
	.open           = dpaa2_aiop_console_open,
	.release        = dpaa2_console_close,
	.read           = dpaa2_console_read,
};

static struct miscdevice dpaa2_aiop_console_dev = {
	.minor = MISC_DYNAMIC_MINOR,
	.name = "dpaa2_aiop_console",
	.fops = &dpaa2_aiop_console_fops
};

static int dpaa2_console_probe(struct platform_device *pdev)
{
	int error;

	error = of_address_to_resource(pdev->dev.of_node, 0, &mc_base_addr);
	if (error < 0) {
		pr_err("of_address_to_resource() failed for %pOF with %d\n",
		       pdev->dev.of_node, error);
		return error;
	}

	error = misc_register(&dpaa2_mc_console_dev);
	if (error) {
		pr_err("cannot register device %s\n",
		       dpaa2_mc_console_dev.name);
		goto err_register_mc;
	}

	error = misc_register(&dpaa2_aiop_console_dev);
	if (error) {
		pr_err("cannot register device %s\n",
		       dpaa2_aiop_console_dev.name);
		goto err_register_aiop;
	}

	return 0;

err_register_aiop:
	misc_deregister(&dpaa2_mc_console_dev);
err_register_mc:
	return error;
}

static void dpaa2_console_remove(struct platform_device *pdev)
{
	misc_deregister(&dpaa2_mc_console_dev);
	misc_deregister(&dpaa2_aiop_console_dev);
}

static const struct of_device_id dpaa2_console_match_table[] = {
	{ .compatible = "fsl,dpaa2-console",},
	{},
};

MODULE_DEVICE_TABLE(of, dpaa2_console_match_table);

static struct platform_driver dpaa2_console_driver = {
	.driver = {
		   .name = "dpaa2-console",
		   .pm = NULL,
		   .of_match_table = dpaa2_console_match_table,
		   },
	.probe = dpaa2_console_probe,
	.remove_new = dpaa2_console_remove,
};
module_platform_driver(dpaa2_console_driver);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Roy Pledge <roy.pledge@nxp.com>");
MODULE_DESCRIPTION("DPAA2 console driver");
