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

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

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

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_host(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);

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)
{
	if (of_machine_is_compatible("eyetech,amigaone")) {
		/*
		 * 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;
	}

	return 0;
}

define_machine(amigaone) {
	.name			= "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,
	.calibrate_decr		= generic_calibrate_decr,
	.progress		= udbg_progress,
};
