2 * Copyright 2008 Extreme Engineering Solutions, Inc.
3 * Copyright 2007-2008 Freescale Semiconductor, Inc.
5 * See file CREDITS for list of people who contributed to this
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 #include <asm/fsl_pci.h>
28 #include <fdt_support.h>
30 int first_free_busno = 0;
33 static struct pci_controller pci1_hose;
36 static struct pci_controller pcie1_hose;
39 static struct pci_controller pcie2_hose;
42 static struct pci_controller pcie3_hose;
46 /* Correlate host/agent POR bits to usable info. Table 4-14 */
47 struct host_agent_cfg_t {
50 } host_agent_cfg[8] = {
61 /* Correlate port width POR bits to usable info. Table 4-15 */
62 struct io_port_cfg_t {
83 #elif defined CONFIG_MPC8548
84 /* Correlate host/agent POR bits to usable info. Table 4-12 */
85 struct host_agent_cfg_t {
89 } host_agent_cfg[8] = {
93 {{0, 0}, {0}, 0}, /* reserved */
100 /* Correlate port width POR bits to usable info. Table 4-13 */
101 struct io_port_cfg_t {
114 #elif defined CONFIG_MPC86xx
115 /* Correlate host/agent POR bits to usable info. Table 4-17 */
116 struct host_agent_cfg_t {
119 } host_agent_cfg[8] = {
126 /* Correlate port width POR bits to usable info. Table 4-16 */
127 struct io_port_cfg_t {
130 } io_port_cfg[16] = {
151 * 85xx and 86xx share naming conventions, but different layout.
152 * Correlate names to CPU-specific values to share common
155 #if defined(CONFIG_MPC85xx)
156 #define MPC8xxx_DEVDISR_PCIE1 MPC85xx_DEVDISR_PCIE
157 #define MPC8xxx_DEVDISR_PCIE2 MPC85xx_DEVDISR_PCIE2
158 #define MPC8xxx_DEVDISR_PCIE3 MPC85xx_DEVDISR_PCIE3
159 #define MPC8xxx_PORDEVSR_IO_SEL MPC85xx_PORDEVSR_IO_SEL
160 #define MPC8xxx_PORDEVSR_IO_SEL_SHIFT MPC85xx_PORDEVSR_IO_SEL_SHIFT
161 #define MPC8xxx_PORBMSR_HA MPC85xx_PORBMSR_HA
162 #define MPC8xxx_PORBMSR_HA_SHIFT MPC85xx_PORBMSR_HA_SHIFT
163 #elif defined(CONFIG_MPC86xx)
164 #define MPC8xxx_DEVDISR_PCIE1 MPC86xx_DEVDISR_PCIEX1
165 #define MPC8xxx_DEVDISR_PCIE2 MPC86xx_DEVDISR_PCIEX2
166 #define MPC8xxx_DEVDISR_PCIE3 0 /* 8641 doesn't have PCIe3 */
167 #define MPC8xxx_PORDEVSR_IO_SEL MPC8641_PORDEVSR_IO_SEL
168 #define MPC8xxx_PORDEVSR_IO_SEL_SHIFT MPC8641_PORDEVSR_IO_SEL_SHIFT
169 #define MPC8xxx_PORBMSR_HA MPC8641_PORBMSR_HA
170 #define MPC8xxx_PORBMSR_HA_SHIFT MPC8641_PORBMSR_HA_SHIFT
173 void pci_init_board(void)
175 struct pci_controller *hose;
176 volatile ccsr_fsl_pci_t *pci;
179 #if defined(CONFIG_MPC85xx)
180 volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
181 #elif defined(CONFIG_MPC86xx)
182 immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
183 volatile ccsr_gur_t *gur = &immap->im_gur;
185 uint devdisr = gur->devdisr;
186 uint io_sel = (gur->pordevsr & MPC8xxx_PORDEVSR_IO_SEL) >>
187 MPC8xxx_PORDEVSR_IO_SEL_SHIFT;
188 uint host_agent = (gur->porbmsr & MPC8xxx_PORBMSR_HA) >>
189 MPC8xxx_PORBMSR_HA_SHIFT;
190 struct pci_region *r;
193 uint pci_spd_norm = (gur->pordevsr & MPC85xx_PORDEVSR_PCI1_SPD);
194 uint pci_32 = gur->pordevsr & MPC85xx_PORDEVSR_PCI1_PCI32;
195 uint pci_arb = gur->pordevsr & MPC85xx_PORDEVSR_PCI1_ARB;
196 uint pcix = gur->pordevsr & MPC85xx_PORDEVSR_PCI1;
197 uint freq = CONFIG_SYS_CLK_FREQ / 1000 / 1000;
199 width = 0; /* Silence compiler warning... */
200 io_sel &= 0xf; /* Silence compiler warning... */
201 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCI1_ADDR;
203 host = host_agent_cfg[host_agent].pci_host[0];
207 if (!(devdisr & MPC85xx_DEVDISR_PCI1)) {
208 printf("\n PCI1: %d bit %s, %s %d MHz, %s, %s\n",
210 pcix ? "PCIX" : "PCI",
211 pci_spd_norm ? ">=" : "<=",
212 pcix ? freq * 2 : freq,
213 host ? "host" : "agent",
214 pci_arb ? "arbiter" : "external-arbiter");
217 r += fsl_pci_setup_inbound_windows(r);
219 /* outbound memory */
221 CONFIG_SYS_PCI1_MEM_BASE,
222 CONFIG_SYS_PCI1_MEM_PHYS,
223 CONFIG_SYS_PCI1_MEM_SIZE,
228 CONFIG_SYS_PCI1_IO_BASE,
229 CONFIG_SYS_PCI1_IO_PHYS,
230 CONFIG_SYS_PCI1_IO_SIZE,
233 hose->region_count = r - hose->regions;
235 hose->first_busno = first_free_busno;
236 pci_setup_indirect(hose, (int)&pci->cfg_addr,
237 (int)&pci->cfg_data);
241 /* Unlock inbound PCI configuration cycles */
243 fsl_pci_config_unlock(hose);
245 first_free_busno = hose->last_busno + 1;
246 printf(" PCI1 on bus %02x - %02x\n",
247 hose->first_busno, hose->last_busno);
249 printf(" PCI1: disabled\n");
251 #elif defined CONFIG_MPC8548
252 /* PCI1 not present on MPC8572 */
253 gur->devdisr |= MPC85xx_DEVDISR_PCI1; /* disable */
256 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE1_ADDR;
258 host = host_agent_cfg[host_agent].pcie_root[0];
259 width = io_port_cfg[io_sel].pcie_width[0];
262 if (width && !(devdisr & MPC8xxx_DEVDISR_PCIE1)) {
263 printf("\n PCIE1 connected as %s (x%d)",
264 host ? "Root Complex" : "End Point", width);
265 if (pci->pme_msg_det) {
266 pci->pme_msg_det = 0xffffffff;
267 debug(" with errors. Clearing. Now 0x%08x",
273 r += fsl_pci_setup_inbound_windows(r);
275 /* outbound memory */
277 CONFIG_SYS_PCIE1_MEM_BASE,
278 CONFIG_SYS_PCIE1_MEM_PHYS,
279 CONFIG_SYS_PCIE1_MEM_SIZE,
284 CONFIG_SYS_PCIE1_IO_BASE,
285 CONFIG_SYS_PCIE1_IO_PHYS,
286 CONFIG_SYS_PCIE1_IO_SIZE,
289 hose->region_count = r - hose->regions;
291 hose->first_busno = first_free_busno;
292 pci_setup_indirect(hose, (int)&pci->cfg_addr,
293 (int) &pci->cfg_data);
297 /* Unlock inbound PCI configuration cycles */
299 fsl_pci_config_unlock(hose);
301 first_free_busno = hose->last_busno + 1;
302 printf(" PCIE1 on bus %02x - %02x\n",
303 hose->first_busno, hose->last_busno);
306 gur->devdisr |= MPC8xxx_DEVDISR_PCIE1; /* disable */
307 #endif /* CONFIG_PCIE1 */
310 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE2_ADDR;
312 host = host_agent_cfg[host_agent].pcie_root[1];
313 width = io_port_cfg[io_sel].pcie_width[1];
316 if (width && !(devdisr & MPC8xxx_DEVDISR_PCIE2)) {
317 printf("\n PCIE2 connected as %s (x%d)",
318 host ? "Root Complex" : "End Point", width);
319 if (pci->pme_msg_det) {
320 pci->pme_msg_det = 0xffffffff;
321 debug(" with errors. Clearing. Now 0x%08x",
327 r += fsl_pci_setup_inbound_windows(r);
329 /* outbound memory */
331 CONFIG_SYS_PCIE2_MEM_BASE,
332 CONFIG_SYS_PCIE2_MEM_PHYS,
333 CONFIG_SYS_PCIE2_MEM_SIZE,
338 CONFIG_SYS_PCIE2_IO_BASE,
339 CONFIG_SYS_PCIE2_IO_PHYS,
340 CONFIG_SYS_PCIE2_IO_SIZE,
343 hose->region_count = r - hose->regions;
345 hose->first_busno = first_free_busno;
346 pci_setup_indirect(hose, (int)&pci->cfg_addr,
347 (int)&pci->cfg_data);
351 /* Unlock inbound PCI configuration cycles */
353 fsl_pci_config_unlock(hose);
355 first_free_busno = hose->last_busno + 1;
356 printf(" PCIE2 on bus %02x - %02x\n",
357 hose->first_busno, hose->last_busno);
360 gur->devdisr |= MPC8xxx_DEVDISR_PCIE2; /* disable */
361 #endif /* CONFIG_PCIE2 */
364 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE3_ADDR;
366 host = host_agent_cfg[host_agent].pcie_root[2];
367 width = io_port_cfg[io_sel].pcie_width[2];
370 if (width && !(devdisr & MPC8xxx_DEVDISR_PCIE3)) {
371 printf("\n PCIE3 connected as %s (x%d)",
372 host ? "Root Complex" : "End Point", width);
373 if (pci->pme_msg_det) {
374 pci->pme_msg_det = 0xffffffff;
375 debug(" with errors. Clearing. Now 0x%08x",
381 r += fsl_pci_setup_inbound_windows(r);
383 /* outbound memory */
385 CONFIG_SYS_PCIE3_MEM_BASE,
386 CONFIG_SYS_PCIE3_MEM_PHYS,
387 CONFIG_SYS_PCIE3_MEM_SIZE,
392 CONFIG_SYS_PCIE3_IO_BASE,
393 CONFIG_SYS_PCIE3_IO_PHYS,
394 CONFIG_SYS_PCIE3_IO_SIZE,
397 hose->region_count = r - hose->regions;
399 hose->first_busno = first_free_busno;
400 pci_setup_indirect(hose, (int)&pci->cfg_addr,
401 (int)&pci->cfg_data);
405 /* Unlock inbound PCI configuration cycles */
407 fsl_pci_config_unlock(hose);
409 first_free_busno = hose->last_busno + 1;
410 printf(" PCIE3 on bus %02x - %02x\n",
411 hose->first_busno, hose->last_busno);
414 gur->devdisr |= MPC8xxx_DEVDISR_PCIE3; /* disable */
415 #endif /* CONFIG_PCIE3 */
418 #if defined(CONFIG_OF_BOARD_SETUP)
419 void ft_board_pci_setup(void *blob, bd_t *bd)
421 /* TODO - make node name (eg pci0) dynamic */
423 ft_fsl_pci_setup(blob, "pci0", &pci1_hose);
426 ft_fsl_pci_setup(blob, "pci2", &pcie1_hose);
429 ft_fsl_pci_setup(blob, "pci1", &pcie2_hose);
432 ft_fsl_pci_setup(blob, "pci0", &pcie3_hose);
435 #endif /* CONFIG_OF_BOARD_SETUP */