/*
 * Copyright (C) 2009-2010 DENX Software Engineering <wd@denx.de>
 * Copyright (C) Freescale Semiconductor, Inc. 2006, 2007.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>

#include <asm/io.h>
#include <asm/mmu.h>
#include <asm/global_data.h>
#include <pci.h>
#if defined(CONFIG_OF_LIBFDT)
#include <libfdt.h>
#include <fdt_support.h>
#endif

DECLARE_GLOBAL_DATA_PTR;

/* System RAM mapped to PCI space */
#define CONFIG_PCI_SYS_MEM_BUS	CONFIG_SYS_SDRAM_BASE
#define CONFIG_PCI_SYS_MEM_PHYS	CONFIG_SYS_SDRAM_BASE

static struct pci_controller pci_hose;


/**************************************************************************
 * pci_init_board()
 *
 */
void
pci_init_board(void)
{
	volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
	volatile law512x_t *pci_law;
	volatile pot512x_t *pci_pot;
	volatile pcictrl512x_t *pci_ctrl;
	volatile pciconf512x_t *pci_conf;
	u16 reg16;
	u32 reg32;
	u32 dev;
	int i;
	struct pci_controller *hose;

	/* Set PCI divider for 33MHz */
	reg32 = in_be32(&im->clk.scfr[0]);
	reg32 &= ~(SCFR1_PCI_DIV_MASK);
	reg32 |= SCFR1_PCI_DIV << SCFR1_PCI_DIV_SHIFT;
	out_be32(&im->clk.scfr[0], reg32);

	clrsetbits_be32(&im->clk.scfr[0],
			SCFR1_PCI_DIV_MASK,
			SCFR1_PCI_DIV << SCFR1_PCI_DIV_SHIFT
	);

	pci_law = im->sysconf.pcilaw;
	pci_pot = im->ios.pot;
	pci_ctrl = &im->pci_ctrl;
	pci_conf = &im->pci_conf;

	hose = &pci_hose;

	/*
	 * Release PCI RST Output signal
	 */
	out_be32(&pci_ctrl->gcr, 0);
	udelay(2000);
	out_be32(&pci_ctrl->gcr, 1);

	/* We need to wait at least a 1sec based on PCI specs */
	for (i = 0; i < 1000; i++)
		udelay(1000);

	/*
	 * Configure PCI Local Access Windows
	 */
	out_be32(&pci_law[0].bar, CONFIG_SYS_PCI_MEM_PHYS & LAWBAR_BAR);
	out_be32(&pci_law[0].ar, LAWAR_EN | LAWAR_SIZE_512M);

	out_be32(&pci_law[1].bar, CONFIG_SYS_PCI_IO_PHYS & LAWBAR_BAR);
	out_be32(&pci_law[1].ar, LAWAR_EN | LAWAR_SIZE_16M);

	/*
	 * Configure PCI Outbound Translation Windows
	 */

	/* PCI mem space - prefetch */
	out_be32(&pci_pot[0].potar,
		(CONFIG_SYS_PCI_MEM_BASE >> 12) & POTAR_TA_MASK);
	out_be32(&pci_pot[0].pobar,
		(CONFIG_SYS_PCI_MEM_PHYS >> 12) & POBAR_BA_MASK);
	out_be32(&pci_pot[0].pocmr,
		POCMR_EN | POCMR_PRE | POCMR_CM_256M);

	/* PCI IO space */
	out_be32(&pci_pot[1].potar,
		(CONFIG_SYS_PCI_IO_BASE >> 12) & POTAR_TA_MASK);
	out_be32(&pci_pot[1].pobar,
		(CONFIG_SYS_PCI_IO_PHYS >> 12) & POBAR_BA_MASK);
	out_be32(&pci_pot[1].pocmr,
		POCMR_EN | POCMR_IO | POCMR_CM_16M);

	/* PCI mmio - non-prefetch mem space */
	out_be32(&pci_pot[2].potar,
		(CONFIG_SYS_PCI_MMIO_BASE >> 12) & POTAR_TA_MASK);
	out_be32(&pci_pot[2].pobar,
		(CONFIG_SYS_PCI_MMIO_PHYS >> 12) & POBAR_BA_MASK);
	out_be32(&pci_pot[2].pocmr,
		POCMR_EN | POCMR_CM_256M);

	/*
	 * Configure PCI Inbound Translation Windows
	 */

	/* we need RAM mapped to PCI space for the devices to
	 * access main memory */
	out_be32(&pci_ctrl[0].pitar1, 0x0);
	out_be32(&pci_ctrl[0].pibar1, 0x0);
	out_be32(&pci_ctrl[0].piebar1, 0x0);
	out_be32(&pci_ctrl[0].piwar1,
		PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP |
		PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1));

	hose->first_busno = 0;
	hose->last_busno = 0xff;

	/* PCI memory prefetch space */
	pci_set_region(hose->regions + 0,
		       CONFIG_SYS_PCI_MEM_BASE,
		       CONFIG_SYS_PCI_MEM_PHYS,
		       CONFIG_SYS_PCI_MEM_SIZE,
		       PCI_REGION_MEM|PCI_REGION_PREFETCH);

	/* PCI memory space */
	pci_set_region(hose->regions + 1,
		       CONFIG_SYS_PCI_MMIO_BASE,
		       CONFIG_SYS_PCI_MMIO_PHYS,
		       CONFIG_SYS_PCI_MMIO_SIZE,
		       PCI_REGION_MEM);

	/* PCI IO space */
	pci_set_region(hose->regions + 2,
		       CONFIG_SYS_PCI_IO_BASE,
		       CONFIG_SYS_PCI_IO_PHYS,
		       CONFIG_SYS_PCI_IO_SIZE,
		       PCI_REGION_IO);

	/* System memory space */
	pci_set_region(hose->regions + 3,
		       CONFIG_PCI_SYS_MEM_BUS,
		       CONFIG_PCI_SYS_MEM_PHYS,
		       gd->ram_size,
		       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);

	hose->region_count = 4;

	pci_setup_indirect(hose,
			   (CONFIG_SYS_IMMR + 0x8300),
			   (CONFIG_SYS_IMMR + 0x8304));

	pci_register_hose(hose);

	/*
	 * Write to Command register
	 */
	reg16 = 0xff;
	dev = PCI_BDF(hose->first_busno, 0, 0);
	pci_hose_read_config_word(hose, dev, PCI_COMMAND, &reg16);
	reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
	pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);

	/*
	 * Clear non-reserved bits in status register.
	 */
	pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
	pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
	pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);

#ifdef CONFIG_PCI_SCAN_SHOW
	printf("PCI:   Bus Dev VenId DevId Class Int\n");
#endif
	/*
	 * Hose scan.
	 */
	hose->last_busno = pci_hose_scan(hose);
}

#if defined(CONFIG_OF_LIBFDT)
void ft_pci_setup(void *blob, bd_t *bd)
{
	int nodeoffset;
	int tmp[2];
	const char *path;

	nodeoffset = fdt_path_offset(blob, "/aliases");
	if (nodeoffset >= 0) {
		path = fdt_getprop(blob, nodeoffset, "pci", NULL);
		if (path) {
			tmp[0] = cpu_to_be32(pci_hose.first_busno);
			tmp[1] = cpu_to_be32(pci_hose.last_busno);
			do_fixup_by_path(blob, path, "bus-range",
				&tmp, sizeof(tmp), 1);

			tmp[0] = cpu_to_be32(gd->pci_clk);
			do_fixup_by_path(blob, path, "clock-frequency",
				&tmp, sizeof(tmp[0]), 1);
		}
	}
}
#endif /* CONFIG_OF_LIBFDT */
