/*
 * MPC86XX pci setup code
 *
 * Recode: ZHANG WEI <wei.zhang@freescale.com>
 * Initial author: Xianghua Xiao <x.xiao@freescale.com>
 *
 * Copyright 2006 Freescale Semiconductor 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.
 */

#include <linux/types.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/serial.h>

#include <asm/system.h>
#include <asm/atomic.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/immap_86xx.h>
#include <asm/pci-bridge.h>
#include <sysdev/fsl_soc.h>

#include "mpc86xx.h"

#undef DEBUG

#ifdef DEBUG
#define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args)
#else
#define DBG(fmt, args...)
#endif

struct pcie_outbound_window_regs {
	uint    pexotar;               /* 0x.0 - PCI Express outbound translation address register */
	uint    pexotear;              /* 0x.4 - PCI Express outbound translation extended address register */
	uint    pexowbar;              /* 0x.8 - PCI Express outbound window base address register */
	char    res1[4];
	uint    pexowar;               /* 0x.10 - PCI Express outbound window attributes register */
	char    res2[12];
};

struct pcie_inbound_window_regs {
	uint    pexitar;               /* 0x.0 - PCI Express inbound translation address register */
	char    res1[4];
	uint    pexiwbar;              /* 0x.8 - PCI Express inbound window base address register */
	uint    pexiwbear;             /* 0x.c - PCI Express inbound window base extended address register */
	uint    pexiwar;               /* 0x.10 - PCI Express inbound window attributes register */
	char    res2[12];
};

static void __init setup_pcie_atmu(struct pci_controller *hose, struct resource *rsrc)
{
	volatile struct ccsr_pex *pcie;
	volatile struct pcie_outbound_window_regs *pcieow;
	volatile struct pcie_inbound_window_regs *pcieiw;
	int i = 0;

	DBG("PCIE memory map start 0x%x, size 0x%x\n", rsrc->start,
			rsrc->end - rsrc->start + 1);
	pcie = ioremap(rsrc->start, rsrc->end - rsrc->start + 1);

	/* Disable all windows (except pexowar0 since its ignored) */
	pcie->pexowar1 = 0;
	pcie->pexowar2 = 0;
 	pcie->pexowar3 = 0;
 	pcie->pexowar4 = 0;
 	pcie->pexiwar1 = 0;
 	pcie->pexiwar2 = 0;
 	pcie->pexiwar3 = 0;

 	pcieow = (struct pcie_outbound_window_regs *)&pcie->pexotar1;
 	pcieiw = (struct pcie_inbound_window_regs *)&pcie->pexitar1;

 	/* Setup outbound MEM window */
 	for(i = 0; i < 3; i++)
 		if (hose->mem_resources[i].flags & IORESOURCE_MEM){
 			DBG("PCIE MEM resource start 0x%08x, size 0x%08x.\n",
 				hose->mem_resources[i].start,
 				hose->mem_resources[i].end
 				  - hose->mem_resources[i].start + 1);
 			pcieow->pexotar = (hose->mem_resources[i].start) >> 12
 				& 0x000fffff;
 			pcieow->pexotear = 0;
 			pcieow->pexowbar = (hose->mem_resources[i].start) >> 12
 				& 0x000fffff;
 			/* Enable, Mem R/W */
 			pcieow->pexowar = 0x80044000 |
 				(__ilog2(hose->mem_resources[i].end
 					 - hose->mem_resources[i].start + 1)
 				 - 1);
 			pcieow++;
 		}

 	/* Setup outbound IO window */
 	if (hose->io_resource.flags & IORESOURCE_IO){
 		DBG("PCIE IO resource start 0x%08x, size 0x%08x, phy base 0x%08x.\n",
 			hose->io_resource.start,
 			hose->io_resource.end - hose->io_resource.start + 1,
 			hose->io_base_phys);
 		pcieow->pexotar = (hose->io_resource.start) >> 12 & 0x000fffff;
 		pcieow->pexotear = 0;
 		pcieow->pexowbar = (hose->io_base_phys) >> 12 & 0x000fffff;
 		/* Enable, IO R/W */
 		pcieow->pexowar = 0x80088000 | (__ilog2(hose->io_resource.end
 					- hose->io_resource.start + 1) - 1);
 	}

 	/* Setup 2G inbound Memory Window @ 0 */
 	pcieiw->pexitar = 0x00000000;
 	pcieiw->pexiwbar = 0x00000000;
 	/* Enable, Prefetch, Local Mem, Snoop R/W, 2G */
 	pcieiw->pexiwar = 0xa0f5501e;
}

static void __init
mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size)
{
	u16 cmd;
	unsigned int temps;

	DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n",
			pcie_offset, pcie_size);

	early_read_config_word(hose, 0, 0, PCI_COMMAND, &cmd);
	cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY
	    | PCI_COMMAND_IO;
	early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd);

	early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80);

	/* PCIE Bus, Fix the MPC8641D host bridge's location to bus 0xFF. */
	early_read_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, &temps);
	temps = (temps & 0xff000000) | (0xff) | (0x0 << 8) | (0xfe << 16);
	early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps);
}

int mpc86xx_exclude_device(u_char bus, u_char devfn)
{
	if (bus == 0 && PCI_SLOT(devfn) == 0)
		return PCIBIOS_DEVICE_NOT_FOUND;

	return PCIBIOS_SUCCESSFUL;
}

int __init add_bridge(struct device_node *dev)
{
	int len;
	struct pci_controller *hose;
	struct resource rsrc;
	int *bus_range;
	int has_address = 0;
	int primary = 0;

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

	/* Fetch host bridge registers address */
	has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);

	/* Get bus range if any */
	bus_range = (int *) get_property(dev, "bus-range", &len);
	if (bus_range == NULL || len < 2 * sizeof(int))
		printk(KERN_WARNING "Can't get bus-range for %s, assume"
		       " bus 0\n", dev->full_name);

	hose = pcibios_alloc_controller();
	if (!hose)
		return -ENOMEM;
	hose->arch_data = dev;
	hose->set_cfg_type = 1;

	/* last_busno = 0xfe cause by MPC8641 PCIE bug */
	hose->first_busno = bus_range ? bus_range[0] : 0x0;
	hose->last_busno = bus_range ? bus_range[1] : 0xfe;

	setup_indirect_pcie(hose, rsrc.start, rsrc.start + 0x4);

	/* Setup the PCIE host controller. */
	mpc86xx_setup_pcie(hose, rsrc.start, rsrc.end - rsrc.start + 1);

	if ((rsrc.start & 0xfffff) == 0x8000)
		primary = 1;

	printk(KERN_INFO "Found MPC86xx PCIE host bridge at 0x%08lx. "
	       "Firmware bus number: %d->%d\n",
		rsrc.start, hose->first_busno, hose->last_busno);

	DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n",
		hose, hose->cfg_addr, hose->cfg_data);

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

	/* Setup PEX window registers */
	setup_pcie_atmu(hose, &rsrc);

	return 0;
}
