// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * GE IMP3A Board Setup
 *
 * Author Martyn Welch <martyn.welch@ge.com>
 *
 * Copyright 2010 GE Intelligent Platforms Embedded Systems, Inc.
 *
 * Based on: mpc85xx_ds.c (MPC85xx DS Board Setup)
 * Copyright 2007 Freescale Semiconductor Inc.
 */

#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/kdev_t.h>
#include <linux/delay.h>
#include <linux/seq_file.h>
#include <linux/interrupt.h>
#include <linux/of.h>
#include <linux/of_address.h>

#include <asm/time.h>
#include <asm/machdep.h>
#include <asm/pci-bridge.h>
#include <mm/mmu_decl.h>
#include <asm/udbg.h>
#include <asm/mpic.h>
#include <asm/swiotlb.h>
#include <asm/nvram.h>

#include <sysdev/fsl_soc.h>
#include <sysdev/fsl_pci.h>
#include "smp.h"

#include "mpc85xx.h"
#include <sysdev/ge/ge_pic.h>

void __iomem *imp3a_regs;

static void __init ge_imp3a_pic_init(void)
{
	struct mpic *mpic;
	struct device_node *np;
	struct device_node *cascade_node = NULL;

	if (of_machine_is_compatible("fsl,MPC8572DS-CAMP")) {
		mpic = mpic_alloc(NULL, 0,
			MPIC_NO_RESET |
			MPIC_BIG_ENDIAN |
			MPIC_SINGLE_DEST_CPU,
			0, 256, " OpenPIC  ");
	} else {
		mpic = mpic_alloc(NULL, 0,
			  MPIC_BIG_ENDIAN |
			  MPIC_SINGLE_DEST_CPU,
			0, 256, " OpenPIC  ");
	}

	BUG_ON(mpic == NULL);
	mpic_init(mpic);
	/*
	 * There is a simple interrupt handler in the main FPGA, this needs
	 * to be cascaded into the MPIC
	 */
	for_each_node_by_type(np, "interrupt-controller")
		if (of_device_is_compatible(np, "gef,fpga-pic-1.00")) {
			cascade_node = np;
			break;
		}

	if (cascade_node == NULL) {
		printk(KERN_WARNING "IMP3A: No FPGA PIC\n");
		return;
	}

	gef_pic_init(cascade_node);
	of_node_put(cascade_node);
}

static void __init ge_imp3a_pci_assign_primary(void)
{
#ifdef CONFIG_PCI
	struct device_node *np;
	struct resource rsrc;

	for_each_node_by_type(np, "pci") {
		if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
		    of_device_is_compatible(np, "fsl,mpc8548-pcie") ||
		    of_device_is_compatible(np, "fsl,p2020-pcie")) {
			of_address_to_resource(np, 0, &rsrc);
			if ((rsrc.start & 0xfffff) == 0x9000) {
				of_node_put(fsl_pci_primary);
				fsl_pci_primary = of_node_get(np);
			}
		}
	}
#endif
}

/*
 * Setup the architecture
 */
static void __init ge_imp3a_setup_arch(void)
{
	struct device_node *regs;

	if (ppc_md.progress)
		ppc_md.progress("ge_imp3a_setup_arch()", 0);

	mpc85xx_smp_init();

	ge_imp3a_pci_assign_primary();

	swiotlb_detect_4g();

	/* Remap basic board registers */
	regs = of_find_compatible_node(NULL, NULL, "ge,imp3a-fpga-regs");
	if (regs) {
		imp3a_regs = of_iomap(regs, 0);
		if (imp3a_regs == NULL)
			printk(KERN_WARNING "Unable to map board registers\n");
		of_node_put(regs);
	}

#if defined(CONFIG_MMIO_NVRAM)
	mmio_nvram_init();
#endif

	printk(KERN_INFO "GE Intelligent Platforms IMP3A 3U cPCI SBC\n");
}

/* Return the PCB revision */
static unsigned int ge_imp3a_get_pcb_rev(void)
{
	unsigned int reg;

	reg = ioread16(imp3a_regs);
	return (reg >> 8) & 0xff;
}

/* Return the board (software) revision */
static unsigned int ge_imp3a_get_board_rev(void)
{
	unsigned int reg;

	reg = ioread16(imp3a_regs + 0x2);
	return reg & 0xff;
}

/* Return the FPGA revision */
static unsigned int ge_imp3a_get_fpga_rev(void)
{
	unsigned int reg;

	reg = ioread16(imp3a_regs + 0x2);
	return (reg >> 8) & 0xff;
}

/* Return compactPCI Geographical Address */
static unsigned int ge_imp3a_get_cpci_geo_addr(void)
{
	unsigned int reg;

	reg = ioread16(imp3a_regs + 0x6);
	return (reg & 0x0f00) >> 8;
}

/* Return compactPCI System Controller Status */
static unsigned int ge_imp3a_get_cpci_is_syscon(void)
{
	unsigned int reg;

	reg = ioread16(imp3a_regs + 0x6);
	return reg & (1 << 12);
}

static void ge_imp3a_show_cpuinfo(struct seq_file *m)
{
	seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n");

	seq_printf(m, "Revision\t: %u%c\n", ge_imp3a_get_pcb_rev(),
		('A' + ge_imp3a_get_board_rev() - 1));

	seq_printf(m, "FPGA Revision\t: %u\n", ge_imp3a_get_fpga_rev());

	seq_printf(m, "cPCI geo. addr\t: %u\n", ge_imp3a_get_cpci_geo_addr());

	seq_printf(m, "cPCI syscon\t: %s\n",
		ge_imp3a_get_cpci_is_syscon() ? "yes" : "no");
}

machine_arch_initcall(ge_imp3a, mpc85xx_common_publish_devices);

define_machine(ge_imp3a) {
	.name			= "GE_IMP3A",
	.compatible		= "ge,IMP3A",
	.setup_arch		= ge_imp3a_setup_arch,
	.init_IRQ		= ge_imp3a_pic_init,
	.show_cpuinfo		= ge_imp3a_show_cpuinfo,
#ifdef CONFIG_PCI
	.pcibios_fixup_bus	= fsl_pcibios_fixup_bus,
	.pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
#endif
	.get_irq		= mpic_get_irq,
	.progress		= udbg_progress,
};
