// SPDX-License-Identifier: GPL-2.0
#include <linux/kernel.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/serial_core.h>
#include <linux/console.h>
#include <linux/pci.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/serial_reg.h>
#include <asm/io.h>
#include <asm/mmu.h>
#include <asm/serial.h>
#include <asm/udbg.h>
#include <asm/pci-bridge.h>
#include <asm/ppc-pci.h>
#include <asm/early_ioremap.h>

#undef DEBUG

#ifdef DEBUG
#define DBG(fmt...) do { printk(fmt); } while(0)
#else
#define DBG(fmt...) do { } while(0)
#endif

#define MAX_LEGACY_SERIAL_PORTS	8

static struct plat_serial8250_port
legacy_serial_ports[MAX_LEGACY_SERIAL_PORTS+1];
static struct legacy_serial_info {
	struct device_node		*np;
	unsigned int			speed;
	unsigned int			clock;
	int				irq_check_parent;
	phys_addr_t			taddr;
	void __iomem			*early_addr;
} legacy_serial_infos[MAX_LEGACY_SERIAL_PORTS];

static const struct of_device_id legacy_serial_parents[] __initconst = {
	{.type = "soc",},
	{.type = "tsi-bridge",},
	{.type = "opb", },
	{.compatible = "ibm,opb",},
	{.compatible = "simple-bus",},
	{.compatible = "wrs,epld-localbus",},
	{},
};

static unsigned int legacy_serial_count;
static int legacy_serial_console = -1;

static const upf_t legacy_port_flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST |
	UPF_SHARE_IRQ | UPF_FIXED_PORT;

static unsigned int tsi_serial_in(struct uart_port *p, int offset)
{
	unsigned int tmp;
	offset = offset << p->regshift;
	if (offset == UART_IIR) {
		tmp = readl(p->membase + (UART_IIR & ~3));
		return (tmp >> 16) & 0xff; /* UART_IIR % 4 == 2 */
	} else
		return readb(p->membase + offset);
}

static void tsi_serial_out(struct uart_port *p, int offset, int value)
{
	offset = offset << p->regshift;
	if (!((offset == UART_IER) && (value & UART_IER_UUE)))
		writeb(value, p->membase + offset);
}

static int __init add_legacy_port(struct device_node *np, int want_index,
				  int iotype, phys_addr_t base,
				  phys_addr_t taddr, unsigned long irq,
				  upf_t flags, int irq_check_parent)
{
	const __be32 *clk, *spd, *rs;
	u32 clock = BASE_BAUD * 16;
	u32 shift = 0;
	int index;

	/* get clock freq. if present */
	clk = of_get_property(np, "clock-frequency", NULL);
	if (clk && *clk)
		clock = be32_to_cpup(clk);

	/* get default speed if present */
	spd = of_get_property(np, "current-speed", NULL);

	/* get register shift if present */
	rs = of_get_property(np, "reg-shift", NULL);
	if (rs && *rs)
		shift = be32_to_cpup(rs);

	/* If we have a location index, then try to use it */
	if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS)
		index = want_index;
	else
		index = legacy_serial_count;

	/* if our index is still out of range, that mean that
	 * array is full, we could scan for a free slot but that
	 * make little sense to bother, just skip the port
	 */
	if (index >= MAX_LEGACY_SERIAL_PORTS)
		return -1;
	if (index >= legacy_serial_count)
		legacy_serial_count = index + 1;

	/* Check if there is a port who already claimed our slot */
	if (legacy_serial_infos[index].np != NULL) {
		/* if we still have some room, move it, else override */
		if (legacy_serial_count < MAX_LEGACY_SERIAL_PORTS) {
			printk(KERN_DEBUG "Moved legacy port %d -> %d\n",
			       index, legacy_serial_count);
			legacy_serial_ports[legacy_serial_count] =
				legacy_serial_ports[index];
			legacy_serial_infos[legacy_serial_count] =
				legacy_serial_infos[index];
			legacy_serial_count++;
		} else {
			printk(KERN_DEBUG "Replacing legacy port %d\n", index);
		}
	}

	/* Now fill the entry */
	memset(&legacy_serial_ports[index], 0,
	       sizeof(struct plat_serial8250_port));
	if (iotype == UPIO_PORT)
		legacy_serial_ports[index].iobase = base;
	else
		legacy_serial_ports[index].mapbase = base;

	legacy_serial_ports[index].iotype = iotype;
	legacy_serial_ports[index].uartclk = clock;
	legacy_serial_ports[index].irq = irq;
	legacy_serial_ports[index].flags = flags;
	legacy_serial_ports[index].regshift = shift;
	legacy_serial_infos[index].taddr = taddr;
	legacy_serial_infos[index].np = of_node_get(np);
	legacy_serial_infos[index].clock = clock;
	legacy_serial_infos[index].speed = spd ? be32_to_cpup(spd) : 0;
	legacy_serial_infos[index].irq_check_parent = irq_check_parent;

	if (iotype == UPIO_TSI) {
		legacy_serial_ports[index].serial_in = tsi_serial_in;
		legacy_serial_ports[index].serial_out = tsi_serial_out;
	}

	printk(KERN_DEBUG "Found legacy serial port %d for %pOF\n",
	       index, np);
	printk(KERN_DEBUG "  %s=%llx, taddr=%llx, irq=%lx, clk=%d, speed=%d\n",
	       (iotype == UPIO_PORT) ? "port" : "mem",
	       (unsigned long long)base, (unsigned long long)taddr, irq,
	       legacy_serial_ports[index].uartclk,
	       legacy_serial_infos[index].speed);

	return index;
}

static int __init add_legacy_soc_port(struct device_node *np,
				      struct device_node *soc_dev)
{
	u64 addr;
	const __be32 *addrp;
	struct device_node *tsi = of_get_parent(np);

	/* We only support ports that have a clock frequency properly
	 * encoded in the device-tree.
	 */
	if (!of_property_present(np, "clock-frequency"))
		return -1;

	/* if reg-offset don't try to use it */
	if (of_property_present(np, "reg-offset"))
		return -1;

	/* if rtas uses this device, don't try to use it as well */
	if (of_property_read_bool(np, "used-by-rtas"))
		return -1;

	/* Get the address */
	addrp = of_get_address(soc_dev, 0, NULL, NULL);
	if (addrp == NULL)
		return -1;

	addr = of_translate_address(soc_dev, addrp);
	if (addr == OF_BAD_ADDR)
		return -1;

	/* Add port, irq will be dealt with later. We passed a translated
	 * IO port value. It will be fixed up later along with the irq
	 */
	if (of_node_is_type(tsi, "tsi-bridge"))
		return add_legacy_port(np, -1, UPIO_TSI, addr, addr,
				       0, legacy_port_flags, 0);
	else
		return add_legacy_port(np, -1, UPIO_MEM, addr, addr,
				       0, legacy_port_flags, 0);
}

static int __init add_legacy_isa_port(struct device_node *np,
				      struct device_node *isa_brg)
{
	const __be32 *reg;
	const char *typep;
	int index = -1;
	u64 taddr;

	DBG(" -> add_legacy_isa_port(%pOF)\n", np);

	/* Get the ISA port number */
	reg = of_get_property(np, "reg", NULL);
	if (reg == NULL)
		return -1;

	/* Verify it's an IO port, we don't support anything else */
	if (!(be32_to_cpu(reg[0]) & 0x00000001))
		return -1;

	/* Now look for an "ibm,aix-loc" property that gives us ordering
	 * if any...
	 */
	typep = of_get_property(np, "ibm,aix-loc", NULL);

	/* If we have a location index, then use it */
	if (typep && *typep == 'S')
		index = simple_strtol(typep+1, NULL, 0) - 1;

	/* Translate ISA address. If it fails, we still register the port
	 * with no translated address so that it can be picked up as an IO
	 * port later by the serial driver
	 *
	 * Note: Don't even try on P8 lpc, we know it's not directly mapped
	 */
	if (!of_device_is_compatible(isa_brg, "ibm,power8-lpc") ||
	    of_property_present(isa_brg, "ranges")) {
		taddr = of_translate_address(np, reg);
		if (taddr == OF_BAD_ADDR)
			taddr = 0;
	} else
		taddr = 0;

	/* Add port, irq will be dealt with later */
	return add_legacy_port(np, index, UPIO_PORT, be32_to_cpu(reg[1]),
			       taddr, 0, legacy_port_flags, 0);

}

#ifdef CONFIG_PCI
static int __init add_legacy_pci_port(struct device_node *np,
				      struct device_node *pci_dev)
{
	u64 addr, base;
	const __be32 *addrp;
	unsigned int flags;
	int iotype, index = -1, lindex = 0;

	DBG(" -> add_legacy_pci_port(%pOF)\n", np);

	/* We only support ports that have a clock frequency properly
	 * encoded in the device-tree (that is have an fcode). Anything
	 * else can't be used that early and will be normally probed by
	 * the generic 8250_pci driver later on. The reason is that 8250
	 * compatible UARTs on PCI need all sort of quirks (port offsets
	 * etc...) that this code doesn't know about
	 */
	if (!of_property_present(np, "clock-frequency"))
		return -1;

	/* Get the PCI address. Assume BAR 0 */
	addrp = of_get_pci_address(pci_dev, 0, NULL, &flags);
	if (addrp == NULL)
		return -1;

	/* We only support BAR 0 for now */
	iotype = (flags & IORESOURCE_MEM) ? UPIO_MEM : UPIO_PORT;
	addr = of_translate_address(pci_dev, addrp);
	if (addr == OF_BAD_ADDR)
		return -1;

	/* Set the IO base to the same as the translated address for MMIO,
	 * or to the domain local IO base for PIO (it will be fixed up later)
	 */
	if (iotype == UPIO_MEM)
		base = addr;
	else
		base = of_read_number(&addrp[2], 1);

	/* Try to guess an index... If we have subdevices of the pci dev,
	 * we get to their "reg" property
	 */
	if (np != pci_dev) {
		const __be32 *reg = of_get_property(np, "reg", NULL);
		if (reg && (be32_to_cpup(reg) < 4))
			index = lindex = be32_to_cpup(reg);
	}

	/* Local index means it's the Nth port in the PCI chip. Unfortunately
	 * the offset to add here is device specific. We know about those
	 * EXAR ports and we default to the most common case. If your UART
	 * doesn't work for these settings, you'll have to add your own special
	 * cases here
	 */
	if (of_device_is_compatible(pci_dev, "pci13a8,152") ||
	    of_device_is_compatible(pci_dev, "pci13a8,154") ||
	    of_device_is_compatible(pci_dev, "pci13a8,158")) {
		addr += 0x200 * lindex;
		base += 0x200 * lindex;
	} else {
		addr += 8 * lindex;
		base += 8 * lindex;
	}

	/* Add port, irq will be dealt with later. We passed a translated
	 * IO port value. It will be fixed up later along with the irq
	 */
	return add_legacy_port(np, index, iotype, base, addr, 0,
			       legacy_port_flags, np != pci_dev);
}
#endif

static void __init setup_legacy_serial_console(int console)
{
	struct legacy_serial_info *info = &legacy_serial_infos[console];
	struct plat_serial8250_port *port = &legacy_serial_ports[console];
	unsigned int stride;

	stride = 1 << port->regshift;

	/* Check if a translated MMIO address has been found */
	if (info->taddr) {
		info->early_addr = early_ioremap(info->taddr, 0x1000);
		if (info->early_addr == NULL)
			return;
		udbg_uart_init_mmio(info->early_addr, stride);
	} else {
		/* Check if it's PIO and we support untranslated PIO */
		if (port->iotype == UPIO_PORT && isa_io_special)
			udbg_uart_init_pio(port->iobase, stride);
		else
			return;
	}

	/* Try to query the current speed */
	if (info->speed == 0)
		info->speed = udbg_probe_uart_speed(info->clock);

	/* Set it up */
	DBG("default console speed = %d\n", info->speed);
	udbg_uart_setup(info->speed, info->clock);
}

static int __init ioremap_legacy_serial_console(void)
{
	struct plat_serial8250_port *port;
	struct legacy_serial_info *info;
	void __iomem *vaddr;

	if (legacy_serial_console < 0)
		return 0;

	info = &legacy_serial_infos[legacy_serial_console];
	port = &legacy_serial_ports[legacy_serial_console];

	if (!info->early_addr)
		return 0;

	vaddr = ioremap(info->taddr, 0x1000);
	if (WARN_ON(!vaddr))
		return -ENOMEM;

	udbg_uart_init_mmio(vaddr, 1 << port->regshift);
	early_iounmap(info->early_addr, 0x1000);
	info->early_addr = NULL;

	return 0;
}
early_initcall(ioremap_legacy_serial_console);

/*
 * This is called very early, as part of setup_system() or eventually
 * setup_arch(), basically before anything else in this file. This function
 * will try to build a list of all the available 8250-compatible serial ports
 * in the machine using the Open Firmware device-tree. It currently only deals
 * with ISA and PCI busses but could be extended. It allows a very early boot
 * console to be initialized, that list is also used later to provide 8250 with
 * the machine non-PCI ports and to properly pick the default console port
 */
void __init find_legacy_serial_ports(void)
{
	struct device_node *np, *stdout = NULL;
	const char *path;
	int index;

	DBG(" -> find_legacy_serial_port()\n");

	/* Now find out if one of these is out firmware console */
	path = of_get_property(of_chosen, "linux,stdout-path", NULL);
	if (path == NULL)
		path = of_get_property(of_chosen, "stdout-path", NULL);
	if (path != NULL) {
		stdout = of_find_node_by_path(path);
		if (stdout)
			DBG("stdout is %pOF\n", stdout);
	} else {
		DBG(" no linux,stdout-path !\n");
	}

	/* Iterate over all the 16550 ports, looking for known parents */
	for_each_compatible_node(np, "serial", "ns16550") {
		struct device_node *parent = of_get_parent(np);
		if (!parent)
			continue;
		if (of_match_node(legacy_serial_parents, parent) != NULL) {
			if (of_device_is_available(np)) {
				index = add_legacy_soc_port(np, np);
				if (index >= 0 && np == stdout)
					legacy_serial_console = index;
			}
		}
		of_node_put(parent);
	}

	/* Next, fill our array with ISA ports */
	for_each_node_by_type(np, "serial") {
		struct device_node *isa = of_get_parent(np);
		if (of_node_name_eq(isa, "isa") || of_node_name_eq(isa, "lpc")) {
			if (of_device_is_available(np)) {
				index = add_legacy_isa_port(np, isa);
				if (index >= 0 && np == stdout)
					legacy_serial_console = index;
			}
		}
		of_node_put(isa);
	}

#ifdef CONFIG_PCI
	/* Next, try to locate PCI ports */
	for (np = NULL; (np = of_find_all_nodes(np));) {
		struct device_node *pci, *parent = of_get_parent(np);
		if (of_node_name_eq(parent, "isa")) {
			of_node_put(parent);
			continue;
		}
		if (!of_node_name_eq(np, "serial") &&
		    !of_node_is_type(np, "serial")) {
			of_node_put(parent);
			continue;
		}
		/* Check for known pciclass, and also check whether we have
		 * a device with child nodes for ports or not
		 */
		if (of_device_is_compatible(np, "pciclass,0700") ||
		    of_device_is_compatible(np, "pciclass,070002"))
			pci = np;
		else if (of_device_is_compatible(parent, "pciclass,0700") ||
			 of_device_is_compatible(parent, "pciclass,070002"))
			pci = parent;
		else {
			of_node_put(parent);
			continue;
		}
		index = add_legacy_pci_port(np, pci);
		if (index >= 0 && np == stdout)
			legacy_serial_console = index;
		of_node_put(parent);
	}
#endif

	of_node_put(stdout);

	DBG("legacy_serial_console = %d\n", legacy_serial_console);
	if (legacy_serial_console >= 0)
		setup_legacy_serial_console(legacy_serial_console);
	DBG(" <- find_legacy_serial_port()\n");
}

static struct platform_device serial_device = {
	.name	= "serial8250",
	.id	= PLAT8250_DEV_PLATFORM,
	.dev	= {
		.platform_data = legacy_serial_ports,
	},
};

static void __init fixup_port_irq(int index,
				  struct device_node *np,
				  struct plat_serial8250_port *port)
{
	unsigned int virq;

	DBG("fixup_port_irq(%d)\n", index);

	virq = irq_of_parse_and_map(np, 0);
	if (!virq && legacy_serial_infos[index].irq_check_parent) {
		np = of_get_parent(np);
		if (np == NULL)
			return;
		virq = irq_of_parse_and_map(np, 0);
		of_node_put(np);
	}
	if (!virq)
		return;

	port->irq = virq;

	if (IS_ENABLED(CONFIG_SERIAL_8250) &&
	    of_device_is_compatible(np, "fsl,ns16550")) {
		if (IS_REACHABLE(CONFIG_SERIAL_8250_FSL)) {
			port->handle_irq = fsl8250_handle_irq;
			port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_8250_CONSOLE);
		} else {
			pr_warn_once("Not activating Freescale specific workaround for device %pOFP\n",
				     np);
		}
	}
}

static void __init fixup_port_pio(int index,
				  struct device_node *np,
				  struct plat_serial8250_port *port)
{
#ifdef CONFIG_PCI
	struct pci_controller *hose;

	DBG("fixup_port_pio(%d)\n", index);

	hose = pci_find_hose_for_OF_device(np);
	if (hose) {
		unsigned long offset = (unsigned long)hose->io_base_virt -
#ifdef CONFIG_PPC64
			pci_io_base;
#else
			isa_io_base;
#endif
		DBG("port %d, IO %lx -> %lx\n",
		    index, port->iobase, port->iobase + offset);
		port->iobase += offset;
	}
#endif
}

static void __init fixup_port_mmio(int index,
				   struct device_node *np,
				   struct plat_serial8250_port *port)
{
	DBG("fixup_port_mmio(%d)\n", index);

	port->membase = ioremap(port->mapbase, 0x100);
}

/*
 * This is called as an arch initcall, hopefully before the PCI bus is
 * probed and/or the 8250 driver loaded since we need to register our
 * platform devices before 8250 PCI ones are detected as some of them
 * must properly "override" the platform ones.
 *
 * This function fixes up the interrupt value for platform ports as it
 * couldn't be done earlier before interrupt maps have been parsed. It
 * also "corrects" the IO address for PIO ports for the same reason,
 * since earlier, the PHBs virtual IO space wasn't assigned yet. It then
 * registers all those platform ports for use by the 8250 driver when it
 * finally loads.
 */
static int __init serial_dev_init(void)
{
	int i;

	if (legacy_serial_count == 0)
		return -ENODEV;

	/*
	 * Before we register the platform serial devices, we need
	 * to fixup their interrupts and their IO ports.
	 */
	DBG("Fixing serial ports interrupts and IO ports ...\n");

	for (i = 0; i < legacy_serial_count; i++) {
		struct plat_serial8250_port *port = &legacy_serial_ports[i];
		struct device_node *np = legacy_serial_infos[i].np;

		if (!port->irq)
			fixup_port_irq(i, np, port);
		if (port->iotype == UPIO_PORT)
			fixup_port_pio(i, np, port);
		if ((port->iotype == UPIO_MEM) || (port->iotype == UPIO_TSI))
			fixup_port_mmio(i, np, port);
	}

	DBG("Registering platform serial ports\n");

	return platform_device_register(&serial_device);
}
device_initcall(serial_dev_init);


#ifdef CONFIG_SERIAL_8250_CONSOLE
/*
 * This is called very early, as part of console_init() (typically just after
 * time_init()). This function is respondible for trying to find a good
 * default console on serial ports. It tries to match the open firmware
 * default output with one of the available serial console drivers that have
 * been probed earlier by find_legacy_serial_ports()
 */
static int __init check_legacy_serial_console(void)
{
	struct device_node *prom_stdout = NULL;
	int i, speed = 0, offset = 0;
	const char *name;
	const __be32 *spd;

	DBG(" -> check_legacy_serial_console()\n");

	/* The user has requested a console so this is already set up. */
	if (strstr(boot_command_line, "console=")) {
		DBG(" console was specified !\n");
		return -EBUSY;
	}

	if (!of_chosen) {
		DBG(" of_chosen is NULL !\n");
		return -ENODEV;
	}

	if (legacy_serial_console < 0) {
		DBG(" legacy_serial_console not found !\n");
		return -ENODEV;
	}
	/* We are getting a weird phandle from OF ... */
	/* ... So use the full path instead */
	name = of_get_property(of_chosen, "linux,stdout-path", NULL);
	if (name == NULL)
		name = of_get_property(of_chosen, "stdout-path", NULL);
	if (name == NULL) {
		DBG(" no stdout-path !\n");
		return -ENODEV;
	}
	prom_stdout = of_find_node_by_path(name);
	if (!prom_stdout) {
		DBG(" can't find stdout package %s !\n", name);
		return -ENODEV;
	}
	DBG("stdout is %pOF\n", prom_stdout);

	name = of_get_property(prom_stdout, "name", NULL);
	if (!name) {
		DBG(" stdout package has no name !\n");
		goto not_found;
	}
	spd = of_get_property(prom_stdout, "current-speed", NULL);
	if (spd)
		speed = be32_to_cpup(spd);

	if (strcmp(name, "serial") != 0)
		goto not_found;

	/* Look for it in probed array */
	for (i = 0; i < legacy_serial_count; i++) {
		if (prom_stdout != legacy_serial_infos[i].np)
			continue;
		offset = i;
		speed = legacy_serial_infos[i].speed;
		break;
	}
	if (i >= legacy_serial_count)
		goto not_found;

	of_node_put(prom_stdout);

	DBG("Found serial console at ttyS%d\n", offset);

	if (speed) {
		static char __initdata opt[16];
		sprintf(opt, "%d", speed);
		return add_preferred_console("ttyS", offset, opt);
	} else
		return add_preferred_console("ttyS", offset, NULL);

 not_found:
	DBG("No preferred console found !\n");
	of_node_put(prom_stdout);
	return -ENODEV;
}
console_initcall(check_legacy_serial_console);

#endif /* CONFIG_SERIAL_8250_CONSOLE */
