// 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;

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