Commit 69fd2d3b0559f221a45e9a86b8ead16490f4e47b
Committed by
Wolfgang Denk
1 parent
98c397a6ed
Exists in
master
and in
54 other branches
pci: add CONFIG_PCI_ENUM_ONLY for platforms that don't need PCI setup done
Introduce CONFIG_PCI_ENUM_ONLY variable for platforms that just want a quick enumberation of the PCI devices, but don't need any setup work done. This is very beneficial on platforms that have u-boot loaded by another boot loader which does a more sophisticated job of setup of PCI devices than u-boot. That way, u-boot can just read what's there and get on with life. This is what SeaBIOS does. Signed-off-by: Andrew Sharp <andywyse6@gmail.com>
Showing 2 changed files with 32 additions and 10 deletions Side-by-side Diff
README
... | ... | @@ -3377,6 +3377,13 @@ |
3377 | 3377 | Disable PCI-Express on systems where it is supported but not |
3378 | 3378 | required. |
3379 | 3379 | |
3380 | +- CONFIG_PCI_ENUM_ONLY | |
3381 | + Only scan through and get the devices on the busses. | |
3382 | + Don't do any setup work, presumably because someone or | |
3383 | + something has already done it, and we don't need to do it | |
3384 | + a second time. Useful for platforms that are pre-booted | |
3385 | + by coreboot or similar. | |
3386 | + | |
3380 | 3387 | - CONFIG_SYS_SRIO: |
3381 | 3388 | Chip has SRIO or not |
3382 | 3389 |
drivers/pci/pci_auto.c
... | ... | @@ -90,12 +90,14 @@ |
90 | 90 | struct pci_region *io) |
91 | 91 | { |
92 | 92 | pci_addr_t bar_response; |
93 | - pci_addr_t bar_value; | |
94 | 93 | pci_size_t bar_size; |
95 | 94 | u16 cmdstat = 0; |
96 | - struct pci_region *bar_res; | |
97 | 95 | int bar, bar_nr = 0; |
96 | +#ifndef CONFIG_PCI_ENUM_ONLY | |
97 | + pci_addr_t bar_value; | |
98 | + struct pci_region *bar_res; | |
98 | 99 | int found_mem64 = 0; |
100 | +#endif | |
99 | 101 | |
100 | 102 | pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat); |
101 | 103 | cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | PCI_COMMAND_MASTER; |
102 | 104 | |
103 | 105 | |
104 | 106 | |
105 | 107 | |
106 | 108 | |
... | ... | @@ -103,20 +105,26 @@ |
103 | 105 | for (bar = PCI_BASE_ADDRESS_0; |
104 | 106 | bar < PCI_BASE_ADDRESS_0 + (bars_num * 4); bar += 4) { |
105 | 107 | /* Tickle the BAR and get the response */ |
108 | +#ifndef CONFIG_PCI_ENUM_ONLY | |
106 | 109 | pci_hose_write_config_dword(hose, dev, bar, 0xffffffff); |
110 | +#endif | |
107 | 111 | pci_hose_read_config_dword(hose, dev, bar, &bar_response); |
108 | 112 | |
109 | 113 | /* If BAR is not implemented go to the next BAR */ |
110 | 114 | if (!bar_response) |
111 | 115 | continue; |
112 | 116 | |
117 | +#ifndef CONFIG_PCI_ENUM_ONLY | |
113 | 118 | found_mem64 = 0; |
119 | +#endif | |
114 | 120 | |
115 | 121 | /* Check the BAR type and set our address mask */ |
116 | 122 | if (bar_response & PCI_BASE_ADDRESS_SPACE) { |
117 | 123 | bar_size = ((~(bar_response & PCI_BASE_ADDRESS_IO_MASK)) |
118 | 124 | & 0xffff) + 1; |
125 | +#ifndef CONFIG_PCI_ENUM_ONLY | |
119 | 126 | bar_res = io; |
127 | +#endif | |
120 | 128 | |
121 | 129 | DEBUGF("PCI Autoconfig: BAR %d, I/O, size=0x%llx, ", bar_nr, (u64)bar_size); |
122 | 130 | } else { |
123 | 131 | |
124 | 132 | |
125 | 133 | |
126 | 134 | |
127 | 135 | |
128 | 136 | |
... | ... | @@ -124,26 +132,34 @@ |
124 | 132 | PCI_BASE_ADDRESS_MEM_TYPE_64) { |
125 | 133 | u32 bar_response_upper; |
126 | 134 | u64 bar64; |
135 | + | |
136 | +#ifndef CONFIG_PCI_ENUM_ONLY | |
127 | 137 | pci_hose_write_config_dword(hose, dev, bar + 4, |
128 | 138 | 0xffffffff); |
139 | +#endif | |
129 | 140 | pci_hose_read_config_dword(hose, dev, bar + 4, |
130 | 141 | &bar_response_upper); |
131 | 142 | |
132 | 143 | bar64 = ((u64)bar_response_upper << 32) | bar_response; |
133 | 144 | |
134 | 145 | bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1; |
146 | +#ifndef CONFIG_PCI_ENUM_ONLY | |
135 | 147 | found_mem64 = 1; |
148 | +#endif | |
136 | 149 | } else { |
137 | 150 | bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1); |
138 | 151 | } |
152 | +#ifndef CONFIG_PCI_ENUM_ONLY | |
139 | 153 | if (prefetch && (bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH)) |
140 | 154 | bar_res = prefetch; |
141 | 155 | else |
142 | 156 | bar_res = mem; |
157 | +#endif | |
143 | 158 | |
144 | 159 | DEBUGF("PCI Autoconfig: BAR %d, Mem, size=0x%llx, ", bar_nr, (u64)bar_size); |
145 | 160 | } |
146 | 161 | |
162 | +#ifndef CONFIG_PCI_ENUM_ONLY | |
147 | 163 | if (pciauto_region_allocate(bar_res, bar_size, &bar_value) == 0) { |
148 | 164 | /* Write it out and update our limit */ |
149 | 165 | pci_hose_write_config_dword(hose, dev, bar, (u32)bar_value); |
150 | 166 | |
... | ... | @@ -162,9 +178,10 @@ |
162 | 178 | #endif |
163 | 179 | } |
164 | 180 | |
165 | - cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ? | |
166 | - PCI_COMMAND_IO : PCI_COMMAND_MEMORY; | |
167 | 181 | } |
182 | +#endif | |
183 | + cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ? | |
184 | + PCI_COMMAND_IO : PCI_COMMAND_MEMORY; | |
168 | 185 | |
169 | 186 | DEBUGF("\n"); |
170 | 187 | |
... | ... | @@ -357,12 +374,6 @@ |
357 | 374 | pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class); |
358 | 375 | |
359 | 376 | switch (class) { |
360 | - case PCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */ | |
361 | - DEBUGF("PCI AutoConfig: Found PowerPC device\n"); | |
362 | - pciauto_setup_device(hose, dev, 6, hose->pci_mem, | |
363 | - hose->pci_prefetch, hose->pci_io); | |
364 | - break; | |
365 | - | |
366 | 377 | case PCI_CLASS_BRIDGE_PCI: |
367 | 378 | hose->current_busno++; |
368 | 379 | pciauto_setup_device(hose, dev, 2, hose->pci_mem, |
... | ... | @@ -429,6 +440,10 @@ |
429 | 440 | hose->pci_prefetch, hose->pci_io); |
430 | 441 | break; |
431 | 442 | #endif |
443 | + | |
444 | + case PCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */ | |
445 | + DEBUGF("PCI AutoConfig: Found PowerPC device\n"); | |
446 | + | |
432 | 447 | default: |
433 | 448 | pciauto_setup_device(hose, dev, 6, hose->pci_mem, |
434 | 449 | hose->pci_prefetch, hose->pci_io); |