// 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_device.h>
#include <linux/of_address.h>
#include <linux/miscdevice.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;

	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 int dpaa2_console_remove(struct platform_device *pdev)
{
	misc_deregister(&dpaa2_mc_console_dev);
	misc_deregister(&dpaa2_aiop_console_dev);

	return 0;
}

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 = 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");
