uboot/board/esd/common/pci.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2001
   3 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <asm/ppc4xx.h>
  10#include <asm/processor.h>
  11#include <pci.h>
  12
  13
  14u_long pci9054_iobase;
  15
  16
  17#define PCI_PRIMARY_CAR (0x500000dc) /* PCI config address reg */
  18#define PCI_PRIMARY_CDR (0x80000000) /* PCI config data    reg */
  19
  20
  21/*-----------------------------------------------------------------------------+
  22|  Subroutine:  pci9054_read_config_dword
  23|  Description: Read a PCI configuration register
  24|  Inputs:
  25|               hose            PCI Controller
  26|               dev             PCI Bus+Device+Function number
  27|               offset          Configuration register number
  28|               value           Address of the configuration register value
  29|  Return value:
  30|               0               Successful
  31+-----------------------------------------------------------------------------*/
  32int pci9054_read_config_dword(struct pci_controller *hose,
  33                              pci_dev_t dev, int offset, u32* value)
  34{
  35  unsigned long      conAdrVal;
  36  unsigned long      val;
  37
  38  /* generate coded value for CON_ADR register */
  39  conAdrVal = dev | (offset & 0xfc) | 0x80000000;
  40
  41  /* Load the CON_ADR (CAR) value first, then read from CON_DATA (CDR) */
  42  *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal;
  43
  44  /* Note: *pResult comes back as -1 if machine check happened */
  45  val = in32r(PCI_PRIMARY_CDR);
  46
  47  *value = (unsigned long) val;
  48
  49  out32r(PCI_PRIMARY_CAR, 0);
  50
  51  if ((*(unsigned long *)0x50000304) & 0x60000000)
  52    {
  53      /* clear pci master/target abort bits */
  54      *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304;
  55    }
  56
  57  return 0;
  58}
  59
  60/*-----------------------------------------------------------------------------+
  61|  Subroutine:  pci9054_write_config_dword
  62|  Description: Write a PCI configuration register.
  63|  Inputs:
  64|               hose            PCI Controller
  65|               dev             PCI Bus+Device+Function number
  66|               offset          Configuration register number
  67|               Value           Configuration register value
  68|  Return value:
  69|               0               Successful
  70| Updated for pass2 errata #6. Need to disable interrupts and clear the
  71| PCICFGADR reg after writing the PCICFGDATA reg.
  72+-----------------------------------------------------------------------------*/
  73int pci9054_write_config_dword(struct pci_controller *hose,
  74                               pci_dev_t dev, int offset, u32 value)
  75{
  76  unsigned long      conAdrVal;
  77
  78  conAdrVal = dev | (offset & 0xfc) | 0x80000000;
  79
  80  *(unsigned long *)PCI_PRIMARY_CAR = conAdrVal;
  81
  82  out32r(PCI_PRIMARY_CDR, value);
  83
  84  out32r(PCI_PRIMARY_CAR, 0);
  85
  86  /* clear pci master/target abort bits */
  87  *(unsigned long *)0x50000304 = *(unsigned long *)0x50000304;
  88
  89  return (0);
  90}
  91
  92/*-----------------------------------------------------------------------
  93 */
  94
  95#ifdef CONFIG_DASA_SIM
  96static void pci_dasa_sim_config_pci9054(struct pci_controller *hose, pci_dev_t dev,
  97                                        struct pci_config_table *_)
  98{
  99  unsigned int iobase;
 100  unsigned short status = 0;
 101  unsigned char timer;
 102
 103  /*
 104   * Configure PLX PCI9054
 105   */
 106  pci_read_config_word(CONFIG_SYS_PCI9054_DEV_FN, PCI_COMMAND, &status);
 107  status |= PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY;
 108  pci_write_config_word(CONFIG_SYS_PCI9054_DEV_FN, PCI_COMMAND, status);
 109
 110  /* Check the latency timer for values >= 0x60.
 111   */
 112  pci_read_config_byte(CONFIG_SYS_PCI9054_DEV_FN, PCI_LATENCY_TIMER, &timer);
 113  if (timer < 0x60)
 114    {
 115      pci_write_config_byte(CONFIG_SYS_PCI9054_DEV_FN, PCI_LATENCY_TIMER, 0x60);
 116    }
 117
 118  /* Set I/O base register.
 119   */
 120  pci_write_config_dword(CONFIG_SYS_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, CONFIG_SYS_PCI9054_IOBASE);
 121  pci_read_config_dword(CONFIG_SYS_PCI9054_DEV_FN, PCI_BASE_ADDRESS_0, &iobase);
 122
 123  pci9054_iobase = pci_mem_to_phys(CONFIG_SYS_PCI9054_DEV_FN, iobase & PCI_BASE_ADDRESS_MEM_MASK);
 124
 125  if (pci9054_iobase == 0xffffffff)
 126    {
 127      printf("Error: Can not set I/O base register.\n");
 128      return;
 129    }
 130}
 131#endif
 132
 133static struct pci_config_table pci9054_config_table[] = {
 134#ifndef CONFIG_PCI_PNP
 135  { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
 136    PCI_BUS(CONFIG_SYS_ETH_DEV_FN), PCI_DEV(CONFIG_SYS_ETH_DEV_FN), PCI_FUNC(CONFIG_SYS_ETH_DEV_FN),
 137    pci_cfgfunc_config_device, { CONFIG_SYS_ETH_IOBASE,
 138                                 CONFIG_SYS_ETH_IOBASE,
 139                                 PCI_COMMAND_IO | PCI_COMMAND_MASTER }},
 140#ifdef CONFIG_DASA_SIM
 141  { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
 142    PCI_BUS(CONFIG_SYS_PCI9054_DEV_FN), PCI_DEV(CONFIG_SYS_PCI9054_DEV_FN), PCI_FUNC(CONFIG_SYS_PCI9054_DEV_FN),
 143    pci_dasa_sim_config_pci9054 },
 144#endif
 145#endif
 146  { }
 147};
 148
 149static struct pci_controller pci9054_hose = {
 150  config_table: pci9054_config_table,
 151};
 152
 153void pci_init_board(void)
 154{
 155  struct pci_controller *hose = &pci9054_hose;
 156
 157  /*
 158   * Register the hose
 159   */
 160  hose->first_busno = 0;
 161  hose->last_busno = 0xff;
 162
 163  /* System memory space */
 164  pci_set_region(hose->regions + 0,
 165                 0x00000000, 0x00000000, 0x01000000,
 166                 PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
 167
 168  /* PCI Memory space */
 169  pci_set_region(hose->regions + 1,
 170                 0x00000000, 0xc0000000, 0x10000000,
 171                 PCI_REGION_MEM);
 172
 173  pci_set_ops(hose,
 174              pci_hose_read_config_byte_via_dword,
 175              pci_hose_read_config_word_via_dword,
 176              pci9054_read_config_dword,
 177              pci_hose_write_config_byte_via_dword,
 178              pci_hose_write_config_word_via_dword,
 179              pci9054_write_config_dword);
 180
 181  hose->region_count = 2;
 182
 183  pci_register_hose(hose);
 184
 185  hose->last_busno = pci_hose_scan(hose);
 186}
 187