// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * AmigaOne platform setup
 *
 * Copyright 2008 Gerhard Pircher (gerhard_pircher@gmx.net)
 *
 *   Based on original amigaone_setup.c source code
 * Copyright 2003 by Hans-Joerg Frieden and Thomas Frieden
 */

#include <linux/irqdomain.h>
#include <linux/kernel.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/seq_file.h>
#include <generated/utsrelease.h>

#include <asm/machdep.h>
#include <asm/cputable.h>
#include <asm/pci-bridge.h>
#include <asm/i8259.h>
#include <asm/time.h>
#include <asm/udbg.h>
#include <asm/dma.h>

extern void __flush_disable_L1(void);

static void amigaone_show_cpuinfo(struct seq_file *m)
{
	seq_printf(m, "vendor\t\t: Eyetech Ltd.\n");
}

static int __init amigaone_add_bridge(struct device_node *dev)
{
	const u32 *cfg_addr, *cfg_data;
	int len;
	const int *bus_range;
	struct pci_controller *hose;

	printk(KERN_INFO "Adding PCI host bridge %pOF\n", dev);

	cfg_addr = of_get_address(dev, 0, NULL, NULL);
	cfg_data = of_get_address(dev, 1, NULL, NULL);
	if ((cfg_addr == NULL) || (cfg_data == NULL))
		return -ENODEV;

	bus_range = of_get_property(dev, "bus-range", &len);
	if ((bus_range == NULL) || (len < 2 * sizeof(int)))
		printk(KERN_WARNING "Can't get bus-range for %pOF, assume"
		       " bus 0\n", dev);

	hose = pcibios_alloc_controller(dev);
	if (hose == NULL)
		return -ENOMEM;

	hose->first_busno = bus_range ? bus_range[0] : 0;
	hose->last_busno = bus_range ? bus_range[1] : 0xff;

	setup_indirect_pci(hose, cfg_addr[0], cfg_data[0], 0);

	/* Interpret the "ranges" property */
	/* This also maps the I/O region and sets isa_io/mem_base */
	pci_process_bridge_OF_ranges(hose, dev, 1);

	return 0;
}

static void __init amigaone_setup_arch(void)
{
	if (ppc_md.progress)
		ppc_md.progress("Linux/PPC "UTS_RELEASE"\n", 0);
}

static void __init amigaone_discover_phbs(void)
{
	struct device_node *np;
	int phb = -ENODEV;

	/* Lookup PCI host bridges. */
	for_each_compatible_node(np, "pci", "mai-logic,articia-s")
		phb = amigaone_add_bridge(np);

	BUG_ON(phb != 0);
}

static void __init amigaone_init_IRQ(void)
{
	struct device_node *pic, *np = NULL;
	const unsigned long *prop = NULL;
	unsigned long int_ack = 0;

	/* Search for ISA interrupt controller. */
	pic = of_find_compatible_node(NULL, "interrupt-controller",
	                              "pnpPNP,000");
	BUG_ON(pic == NULL);

	/* Look for interrupt acknowledge address in the PCI root node. */
	np = of_find_compatible_node(NULL, "pci", "mai-logic,articia-s");
	if (np) {
		prop = of_get_property(np, "8259-interrupt-acknowledge", NULL);
		if (prop)
			int_ack = prop[0];
		of_node_put(np);
	}

	if (int_ack == 0)
		printk(KERN_WARNING "Cannot find PCI interrupt acknowledge"
		       " address, polling\n");

	i8259_init(pic, int_ack);
	ppc_md.get_irq = i8259_irq;
	irq_set_default_domain(i8259_get_host());
}

static int __init request_isa_regions(void)
{
	request_region(0x00, 0x20, "dma1");
	request_region(0x40, 0x20, "timer");
	request_region(0x80, 0x10, "dma page reg");
	request_region(0xc0, 0x20, "dma2");

	return 0;
}
machine_device_initcall(amigaone, request_isa_regions);

static void __noreturn amigaone_restart(char *cmd)
{
	local_irq_disable();

	/* Flush and disable caches. */
	__flush_disable_L1();

        /* Set SRR0 to the reset vector and turn on MSR_IP. */
	mtspr(SPRN_SRR0, 0xfff00100);
	mtspr(SPRN_SRR1, MSR_IP);

	/* Do an rfi to jump back to firmware. */
	__asm__ __volatile__("rfi" : : : "memory");

	/* Not reached. */
	while (1);
}

static int __init amigaone_probe(void)
{
	/*
	 * Coherent memory access cause complete system lockup! Thus
	 * disable this CPU feature, even if the CPU needs it.
	 */
	cur_cpu_spec->cpu_features &= ~CPU_FTR_NEED_COHERENT;

	DMA_MODE_READ = 0x44;
	DMA_MODE_WRITE = 0x48;

	return 1;
}

define_machine(amigaone) {
	.name			= "AmigaOne",
	.compatible		= "eyetech,amigaone",
	.probe			= amigaone_probe,
	.setup_arch		= amigaone_setup_arch,
	.discover_phbs		= amigaone_discover_phbs,
	.show_cpuinfo		= amigaone_show_cpuinfo,
	.init_IRQ		= amigaone_init_IRQ,
	.restart		= amigaone_restart,
	.progress		= udbg_progress,
};
