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>
29 #include <fdt_support.h>
31 int first_free_busno = 0;
34 static struct pci_controller pci1_hose;
37 static struct pci_controller pcie1_hose;
40 static struct pci_controller pcie2_hose;
43 static struct pci_controller pcie3_hose;
47 /* Correlate host/agent POR bits to usable info. Table 4-14 */
48 struct host_agent_cfg_t {
51 } host_agent_cfg[8] = {
62 /* Correlate port width POR bits to usable info. Table 4-15 */
63 struct io_port_cfg_t {
84 #elif defined CONFIG_MPC8548
85 /* Correlate host/agent POR bits to usable info. Table 4-12 */
86 struct host_agent_cfg_t {
90 } host_agent_cfg[8] = {
94 {{0, 0}, {0}, 0}, /* reserved */
101 /* Correlate port width POR bits to usable info. Table 4-13 */
102 struct io_port_cfg_t {
115 #elif defined CONFIG_MPC86xx
116 /* Correlate host/agent POR bits to usable info. Table 4-17 */
117 struct host_agent_cfg_t {
120 } host_agent_cfg[8] = {
127 /* Correlate port width POR bits to usable info. Table 4-16 */
128 struct io_port_cfg_t {
131 } io_port_cfg[16] = {
152 * 85xx and 86xx share naming conventions, but different layout.
153 * Correlate names to CPU-specific values to share common
156 #if defined(CONFIG_MPC85xx)
157 #define MPC8xxx_DEVDISR_PCIE1 MPC85xx_DEVDISR_PCIE
158 #define MPC8xxx_DEVDISR_PCIE2 MPC85xx_DEVDISR_PCIE2
159 #define MPC8xxx_DEVDISR_PCIE3 MPC85xx_DEVDISR_PCIE3
160 #define MPC8xxx_PORDEVSR_IO_SEL MPC85xx_PORDEVSR_IO_SEL
161 #define MPC8xxx_PORDEVSR_IO_SEL_SHIFT MPC85xx_PORDEVSR_IO_SEL_SHIFT
162 #define MPC8xxx_PORBMSR_HA MPC85xx_PORBMSR_HA
163 #define MPC8xxx_PORBMSR_HA_SHIFT MPC85xx_PORBMSR_HA_SHIFT
164 #elif defined(CONFIG_MPC86xx)
165 #define MPC8xxx_DEVDISR_PCIE1 MPC86xx_DEVDISR_PCIEX1
166 #define MPC8xxx_DEVDISR_PCIE2 MPC86xx_DEVDISR_PCIEX2
167 #define MPC8xxx_DEVDISR_PCIE3 0 /* 8641 doesn't have PCIe3 */
168 #define MPC8xxx_PORDEVSR_IO_SEL MPC8641_PORDEVSR_IO_SEL
169 #define MPC8xxx_PORDEVSR_IO_SEL_SHIFT MPC8641_PORDEVSR_IO_SEL_SHIFT
170 #define MPC8xxx_PORBMSR_HA MPC8641_PORBMSR_HA
171 #define MPC8xxx_PORBMSR_HA_SHIFT MPC8641_PORBMSR_HA_SHIFT
174 void pci_init_board(void)
176 struct pci_controller *hose;
177 volatile ccsr_fsl_pci_t *pci;
180 #if defined(CONFIG_MPC85xx)
181 volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
182 #elif defined(CONFIG_MPC86xx)
183 immap_t *immap = (immap_t *)CONFIG_SYS_IMMR;
184 volatile ccsr_gur_t *gur = &immap->im_gur;
186 uint devdisr = in_be32(&gur->devdisr);
187 uint io_sel = (in_be32(&gur->pordevsr) & MPC8xxx_PORDEVSR_IO_SEL) >>
188 MPC8xxx_PORDEVSR_IO_SEL_SHIFT;
189 uint host_agent = (in_be32(&gur->porbmsr) & MPC8xxx_PORBMSR_HA) >>
190 MPC8xxx_PORBMSR_HA_SHIFT;
191 struct pci_region *r;
194 uint pci_spd_norm = in_be32(&gur->pordevsr) & MPC85xx_PORDEVSR_PCI1_SPD;
195 uint pci_32 = in_be32(&gur->pordevsr) & MPC85xx_PORDEVSR_PCI1_PCI32;
196 uint pci_arb = in_be32(&gur->pordevsr) & MPC85xx_PORDEVSR_PCI1_ARB;
197 uint pcix = in_be32(&gur->pordevsr) & MPC85xx_PORDEVSR_PCI1;
198 uint freq = CONFIG_SYS_CLK_FREQ / 1000 / 1000;
200 width = 0; /* Silence compiler warning... */
201 io_sel &= 0xf; /* Silence compiler warning... */
202 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCI1_ADDR;
204 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");
216 /* outbound memory */
218 CONFIG_SYS_PCI1_MEM_BASE,
219 CONFIG_SYS_PCI1_MEM_PHYS,
220 CONFIG_SYS_PCI1_MEM_SIZE,
225 CONFIG_SYS_PCI1_IO_BASE,
226 CONFIG_SYS_PCI1_IO_PHYS,
227 CONFIG_SYS_PCI1_IO_SIZE,
230 hose->region_count = r - hose->regions;
232 hose->first_busno = first_free_busno;
234 fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);
236 /* Unlock inbound PCI configuration cycles */
238 fsl_pci_config_unlock(hose);
240 first_free_busno = hose->last_busno + 1;
241 printf(" PCI1 on bus %02x - %02x\n",
242 hose->first_busno, hose->last_busno);
244 printf(" PCI1: disabled\n");
246 #elif defined CONFIG_MPC8548
247 /* PCI1 not present on MPC8572 */
248 setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_PCI1);
251 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE1_ADDR;
253 host = host_agent_cfg[host_agent].pcie_root[0];
254 width = io_port_cfg[io_sel].pcie_width[0];
257 if (width && !(devdisr & MPC8xxx_DEVDISR_PCIE1)) {
258 printf("\n PCIE1 connected as %s (x%d)",
259 host ? "Root Complex" : "Endpoint", width);
260 if (in_be32(&pci->pme_msg_det)) {
261 out_be32(&pci->pme_msg_det, 0xffffffff);
262 debug(" with errors. Clearing. Now 0x%08x",
263 in_be32(&pci->pme_msg_det));
267 /* outbound memory */
269 CONFIG_SYS_PCIE1_MEM_BASE,
270 CONFIG_SYS_PCIE1_MEM_PHYS,
271 CONFIG_SYS_PCIE1_MEM_SIZE,
276 CONFIG_SYS_PCIE1_IO_BASE,
277 CONFIG_SYS_PCIE1_IO_PHYS,
278 CONFIG_SYS_PCIE1_IO_SIZE,
281 hose->region_count = r - hose->regions;
283 hose->first_busno = first_free_busno;
285 fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);
287 /* Unlock inbound PCI configuration cycles */
289 fsl_pci_config_unlock(hose);
291 first_free_busno = hose->last_busno + 1;
292 printf(" PCIE1 on bus %02x - %02x\n",
293 hose->first_busno, hose->last_busno);
296 setbits_be32(&gur->devdisr, MPC8xxx_DEVDISR_PCIE1);
297 #endif /* CONFIG_PCIE1 */
300 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE2_ADDR;
302 host = host_agent_cfg[host_agent].pcie_root[1];
303 width = io_port_cfg[io_sel].pcie_width[1];
306 if (width && !(devdisr & MPC8xxx_DEVDISR_PCIE2)) {
307 printf("\n PCIE2 connected as %s (x%d)",
308 host ? "Root Complex" : "Endpoint", width);
309 if (in_be32(&pci->pme_msg_det)) {
310 out_be32(&pci->pme_msg_det, 0xffffffff);
311 debug(" with errors. Clearing. Now 0x%08x",
312 in_be32(&pci->pme_msg_det));
316 /* outbound memory */
318 CONFIG_SYS_PCIE2_MEM_BASE,
319 CONFIG_SYS_PCIE2_MEM_PHYS,
320 CONFIG_SYS_PCIE2_MEM_SIZE,
325 CONFIG_SYS_PCIE2_IO_BASE,
326 CONFIG_SYS_PCIE2_IO_PHYS,
327 CONFIG_SYS_PCIE2_IO_SIZE,
330 hose->region_count = r - hose->regions;
332 hose->first_busno = first_free_busno;
334 fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);
336 /* Unlock inbound PCI configuration cycles */
338 fsl_pci_config_unlock(hose);
340 first_free_busno = hose->last_busno + 1;
341 printf(" PCIE2 on bus %02x - %02x\n",
342 hose->first_busno, hose->last_busno);
345 setbits_be32(&gur->devdisr, MPC8xxx_DEVDISR_PCIE2);
346 #endif /* CONFIG_PCIE2 */
349 pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE3_ADDR;
351 host = host_agent_cfg[host_agent].pcie_root[2];
352 width = io_port_cfg[io_sel].pcie_width[2];
355 if (width && !(devdisr & MPC8xxx_DEVDISR_PCIE3)) {
356 printf("\n PCIE3 connected as %s (x%d)",
357 host ? "Root Complex" : "Endpoint", width);
358 if (in_be32(&pci->pme_msg_det)) {
359 out_be32(&pci->pme_msg_det, 0xffffffff);
360 debug(" with errors. Clearing. Now 0x%08x",
361 in_be32(&pci->pme_msg_det));
365 /* outbound memory */
367 CONFIG_SYS_PCIE3_MEM_BASE,
368 CONFIG_SYS_PCIE3_MEM_PHYS,
369 CONFIG_SYS_PCIE3_MEM_SIZE,
374 CONFIG_SYS_PCIE3_IO_BASE,
375 CONFIG_SYS_PCIE3_IO_PHYS,
376 CONFIG_SYS_PCIE3_IO_SIZE,
379 hose->region_count = r - hose->regions;
381 hose->first_busno = first_free_busno;
383 fsl_pci_init(hose, (u32)&pci->cfg_addr, (u32)&pci->cfg_data);
385 /* Unlock inbound PCI configuration cycles */
387 fsl_pci_config_unlock(hose);
389 first_free_busno = hose->last_busno + 1;
390 printf(" PCIE3 on bus %02x - %02x\n",
391 hose->first_busno, hose->last_busno);
394 setbits_be32(&gur->devdisr, MPC8xxx_DEVDISR_PCIE3);
395 #endif /* CONFIG_PCIE3 */
398 #if defined(CONFIG_OF_BOARD_SETUP)
399 void ft_board_pci_setup(void *blob, bd_t *bd)
403 #endif /* CONFIG_OF_BOARD_SETUP */