Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 1 | The U-Boot Driver Model Project |
| 2 | =============================== |
| 3 | PCI subsystem analysis |
| 4 | ====================== |
| 5 | |
| 6 | Pavel Herrmann <morpheus.ibis@gmail.com> |
| 7 | 2012-03-17 |
| 8 | |
| 9 | I) Overview |
| 10 | ----------- |
| 11 | |
| 12 | U-Boot already supports multiple PCI busses, stored in a linked-list of |
| 13 | pci_controller structures. This structure contains generic driver data, bus |
| 14 | interface operations and private data for the driver. |
| 15 | |
| 16 | Bus interface operations for PCI are (names are self-explanatory): |
| 17 | |
| 18 | read_byte() |
| 19 | read_word() |
| 20 | read_dword() |
| 21 | write_byte() |
| 22 | write_word() |
| 23 | write_dword() |
| 24 | |
| 25 | Each driver has to implement dword operations, and either implement word and |
| 26 | byte operations, or use shared $operation_config_$type_via_dword (eg. |
| 27 | read_config_byte_via_dword and similar) function. These functions are used |
| 28 | for config space I/O (read_config_dword and similar functions of the PCI |
| 29 | subsystem), which is used to configure the connected devices for standard MMIO |
| 30 | operations. All data transfers by respective device drivers are then done by |
| 31 | MMIO |
| 32 | |
| 33 | Each driver also defines a separate init function, which has unique symbol |
| 34 | name, and thus more drivers can be compiled in without colliding. This init |
| 35 | function is typically called from pci_init_board(), different for each |
| 36 | particular board. |
| 37 | |
| 38 | Some boards also define a function called fixup_irq, which gets called after |
| 39 | scanning the PCI bus for devices, and should dismiss any interrupts. |
| 40 | |
| 41 | Several drivers are also located in arch/ and should be moved to drivers/pci. |
| 42 | |
| 43 | II) Approach |
| 44 | ------------ |
| 45 | |
| 46 | The pci_controller structure needs to be broken down to fit the new driver |
| 47 | model. Due to a large number of members, this will be done through three |
| 48 | distinct accessors, one for memory regions, one for config table and one for |
| 49 | everything else. That will make the pci_ops structure look like this: |
| 50 | |
| 51 | struct pci_ops { |
| 52 | int (*read_byte)(struct instance *bus, pci_dev_t *dev, int addr, |
| 53 | u8 *buf); |
| 54 | int (*read_word)(struct instance *bus, pci_dev_t *dev, int addr, |
| 55 | u16 *buf); |
| 56 | int (*read_dword)(struct instance *bus, pci_dev_t *dev, int addr, |
| 57 | u32 *buf); |
| 58 | int (*write_byte)(struct instance *bus, pci_dev_t *dev, int addr, |
| 59 | u8 val); |
| 60 | int (*write_byte)(struct instance *bus, pci_dev_t *dev, int addr, |
| 61 | u8 val); |
| 62 | int (*write_dword)(struct instance *bus, pci_dev_t *dev, int addr, |
| 63 | u32 val); |
| 64 | void (*fixup_irq)(struct instance *bus, pci_dev_t *dev); |
| 65 | struct pci_region* (*get_region)(struct instance *, uint num); |
| 66 | struct pci_config_table* (*get_cfg_table)(struct instance *bus); |
| 67 | uint (*get_option)(struct instance * bus, enum pci_option_code op); |
| 68 | } |
| 69 | |
| 70 | enum pci_option_code { |
| 71 | PCI_OPT_BUS_NUMBER=0, |
| 72 | PCI_OPT_REGION_COUNT, |
| 73 | PCI_OPT_INDIRECT_TYPE, |
| 74 | PCI_OPT_AUTO_MEM, |
| 75 | PCI_OPT_AUTO_IO, |
| 76 | PCI_OPT_AUTO_PREFETCH, |
| 77 | PCI_OPT_AUTO_FB, |
| 78 | PCI_OPT_CURRENT_BUS, |
| 79 | PCI_OPT_CFG_ADDR, |
| 80 | } |
| 81 | |
| 82 | The return value for get_option will be an unsigned integer value for any |
| 83 | option code. If the option currently is a pointer to pci_region, it will |
| 84 | return an index for get_region function. Special case has to be made for |
| 85 | PCI_OPT_CFG_ADDR, which should be interpreted as a pointer, but it is only |
| 86 | used for equality in find_hose_by_cfg_addr, and thus can be returned as an |
| 87 | uint. Other function using cfg_addr value are read/write functions for |
| 88 | specific drivers (especially ops for indirect bridges), and thus have access |
| 89 | to private_data of the driver instance. |
| 90 | |
| 91 | The config table accessor will return a pointer to a NULL-terminated array of |
| 92 | pci_config_table, which is supplied by the board in platform_data, or NULL if |
| 93 | the board didn't specify one. This table is used to override PnP |
| 94 | auto-initialization, or to specific initialization functions for non-PNP |
| 95 | devices. |
| 96 | |
| 97 | Transparent PCI-PCI bridges will get their own driver, and will forward all |
| 98 | operations to operations of their parent bus. This however makes it |
| 99 | impossible to use instances to identify devices, as not all devices will be |
| 100 | directly visible to the respective bus driver. |
| 101 | |
| 102 | Init functions of controller drivers will be moved to their respective |
| 103 | probe() functions, in accordance to the driver model. |
| 104 | |
| 105 | The PCI core will handle all mapping functions currently found in pci.c, as |
| 106 | well as proxy functions for read/write operations of the drivers. The PCI |
| 107 | core will also handle bus scanning and device configuration. |
| 108 | |
| 109 | The PnP helper functions currently in pci_auto.c will also be a part of PCI |
| 110 | core, but they will be exposed only to PCI controller drivers, not to other |
| 111 | device drivers. |
| 112 | |
| 113 | The PCI API for device drivers will remain largely unchanged, most drivers |
| 114 | will require no changes at all, and all modifications will be limited to |
| 115 | changing the pci_controlle into instance*. |
| 116 | |
| 117 | III) Analysis of in-tree drivers |
| 118 | -------------------------------- |
| 119 | |
| 120 | A) drivers in drivers/pci/ |
| 121 | -------------------------- |
| 122 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 123 | pci_indirect.c |
| 124 | -------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 125 | Shared driver for indirect PCI bridges, several CONFIG macros - will |
| 126 | require significant cleanup. |
| 127 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 128 | pci_sh4.c |
| 129 | --------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 130 | Shared init function for SH4 drivers, uses dword for read/write ops. |
| 131 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 132 | pci_sh7751.c |
| 133 | ------------ |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 134 | Standard driver, uses SH4 shared init. |
| 135 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 136 | pci_sh7780.c |
| 137 | ------------ |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 138 | Standard driver, uses SH4 shared init. |
| 139 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 140 | tsi108_pci.c |
| 141 | ------------ |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 142 | Standard driver, uses dword for read/write ops. |
| 143 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 144 | fsl_pci_init.c |
| 145 | -------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 146 | Driver for PCI and PCI-e, uses indirect functions. |
| 147 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 148 | pci_ftpci100.c |
| 149 | -------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 150 | Standard driver, uses indirect functions, has separate scan/setup |
| 151 | functions. |
| 152 | |
| 153 | B) driver in arch/ |
| 154 | ------------------ |
| 155 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 156 | x86/lib/pci_type1.c |
| 157 | ------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 158 | Standard driver, specifies all read/write functions separately. |
| 159 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 160 | m68k/cpu/mcf5445x/pci.c |
| 161 | ----------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 162 | Standard driver, specifies all read/write functions separately. |
| 163 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 164 | m68k/cpu/mcf547x_8x/pci.c |
| 165 | ------------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 166 | Standard driver, specifies all read/write functions separately. |
| 167 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 168 | powerpc/cpu/mpc824x/pci.c |
| 169 | ------------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 170 | Standard driver, uses indirect functions, does not setup HW. |
| 171 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 172 | powerpc/cpu/mpc8260/pci.c |
| 173 | ------------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 174 | Standard driver, uses indirect functions. |
| 175 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 176 | powerpc/cpu/ppc4xx/4xx_pci.c |
| 177 | ---------------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 178 | Standard driver, uses indirect functions. |
| 179 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 180 | powerpc/cpu/ppc4xx/4xx_pcie.c |
| 181 | ----------------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 182 | PCI-e driver, specifies all read/write functions separately. |
| 183 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 184 | powerpc/cpu/mpc83xx/pci.c |
| 185 | ------------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 186 | Standard driver, uses indirect functions. |
| 187 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 188 | powerpc/cpu/mpc83xx/pcie.c |
| 189 | -------------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 190 | PCI-e driver, specifies all read/write functions separately. |
| 191 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 192 | powerpc/cpu/mpc5xxx/pci_mpc5200.c |
| 193 | --------------------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 194 | Standard driver, uses dword for read/write ops. |
| 195 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 196 | powerpc/cpu/mpc512x/pci.c |
| 197 | ------------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 198 | Standard driver, uses indirect functions. |
| 199 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 200 | powerpc/cpu/mpc85xx/pci.c |
| 201 | ------------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 202 | Standard driver, uses indirect functions, has two busses. |
| 203 | |
| 204 | C) drivers in board/ |
| 205 | -------------------- |
| 206 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 207 | eltec/elppc/pci.c |
| 208 | ----------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 209 | Standard driver, uses indirect functions. |
| 210 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 211 | amirix/ap1000/pci.c |
| 212 | ------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 213 | Standard driver, specifies all read/write functions separately. |
| 214 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 215 | prodrive/p3mx/pci.c |
| 216 | ------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 217 | Standard driver, uses dword for read/write ops, has two busses. |
| 218 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 219 | esd/cpci750/pci.c |
| 220 | ----------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 221 | Standard driver, uses dword for read/write ops, has two busses. |
| 222 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 223 | esd/common/pci.c |
| 224 | ---------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 225 | Standard driver, uses dword for read/write ops. |
| 226 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 227 | dave/common/pci.c |
| 228 | ----------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 229 | Standard driver, uses dword for read/write ops. |
| 230 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 231 | ppmc7xx/pci.c |
| 232 | ------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 233 | Standard driver, uses indirect functions. |
| 234 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 235 | Marvell/db64360/pci.c |
| 236 | --------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 237 | Standard driver, uses dword for read/write ops, has two busses. |
| 238 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 239 | Marvell/db64460/pci.c |
| 240 | --------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 241 | Standard driver, uses dword for read/write ops, has two busses. |
| 242 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 243 | evb64260/pci.c |
| 244 | -------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 245 | Standard driver, uses dword for read/write ops, has two busses. |
| 246 | |
Masahiro Yamada | a756da9 | 2013-09-24 10:32:04 +0900 | [diff] [blame] | 247 | armltd/integrator/pci.c |
| 248 | ----------------------- |
Pavel Herrmann | 9f47317 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 249 | Standard driver, specifies all read/write functions separately. |
| 250 | |
| 251 | All drivers will be moved to drivers/pci. Several drivers seem |
| 252 | similar/identical, especially those located under board, and may be merged |
| 253 | into one. |