/*
 * Board setup routines for the Motorola/Emerson MVME5100.
 *
 * Copyright 2013 CSC Australia Pty. Ltd.
 *
 * Based on earlier code by:
 *
 *    Matt Porter, MontaVista Software Inc.
 *    Copyright 2001 MontaVista Software Inc.
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 *
 * Author: Stephen Chivers <schivers@csc.com>
 *
 */

#include <linux/of_platform.h>

#include <asm/i8259.h>
#include <asm/pci-bridge.h>
#include <asm/mpic.h>
#include <asm/prom.h>
#include <mm/mmu_decl.h>
#include <asm/udbg.h>

#define HAWK_MPIC_SIZE		0x00040000U
#define MVME5100_PCI_MEM_OFFSET 0x00000000

/* Board register addresses. */
#define BOARD_STATUS_REG	0xfef88080
#define BOARD_MODFAIL_REG	0xfef88090
#define BOARD_MODRST_REG	0xfef880a0
#define BOARD_TBEN_REG		0xfef880c0
#define BOARD_SW_READ_REG	0xfef880e0
#define BOARD_GEO_ADDR_REG	0xfef880e8
#define BOARD_EXT_FEATURE1_REG	0xfef880f0
#define BOARD_EXT_FEATURE2_REG	0xfef88100

static phys_addr_t pci_membase;
static u_char *restart;

static void mvme5100_8259_cascade(unsigned int irq, struct irq_desc *desc)
{
	struct irq_chip *chip = irq_desc_get_chip(desc);
	unsigned int cascade_irq = i8259_irq();

	if (cascade_irq != NO_IRQ)
		generic_handle_irq(cascade_irq);

	chip->irq_eoi(&desc->irq_data);
}

static void __init mvme5100_pic_init(void)
{
	struct mpic *mpic;
	struct device_node *np;
	struct device_node *cp = NULL;
	unsigned int cirq;
	unsigned long intack = 0;
	const u32 *prop = NULL;

	np = of_find_node_by_type(NULL, "open-pic");
	if (!np) {
		pr_err("Could not find open-pic node\n");
		return;
	}

	mpic = mpic_alloc(np, pci_membase, 0, 16, 256, " OpenPIC  ");

	BUG_ON(mpic == NULL);
	of_node_put(np);

	mpic_assign_isu(mpic, 0, pci_membase + 0x10000);

	mpic_init(mpic);

	cp = of_find_compatible_node(NULL, NULL, "chrp,iic");
	if (cp == NULL) {
		pr_warn("mvme5100_pic_init: couldn't find i8259\n");
		return;
	}

	cirq = irq_of_parse_and_map(cp, 0);
	if (cirq == NO_IRQ) {
		pr_warn("mvme5100_pic_init: no cascade interrupt?\n");
		return;
	}

	np = of_find_compatible_node(NULL, "pci", "mpc10x-pci");
	if (np) {
		prop = of_get_property(np, "8259-interrupt-acknowledge", NULL);

		if (prop)
			intack = prop[0];

		of_node_put(np);
	}

	if (intack)
		pr_debug("mvme5100_pic_init: PCI 8259 intack at 0x%016lx\n",
		   intack);

	i8259_init(cp, intack);
	of_node_put(cp);
	irq_set_chained_handler(cirq, mvme5100_8259_cascade);
}

static int __init mvme5100_add_bridge(struct device_node *dev)
{
	const int		*bus_range;
	int			len;
	struct pci_controller	*hose;
	unsigned short		devid;

	pr_info("Adding PCI host bridge %s\n", dev->full_name);

	bus_range = of_get_property(dev, "bus-range", &len);

	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, 0xfe000cf8, 0xfe000cfc, 0);

	pci_process_bridge_OF_ranges(hose, dev, 1);

	early_read_config_word(hose, 0, 0, PCI_DEVICE_ID, &devid);

	if (devid != PCI_DEVICE_ID_MOTOROLA_HAWK) {
		pr_err("HAWK PHB not present?\n");
		return 0;
	}

	early_read_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_1, &pci_membase);

	if (pci_membase == 0) {
		pr_err("HAWK PHB mibar not correctly set?\n");
		return 0;
	}

	pr_info("mvme5100_pic_init: pci_membase: %x\n", pci_membase);

	return 0;
}

static struct of_device_id mvme5100_of_bus_ids[] __initdata = {
	{ .compatible = "hawk-bridge", },
	{},
};

/*
 * Setup the architecture
 */
static void __init mvme5100_setup_arch(void)
{
	struct device_node *np;

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

	for_each_compatible_node(np, "pci", "hawk-pci")
		mvme5100_add_bridge(np);

	restart = ioremap(BOARD_MODRST_REG, 4);
}


static void mvme5100_show_cpuinfo(struct seq_file *m)
{
	seq_puts(m, "Vendor\t\t: Motorola/Emerson\n");
	seq_puts(m, "Machine\t\t: MVME5100\n");
}

static void mvme5100_restart(char *cmd)
{

	local_irq_disable();
	mtmsr(mfmsr() | MSR_IP);

	out_8((u_char *) restart, 0x01);

	while (1)
		;
}

/*
 * Called very early, device-tree isn't unflattened
 */
static int __init mvme5100_probe(void)
{
	unsigned long root = of_get_flat_dt_root();

	return of_flat_dt_is_compatible(root, "MVME5100");
}

static int __init probe_of_platform_devices(void)
{

	of_platform_bus_probe(NULL, mvme5100_of_bus_ids, NULL);
	return 0;
}

machine_device_initcall(mvme5100, probe_of_platform_devices);

define_machine(mvme5100) {
	.name			= "MVME5100",
	.probe			= mvme5100_probe,
	.setup_arch		= mvme5100_setup_arch,
	.init_IRQ		= mvme5100_pic_init,
	.show_cpuinfo		= mvme5100_show_cpuinfo,
	.get_irq		= mpic_get_irq,
	.restart		= mvme5100_restart,
	.calibrate_decr		= generic_calibrate_decr,
	.progress		= udbg_progress,
};
