summaryrefslogtreecommitdiffstats
path: root/doc/driver-model/UDM-pci.txt
blob: 1dce99de3dccbae1627c45277db5f3dc1aa36b89 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
The U-Boot Driver Model Project
===============================
PCI subsystem analysis
======================

Pavel Herrmann <morpheus.ibis@gmail.com>
2012-03-17

I) Overview
-----------

  U-Boot already supports multiple PCI busses, stored in a linked-list of
  pci_controller structures. This structure contains generic driver data, bus
  interface operations and private data for the driver.

  Bus interface operations for PCI are (names are self-explanatory):

    read_byte()
    read_word()
    read_dword()
    write_byte()
    write_word()
    write_dword()

  Each driver has to implement dword operations, and either implement word and
  byte operations, or use shared $operation_config_$type_via_dword (eg.
  read_config_byte_via_dword and similar) function. These functions are used
  for config space I/O (read_config_dword and similar functions of the PCI
  subsystem), which is used to configure the connected devices for standard MMIO
  operations. All data transfers by respective device drivers are then done by
  MMIO

  Each driver also defines a separate init function, which has unique symbol
  name, and thus more drivers can be compiled in without colliding. This init
  function is typically called from pci_init_board(), different for each
  particular board.

  Some boards also define a function called fixup_irq, which gets called after
  scanning the PCI bus for devices, and should dismiss any interrupts.

  Several drivers are also located in arch/ and should be moved to drivers/pci.

II) Approach
------------

  The pci_controller structure needs to be broken down to fit the new driver
  model. Due to a large number of members, this will be done through three
  distinct accessors, one for memory regions, one for config table and one for
  everything else. That will make the pci_ops structure look like this:

    struct pci_ops {
      int (*read_byte)(struct instance *bus, pci_dev_t *dev, int addr,
		       u8 *buf);
      int (*read_word)(struct instance *bus, pci_dev_t *dev, int addr,
		       u16 *buf);
      int (*read_dword)(struct instance *bus, pci_dev_t *dev, int addr,
			u32 *buf);
      int (*write_byte)(struct instance *bus, pci_dev_t *dev, int addr,
			u8 val);
      int (*write_byte)(struct instance *bus, pci_dev_t *dev, int addr,
			u8 val);
      int (*write_dword)(struct instance *bus, pci_dev_t *dev, int addr,
			 u32 val);
      void (*fixup_irq)(struct instance *bus, pci_dev_t *dev);
      struct pci_region* (*get_region)(struct instance *, uint num);
      struct pci_config_table* (*get_cfg_table)(struct instance *bus);
      uint (*get_option)(struct instance * bus, enum pci_option_code op);
    }

    enum pci_option_code {
      PCI_OPT_BUS_NUMBER=0,
      PCI_OPT_REGION_COUNT,
      PCI_OPT_INDIRECT_TYPE,
      PCI_OPT_AUTO_MEM,
      PCI_OPT_AUTO_IO,
      PCI_OPT_AUTO_PREFETCH,
      PCI_OPT_AUTO_FB,
      PCI_OPT_CURRENT_BUS,
      PCI_OPT_CFG_ADDR,
    }

  The return value for get_option will be an unsigned integer value for any
  option code. If the option currently is a pointer to pci_region, it will
  return an index for get_region function. Special case has to be made for
  PCI_OPT_CFG_ADDR, which should be interpreted as a pointer, but it is only
  used for equality in find_hose_by_cfg_addr, and thus can be returned as an
  uint. Other function using cfg_addr value are read/write functions for
  specific drivers (especially ops for indirect bridges), and thus have access
  to private_data of the driver instance.

  The config table accessor will return a pointer to a NULL-terminated array of
  pci_config_table, which is supplied by the board in platform_data, or NULL if
  the board didn't specify one. This table is used to override PnP
  auto-initialization, or to specific initialization functions for non-PNP
  devices.

  Transparent PCI-PCI bridges will get their own driver, and will forward all
  operations to operations of their parent bus. This however makes it
  impossible to use instances to identify devices, as not all devices will be
  directly visible to the respective bus driver.

  Init functions of controller drivers will be moved to their respective
  probe() functions, in accordance to the driver model.

  The PCI core will handle all mapping functions currently found in pci.c, as
  well as proxy functions for read/write operations of the drivers. The PCI
  core will also handle bus scanning and device configuration.

  The PnP helper functions currently in pci_auto.c will also be a part of PCI
  core, but they will be exposed only to PCI controller drivers, not to other
  device drivers.

  The PCI API for device drivers will remain largely unchanged, most drivers
  will require no changes at all, and all modifications will be limited to
  changing the pci_controlle into instance*.

III) Analysis of in-tree drivers
--------------------------------

  A) drivers in drivers/pci/
  --------------------------

    pci_indirect.c
    --------------
      Shared driver for indirect PCI bridges, several CONFIG macros - will
      require significant cleanup.

    pci_sh4.c
    ---------
      Shared init function for SH4 drivers, uses dword for read/write ops.

    pci_sh7751.c
    ------------
      Standard driver, uses SH4 shared init.

    pci_sh7780.c
    ------------
      Standard driver, uses SH4 shared init.

    tsi108_pci.c
    ------------
      Standard driver, uses dword for read/write ops.

    fsl_pci_init.c
    --------------
      Driver for PCI and PCI-e, uses indirect functions.

    pci_ftpci100.c
    --------------
      Standard driver, uses indirect functions, has separate scan/setup
      functions.

  B) driver in arch/
  ------------------

    x86/lib/pci_type1.c
    -------------------
      Standard driver, specifies all read/write functions separately.

    m68k/cpu/mcf5445x/pci.c
    -----------------------
      Standard driver, specifies all read/write functions separately.

    m68k/cpu/mcf547x_8x/pci.c
    -------------------------
      Standard driver, specifies all read/write functions separately.

    powerpc/cpu/mpc824x/pci.c
    -------------------------
      Standard driver, uses indirect functions, does not setup HW.

    powerpc/cpu/mpc8260/pci.c
    -------------------------
      Standard driver, uses indirect functions.

    powerpc/cpu/ppc4xx/4xx_pci.c
    ----------------------------
      Standard driver, uses indirect functions.

    powerpc/cpu/ppc4xx/4xx_pcie.c
    -----------------------------
      PCI-e driver, specifies all read/write functions separately.

    powerpc/cpu/mpc83xx/pci.c
    -------------------------
      Standard driver, uses indirect functions.

    powerpc/cpu/mpc83xx/pcie.c
    --------------------------
      PCI-e driver, specifies all read/write functions separately.

    powerpc/cpu/mpc5xxx/pci_mpc5200.c
    ---------------------------------
      Standard driver, uses dword for read/write ops.

    powerpc/cpu/mpc512x/pci.c
    -------------------------
      Standard driver, uses indirect functions.

    powerpc/cpu/mpc85xx/pci.c
    -------------------------
      Standard driver, uses indirect functions, has two busses.

  C) drivers in board/
  --------------------

    eltec/elppc/pci.c
    -----------------
      Standard driver, uses indirect functions.

    amirix/ap1000/pci.c
    -------------------
      Standard driver, specifies all read/write functions separately.

    prodrive/p3mx/pci.c
    -------------------
      Standard driver, uses dword for read/write ops, has two busses.

    esd/cpci750/pci.c
    -----------------
      Standard driver, uses dword for read/write ops, has two busses.

    esd/common/pci.c
    ----------------
      Standard driver, uses dword for read/write ops.

    dave/common/pci.c
    -----------------
      Standard driver, uses dword for read/write ops.

    ppmc7xx/pci.c
    -------------
      Standard driver, uses indirect functions.

    Marvell/db64360/pci.c
    ---------------------
      Standard driver, uses dword for read/write ops, has two busses.

    Marvell/db64460/pci.c
    ---------------------
      Standard driver, uses dword for read/write ops, has two busses.

    evb64260/pci.c
    --------------
      Standard driver, uses dword for read/write ops, has two busses.

    armltd/integrator/pci.c
    -----------------------
      Standard driver, specifies all read/write functions separately.

  All drivers will be moved to drivers/pci. Several drivers seem
  similar/identical, especially those located under board, and may be merged
  into one.
OpenPOWER on IntegriCloud