2 * Copyright (C) 2007 Freescale Semiconductor, Inc.
4 * See file CREDITS for list of people who contributed to this
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
19 #include <fdt_support.h>
20 #include <asm/fsl_i2c.h>
21 #include <asm/fsl_serdes.h>
23 #if defined(CONFIG_PCI)
24 static struct pci_region pci_regions
[] = {
26 bus_start
: CONFIG_SYS_PCI_MEM_BASE
,
27 phys_start
: CONFIG_SYS_PCI_MEM_PHYS
,
28 size
: CONFIG_SYS_PCI_MEM_SIZE
,
29 flags
: PCI_REGION_MEM
| PCI_REGION_PREFETCH
32 bus_start
: CONFIG_SYS_PCI_MMIO_BASE
,
33 phys_start
: CONFIG_SYS_PCI_MMIO_PHYS
,
34 size
: CONFIG_SYS_PCI_MMIO_SIZE
,
38 bus_start
: CONFIG_SYS_PCI_IO_BASE
,
39 phys_start
: CONFIG_SYS_PCI_IO_PHYS
,
40 size
: CONFIG_SYS_PCI_IO_SIZE
,
45 static struct pci_region pcie_regions_0
[] = {
47 .bus_start
= CONFIG_SYS_PCIE1_MEM_BASE
,
48 .phys_start
= CONFIG_SYS_PCIE1_MEM_PHYS
,
49 .size
= CONFIG_SYS_PCIE1_MEM_SIZE
,
50 .flags
= PCI_REGION_MEM
,
53 .bus_start
= CONFIG_SYS_PCIE1_IO_BASE
,
54 .phys_start
= CONFIG_SYS_PCIE1_IO_PHYS
,
55 .size
= CONFIG_SYS_PCIE1_IO_SIZE
,
56 .flags
= PCI_REGION_IO
,
60 static struct pci_region pcie_regions_1
[] = {
62 .bus_start
= CONFIG_SYS_PCIE2_MEM_BASE
,
63 .phys_start
= CONFIG_SYS_PCIE2_MEM_PHYS
,
64 .size
= CONFIG_SYS_PCIE2_MEM_SIZE
,
65 .flags
= PCI_REGION_MEM
,
68 .bus_start
= CONFIG_SYS_PCIE2_IO_BASE
,
69 .phys_start
= CONFIG_SYS_PCIE2_IO_PHYS
,
70 .size
= CONFIG_SYS_PCIE2_IO_SIZE
,
71 .flags
= PCI_REGION_IO
,
75 static int is_pex_x2(void)
77 const char *pex_x2
= getenv("pex_x2");
79 if (pex_x2
&& !strcmp(pex_x2
, "yes"))
84 void pci_init_board(void)
86 volatile immap_t
*immr
= (volatile immap_t
*)CONFIG_SYS_IMMR
;
87 volatile sysconf83xx_t
*sysconf
= &immr
->sysconf
;
88 volatile clk83xx_t
*clk
= (volatile clk83xx_t
*)&immr
->clk
;
89 volatile law83xx_t
*pci_law
= immr
->sysconf
.pcilaw
;
90 volatile law83xx_t
*pcie_law
= sysconf
->pcielaw
;
91 struct pci_region
*reg
[] = { pci_regions
};
92 struct pci_region
*pcie_reg
[] = { pcie_regions_0
, pcie_regions_1
, };
93 u32 spridr
= in_be32(&immr
->sysconf
.spridr
);
94 int pex2
= is_pex_x2();
96 if (board_pci_host_broken())
99 /* Enable all 5 PCI_CLK_OUTPUTS */
100 clk
->occr
|= 0xf8000000;
103 /* Configure PCI Local Access Windows */
104 pci_law
[0].bar
= CONFIG_SYS_PCI_MEM_PHYS
& LAWBAR_BAR
;
105 pci_law
[0].ar
= LBLAWAR_EN
| LBLAWAR_512MB
;
107 pci_law
[1].bar
= CONFIG_SYS_PCI_IO_PHYS
& LAWBAR_BAR
;
108 pci_law
[1].ar
= LBLAWAR_EN
| LBLAWAR_1MB
;
112 mpc83xx_pci_init(1, reg
, 0);
114 /* There is no PEX in MPC8379 parts. */
115 if (PARTID_NO_E(spridr
) == SPR_8379
)
119 fsl_setup_serdes(CONFIG_FSL_SERDES2
, FSL_SERDES_PROTO_PEX_X2
,
120 FSL_SERDES_CLK_100
, FSL_SERDES_VDD_1V
);
122 fsl_setup_serdes(CONFIG_FSL_SERDES2
, FSL_SERDES_PROTO_PEX
,
123 FSL_SERDES_CLK_100
, FSL_SERDES_VDD_1V
);
125 /* Configure the clock for PCIE controller */
126 clrsetbits_be32(&clk
->sccr
, SCCR_PCIEXP1CM
| SCCR_PCIEXP2CM
,
127 SCCR_PCIEXP1CM_1
| SCCR_PCIEXP2CM_1
);
129 /* Deassert the resets in the control register */
130 out_be32(&sysconf
->pecr1
, 0xE0008000);
132 out_be32(&sysconf
->pecr2
, 0xE0008000);
135 /* Configure PCI Express Local Access Windows */
136 out_be32(&pcie_law
[0].bar
, CONFIG_SYS_PCIE1_BASE
& LAWBAR_BAR
);
137 out_be32(&pcie_law
[0].ar
, LBLAWAR_EN
| LBLAWAR_512MB
);
139 out_be32(&pcie_law
[1].bar
, CONFIG_SYS_PCIE2_BASE
& LAWBAR_BAR
);
140 out_be32(&pcie_law
[1].ar
, LBLAWAR_EN
| LBLAWAR_512MB
);
142 mpc83xx_pcie_init(pex2
? 1 : 2, pcie_reg
, 0);
145 void ft_pcie_fixup(void *blob
, bd_t
*bd
)
147 const char *status
= "disabled (PCIE1 is x2)";
152 do_fixup_by_path(blob
, "pci2", "status", status
,
153 strlen(status
) + 1, 1);
155 #endif /* CONFIG_PCI */