/*
 * (C) Copyright 2001
 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <asm/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(CONFIG_SYS_PCI9054_DEV_FN, PCI_COMMAND, &status);
  status |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
  pci_write_config_word(CONFIG_SYS_PCI9054_DEV_FN, PCI_COMMAND, status);

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

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

  pci9054_iobase = pci_mem_to_phys(CONFIG_SYS_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(CONFIG_SYS_ETH_DEV_FN), PCI_DEV(CONFIG_SYS_ETH_DEV_FN), PCI_FUNC(CONFIG_SYS_ETH_DEV_FN),
    pci_cfgfunc_config_device, { CONFIG_SYS_ETH_IOBASE,
				 CONFIG_SYS_ETH_IOBASE,
				 PCI_COMMAND_IO | PCI_COMMAND_MASTER }},
#ifdef CONFIG_DASA_SIM
  { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
    PCI_BUS(CONFIG_SYS_PCI9054_DEV_FN), PCI_DEV(CONFIG_SYS_PCI9054_DEV_FN), PCI_FUNC(CONFIG_SYS_PCI9054_DEV_FN),
    pci_dasa_sim_config_pci9054 },
#endif
#endif
  { }
};

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

void pci_init(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_SYS_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);
}
