Pavel Herrmann | a09c649 | 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 | |
| 123 | 1) pci_indirect.c |
| 124 | ----------------- |
| 125 | Shared driver for indirect PCI bridges, several CONFIG macros - will |
| 126 | require significant cleanup. |
| 127 | |
| 128 | 2) pci_ixp.c |
| 129 | ------------ |
| 130 | Standard driver, specifies all read/write functions separately. |
| 131 | |
| 132 | 3) pci_sh4.c |
| 133 | ------------ |
| 134 | Shared init function for SH4 drivers, uses dword for read/write ops. |
| 135 | |
| 136 | 4) pci_sh7751.c |
| 137 | --------------- |
| 138 | Standard driver, uses SH4 shared init. |
| 139 | |
| 140 | 5) pci_sh7780.c |
| 141 | --------------- |
| 142 | Standard driver, uses SH4 shared init. |
| 143 | |
| 144 | 6) tsi108_pci.c |
| 145 | --------------- |
| 146 | Standard driver, uses dword for read/write ops. |
| 147 | |
| 148 | 7) fsl_pci_init.c |
| 149 | ----------------- |
| 150 | Driver for PCI and PCI-e, uses indirect functions. |
| 151 | |
| 152 | 8) pci_ftpci100.c |
| 153 | ----------------- |
| 154 | Standard driver, uses indirect functions, has separate scan/setup |
| 155 | functions. |
| 156 | |
| 157 | B) driver in arch/ |
| 158 | ------------------ |
| 159 | |
| 160 | 1) x86/lib/pci_type1.c |
| 161 | ---------------------- |
| 162 | Standard driver, specifies all read/write functions separately. |
| 163 | |
| 164 | 2) m68k/cpu/mcf5445x/pci.c |
| 165 | -------------------------- |
| 166 | Standard driver, specifies all read/write functions separately. |
| 167 | |
| 168 | 3) m68k/cpu/mcf547x_8x/pci.c |
| 169 | ---------------------------- |
| 170 | Standard driver, specifies all read/write functions separately. |
| 171 | |
| 172 | 4) powerpc/cpu/mpc824x/pci.c |
| 173 | ---------------------------- |
| 174 | Standard driver, uses indirect functions, does not setup HW. |
| 175 | |
| 176 | 5) powerpc/cpu/mpc8260/pci.c |
| 177 | ---------------------------- |
| 178 | Standard driver, uses indirect functions. |
| 179 | |
| 180 | 6) powerpc/cpu/ppc4xx/4xx_pci.c |
| 181 | ------------------------------- |
| 182 | Standard driver, uses indirect functions. |
| 183 | |
| 184 | 7) powerpc/cpu/ppc4xx/4xx_pcie.c |
| 185 | -------------------------------- |
| 186 | PCI-e driver, specifies all read/write functions separately. |
| 187 | |
| 188 | 8) powerpc/cpu/mpc83xx/pci.c |
| 189 | ---------------------------- |
| 190 | Standard driver, uses indirect functions. |
| 191 | |
| 192 | 9) powerpc/cpu/mpc83xx/pcie.c |
| 193 | ----------------------------- |
| 194 | PCI-e driver, specifies all read/write functions separately. |
| 195 | |
| 196 | 10) powerpc/cpu/mpc5xxx/pci_mpc5200.c |
| 197 | ------------------------------------- |
| 198 | Standard driver, uses dword for read/write ops. |
| 199 | |
| 200 | 11) powerpc/cpu/mpc512x/pci.c |
| 201 | ----------------------------- |
| 202 | Standard driver, uses indirect functions. |
| 203 | |
| 204 | 12) powerpc/cpu/mpc8220/pci.c |
| 205 | ----------------------------- |
| 206 | Standard driver, specifies all read/write functions separately. |
| 207 | |
| 208 | 13) powerpc/cpu/mpc85xx/pci.c |
| 209 | ----------------------------- |
| 210 | Standard driver, uses indirect functions, has two busses. |
| 211 | |
| 212 | C) drivers in board/ |
| 213 | -------------------- |
| 214 | |
| 215 | 1) eltec/elppc/pci.c |
| 216 | -------------------- |
| 217 | Standard driver, uses indirect functions. |
| 218 | |
| 219 | 2) amirix/ap1000/pci.c |
| 220 | ---------------------- |
| 221 | Standard driver, specifies all read/write functions separately. |
| 222 | |
| 223 | 3) prodrive/p3mx/pci.c |
| 224 | ---------------------- |
| 225 | Standard driver, uses dword for read/write ops, has two busses. |
| 226 | |
| 227 | 4) esd/cpci750/pci.c |
| 228 | -------------------- |
| 229 | Standard driver, uses dword for read/write ops, has two busses. |
| 230 | |
| 231 | 5) esd/common/pci.c |
| 232 | ------------------- |
| 233 | Standard driver, uses dword for read/write ops. |
| 234 | |
| 235 | 6) dave/common/pci.c |
| 236 | -------------------- |
| 237 | Standard driver, uses dword for read/write ops. |
| 238 | |
| 239 | 7) ppmc7xx/pci.c |
| 240 | ---------------- |
| 241 | Standard driver, uses indirect functions. |
| 242 | |
Pavel Herrmann | a09c649 | 2012-08-08 01:42:27 +0000 | [diff] [blame] | 243 | 9) Marvell/db64360/pci.c |
| 244 | ------------------------ |
| 245 | Standard driver, uses dword for read/write ops, has two busses. |
| 246 | |
| 247 | 10) Marvell/db64460/pci.c |
| 248 | ------------------------- |
| 249 | Standard driver, uses dword for read/write ops, has two busses. |
| 250 | |
| 251 | 11) evb64260/pci.c |
| 252 | ------------------ |
| 253 | Standard driver, uses dword for read/write ops, has two busses. |
| 254 | |
| 255 | 12) armltd/integrator/pci.c |
| 256 | --------------------------- |
| 257 | Standard driver, specifies all read/write functions separately. |
| 258 | |
| 259 | All drivers will be moved to drivers/pci. Several drivers seem |
| 260 | similar/identical, especially those located under board, and may be merged |
| 261 | into one. |