/*
 * Copyright 2004 Freescale Semiconductor.
 * Copyright (C) 2003 Motorola Inc.
 * Xianghua Xiao (x.xiao@motorola.com)
 *
 * 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
 */

/*
 * PCI Configuration space access support for MPC85xx PCI Bridge
 */
#include <common.h>
#include <asm/cpm_85xx.h>
#include <pci.h>


#if defined(CONFIG_PCI)

static struct pci_controller *pci_hose;

void
pci_mpc85xx_init(struct pci_controller *board_hose)
{
	u16 reg16;
	u32 dev;

	volatile immap_t    *immap = (immap_t *)CFG_CCSRBAR;
	volatile ccsr_pcix_t *pcix = &immap->im_pcix;
	volatile ccsr_pcix_t *pcix2 = &immap->im_pcix2;
	volatile ccsr_gur_t *gur = &immap->im_gur;
	struct pci_controller * hose;

	pci_hose = board_hose;

	hose = &pci_hose[0];

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

	pci_setup_indirect(hose,
			   (CFG_IMMR+0x8000),
			   (CFG_IMMR+0x8004));

	/*
	 * Hose scan.
	 */
	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);

	if (!(gur->pordevsr & PORDEVSR_PCI)) {
		/* PCI-X init */
		if (CONFIG_SYS_CLK_FREQ < 66000000)
			printf("PCI-X will only work at 66 MHz\n");

		reg16 = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ
			| PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E;
		pci_hose_write_config_word(hose, dev, PCIX_COMMAND, reg16);
	}

	pcix->potar1   = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
	pcix->potear1  = 0x00000000;
	pcix->powbar1  = (CFG_PCI1_MEM_PHYS >> 12) & 0x000fffff;
	pcix->powbear1 = 0x00000000;
	pcix->powar1 = (POWAR_EN | POWAR_MEM_READ |
			POWAR_MEM_WRITE | POWAR_MEM_512M);

	pcix->potar2  = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
	pcix->potear2  = 0x00000000;
	pcix->powbar2  = (CFG_PCI1_IO_PHYS >> 12) & 0x000fffff;
	pcix->powbear2 = 0x00000000;
	pcix->powar2 = (POWAR_EN | POWAR_IO_READ |
			POWAR_IO_WRITE | POWAR_IO_1M);

	pcix->pitar1 = 0x00000000;
	pcix->piwbar1 = 0x00000000;
	pcix->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
			PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G);

	pcix->powar3 = 0;
	pcix->powar4 = 0;
	pcix->piwar2 = 0;
	pcix->piwar3 = 0;

	pci_set_region(hose->regions + 0,
		       CFG_PCI1_MEM_BASE,
		       CFG_PCI1_MEM_PHYS,
		       CFG_PCI1_MEM_SIZE,
		       PCI_REGION_MEM);

	pci_set_region(hose->regions + 1,
		       CFG_PCI1_IO_BASE,
		       CFG_PCI1_IO_PHYS,
		       CFG_PCI1_IO_SIZE,
		       PCI_REGION_IO);

	hose->region_count = 2;

	pci_register_hose(hose);

#if defined(CONFIG_MPC8555CDS) || defined(CONFIG_MPC8541CDS)
	/*
	 * This is a SW workaround for an apparent HW problem
	 * in the PCI controller on the MPC85555/41 CDS boards.
	 * The first config cycle must be to a valid, known
	 * device on the PCI bus in order to trick the PCI
	 * controller state machine into a known valid state.
	 * Without this, the first config cycle has the chance
	 * of hanging the controller permanently, just leaving
	 * it in a semi-working state, or leaving it working.
	 *
	 * Pick on the Tundra, Device 17, to get it right.
	 */
	{
		u8 header_type;

		pci_hose_read_config_byte(hose,
					  PCI_BDF(0,17,0),
					  PCI_HEADER_TYPE,
					  &header_type);
	}
#endif

	hose->last_busno = pci_hose_scan(hose);

#ifdef CONFIG_MPC85XX_PCI2
	hose = &pci_hose[1];

	hose->first_busno = pci_hose[0].last_busno + 1;
	hose->last_busno = 0xff;

	pci_setup_indirect(hose,
			   (CFG_IMMR+0x9000),
			   (CFG_IMMR+0x9004));

	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);

	pcix2->potar1   = (CFG_PCI2_MEM_BASE >> 12) & 0x000fffff;
	pcix2->potear1  = 0x00000000;
	pcix2->powbar1  = (CFG_PCI2_MEM_PHYS >> 12) & 0x000fffff;
	pcix2->powbear1 = 0x00000000;
	pcix2->powar1 = (POWAR_EN | POWAR_MEM_READ |
			POWAR_MEM_WRITE | POWAR_MEM_512M);

	pcix2->potar2  = (CFG_PCI2_IO_BASE >> 12) & 0x000fffff;
	pcix2->potear2  = 0x00000000;
	pcix2->powbar2  = (CFG_PCI2_IO_PHYS >> 12) & 0x000fffff;
	pcix2->powbear2 = 0x00000000;
	pcix2->powar2 = (POWAR_EN | POWAR_IO_READ |
			POWAR_IO_WRITE | POWAR_IO_1M);

	pcix2->pitar1 = 0x00000000;
	pcix2->piwbar1 = 0x00000000;
	pcix2->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
			PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G);

	pcix2->powar3 = 0;
	pcix2->powar4 = 0;
	pcix2->piwar2 = 0;
	pcix2->piwar3 = 0;

	pci_set_region(hose->regions + 0,
		       CFG_PCI2_MEM_BASE,
		       CFG_PCI2_MEM_PHYS,
		       CFG_PCI2_MEM_SIZE,
		       PCI_REGION_MEM);

	pci_set_region(hose->regions + 1,
		       CFG_PCI2_IO_BASE,
		       CFG_PCI2_IO_PHYS,
		       CFG_PCI2_IO_SIZE,
		       PCI_REGION_IO);

	hose->region_count = 2;

	/*
	 * Hose scan.
	 */
	pci_register_hose(hose);

	hose->last_busno = pci_hose_scan(hose);
#endif
}

#ifdef CONFIG_OF_FLAT_TREE
void
ft_pci_setup(void *blob, bd_t *bd)
{
	u32 *p;
	int len;

	p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8000/bus-range", &len);
	if (p != NULL) {
		p[0] = pci_hose[0].first_busno;
		p[1] = pci_hose[0].last_busno;
	}

#ifdef CONFIG_MPC85XX_PCI2
	p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@9000/bus-range", &len);
	if (p != NULL) {
		p[0] = pci_hose[1].first_busno;
		p[1] = pci_hose[1].last_busno;
	}
#endif
}
#endif /* CONFIG_OF_FLAT_TREE */
#endif /* CONFIG_PCI */
