/*
 * Copyright (C) Freescale Semiconductor, Inc. 2006, 2007. All rights reserved.
 * Copyright (C) 2009 DENX Software Engineering <wd@denx.de>
 *
 * 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 = im->clk.scfr[0];
	reg32 &= ~(SCFR1_PCI_DIV_MASK);
	reg32 |= SCFR1_PCI_DIV << SCFR1_PCI_DIV_SHIFT;
	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 */
