/*
 * 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;
	const 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 = 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",
	       (unsigned long) 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;
}
