/*
 * (C) Copyright 2001
 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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
 */

#include <common.h>
#include <ppc4xx.h>
#include <asm/processor.h>
#include <pci.h>


u_long pci9054_iobase;


#define PCI_PRIMARY_CAR	(0x500000dc) /* PCI config address reg */
#define PCI_PRIMARY_CDR	(0x80000000) /* PCI config data    reg */


/*-----------------------------------------------------------------------------+
|  Subroutine:  pci9054_read_config_dword
|  Description: Read a PCI configuration register
|  Inputs:
|               hose            PCI Controller
|               dev             PCI Bus+Device+Function number
|               offset          Configuration register number
|               value           Address of the configuration register value
|  Return value:
|               0               Successful
+-----------------------------------------------------------------------------*/
int pci9054_read_config_dword(struct pci_controller *hose,
			      pci_dev_t dev, int offset, u32* value)
{
  unsigned long      conAdrVal;
  unsigned long      val;

  /* generate coded value for CON_ADR register */
  conAdrVal = dev | (offset & 0xfc) | 0x80000000;

  /* Load the CON_ADR (CAR) value first, then read from CON_DATA (CDR) */
  *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal;

  /* Note: *pResult comes back as -1 if machine check happened */
  val = in32r(PCI_PRIMARY_CDR);

  *value = (unsigned long) val;

  out32r(PCI_PRIMARY_CAR, 0);

  if ((*(unsigned long *)0x50000304) & 0x60000000)
    {
      /* clear pci master/target abort bits */
      *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304;
    }

  return 0;
}

/*-----------------------------------------------------------------------------+
|  Subroutine:  pci9054_write_config_dword
|  Description: Write a PCI configuration register.
|  Inputs:
|               hose            PCI Controller
|               dev             PCI Bus+Device+Function number
|               offset          Configuration register number
|               Value           Configuration register value
|  Return value:
|               0               Successful
| Updated for pass2 errata #6. Need to disable interrupts and clear the
| PCICFGADR reg after writing the PCICFGDATA reg.
+-----------------------------------------------------------------------------*/
int pci9054_write_config_dword(struct pci_controller *hose,
			       pci_dev_t dev, int offset, u32 value)
{
  unsigned long      conAdrVal;

  conAdrVal = dev | (offset & 0xfc) | 0x80000000;

  *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal;

  out32r(PCI_PRIMARY_CDR, value);

  out32r(PCI_PRIMARY_CAR, 0);

  /* clear pci master/target abort bits */
  *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304;

  return (0);
}

/*-----------------------------------------------------------------------
 */

#ifdef CONFIG_DASA_SIM
static void pci_dasa_sim_config_pci9054(struct pci_controller *hose, pci_dev_t dev,
					struct pci_config_table *_)
{
  unsigned int iobase;
  unsigned short status = 0;
  unsigned char timer;

  /*
   * Configure PLX PCI9054
   */
  pci_read_config_word(CFG_PCI9054_DEV_FN, PCI_COMMAND, &status);
  status |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
  pci_write_config_word(CFG_PCI9054_DEV_FN, PCI_COMMAND, status);

  /* Check the latency timer for values >= 0x60.
   */
  pci_read_config_byte(CFG_PCI9054_DEV_FN, PCI_LATENCY_TIMER, &timer);
  if (timer < 0x60)
    {
      pci_write_config_byte(CFG_PCI9054_DEV_FN, PCI_LATENCY_TIMER, 0x60);
    }

  /* Set I/O base register.
   */
  pci_write_config_dword(CFG_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, CFG_PCI9054_IOBASE);
  pci_read_config_dword(CFG_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, &iobase);

  pci9054_iobase = pci_mem_to_phys(CFG_PCI9054_DEV_FN, iobase & PCI_BASE_ADDRESS_MEM_MASK);

  if (pci9054_iobase == 0xffffffff)
    {
      printf("Error: Can not set I/O base register.\n");
      return;
    }
}
#endif

static struct pci_config_table pci9054_config_table[] = {
#ifndef CONFIG_PCI_PNP
  { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
    PCI_BUS(CFG_ETH_DEV_FN), PCI_DEV(CFG_ETH_DEV_FN), PCI_FUNC(CFG_ETH_DEV_FN),
    pci_cfgfunc_config_device, { CFG_ETH_IOBASE,
				 CFG_ETH_IOBASE,
				 PCI_COMMAND_IO | PCI_COMMAND_MASTER }},
#ifdef CONFIG_DASA_SIM
  { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
    PCI_BUS(CFG_PCI9054_DEV_FN), PCI_DEV(CFG_PCI9054_DEV_FN), PCI_FUNC(CFG_PCI9054_DEV_FN),
    pci_dasa_sim_config_pci9054 },
#endif
#endif
  { }
};

static struct pci_controller pci9054_hose = {
  config_table: pci9054_config_table,
};

void pci_init_board(void)
{
  struct pci_controller *hose = &pci9054_hose;

  /*
   * Register the hose
   */
  hose->first_busno = 0;
  hose->last_busno = 0xff;

  /* System memory space */
  pci_set_region(hose->regions + 0,
		 0x00000000, 0x00000000, 0x01000000,
		 PCI_REGION_MEM | PCI_REGION_MEMORY);

  /* PCI Memory space */
  pci_set_region(hose->regions + 1,
		 0x00000000, 0xc0000000, 0x10000000,
		 PCI_REGION_MEM);

  pci_set_ops(hose,
	      pci_hose_read_config_byte_via_dword,
	      pci_hose_read_config_word_via_dword,
	      pci9054_read_config_dword,
	      pci_hose_write_config_byte_via_dword,
	      pci_hose_write_config_word_via_dword,
	      pci9054_write_config_dword);

  hose->region_count = 2;

  pci_register_hose(hose);

  hose->last_busno = pci_hose_scan(hose);
}
