~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/u-boot/board/esd/common/pci.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
14
u_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
+-----------------------------------------------------------------------------*/
 
32
int 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
+-----------------------------------------------------------------------------*/
 
73
int 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
 
96
static 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
 
 
133
static 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
 
 
149
static struct pci_controller pci9054_hose = {
 
150
  config_table: pci9054_config_table,
 
151
};
 
152
 
 
153
void 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
}