MPC8260ADS: Define CONFIG_HAS_ETH0.
[platform/kernel/u-boot.git] / board / xes / common / fsl_85xx_pci.c
1 /*
2  * Copyright 2008 Extreme Engineering Solutions, Inc.
3  * Copyright 2007-2008 Freescale Semiconductor, Inc.
4  *
5  * See file CREDITS for list of people who contributed to this
6  * project.
7  *
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.
12  *
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.
17  *
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,
21  * MA 02111-1307 USA
22  */
23
24 #include <common.h>
25 #include <pci.h>
26 #include <asm/immap_85xx.h>
27 #include <asm/immap_fsl_pci.h>
28 #include <libfdt.h>
29 #include <fdt_support.h>
30
31 extern int fsl_pci_setup_inbound_windows(struct pci_region *r);
32 extern void fsl_pci_config_unlock(struct pci_controller *hose);
33 extern void fsl_pci_init(struct pci_controller *hose);
34
35 int first_free_busno = 0;
36
37 #ifdef CONFIG_PCI1
38 static struct pci_controller pci1_hose;
39 #endif
40 #ifdef CONFIG_PCIE1
41 static struct pci_controller pcie1_hose;
42 #endif
43 #ifdef CONFIG_PCIE2
44 static struct pci_controller pcie2_hose;
45 #endif
46 #ifdef CONFIG_PCIE3
47 static struct pci_controller pcie3_hose;
48 #endif
49
50 #ifdef CONFIG_MPC8572
51 /* Correlate host/agent POR bits to usable info. Table 4-14 */
52 struct host_agent_cfg_t {
53         uchar pcie_root[3];
54         uchar rio_host;
55 } host_agent_cfg[8] = {
56         {{0, 0, 0}, 0},
57         {{0, 1, 1}, 1},
58         {{1, 0, 1}, 0},
59         {{1, 1, 0}, 1},
60         {{0, 0, 1}, 0},
61         {{0, 1, 0}, 1},
62         {{1, 0, 0}, 0},
63         {{1, 1, 1}, 1}
64 };
65
66 /* Correlate port width POR bits to usable info. Table 4-15 */
67 struct io_port_cfg_t {
68         uchar pcie_width[3];
69         uchar rio_width;
70 } io_port_cfg[16] = {
71         {{0, 0, 0}, 0},
72         {{0, 0, 0}, 0},
73         {{4, 0, 0}, 0},
74         {{4, 4, 0}, 0},
75         {{0, 0, 0}, 0},
76         {{0, 0, 0}, 0},
77         {{0, 0, 0}, 4},
78         {{4, 2, 2}, 0},
79         {{0, 0, 0}, 0},
80         {{0, 0, 0}, 0},
81         {{0, 0, 0}, 0},
82         {{4, 0, 0}, 4},
83         {{4, 0, 0}, 4},
84         {{0, 0, 0}, 4},
85         {{0, 0, 0}, 4},
86         {{8, 0, 0}, 0},
87 };
88 #elif defined CONFIG_MPC8548
89 /* Correlate host/agent POR bits to usable info. Table 4-12 */
90 struct host_agent_cfg_t {
91         uchar pci_host[2];
92         uchar pcie_root[1];
93         uchar rio_host;
94 } host_agent_cfg[8] = {
95         {{1, 1}, {0}, 0},
96         {{1, 1}, {1}, 0},
97         {{1, 1}, {0}, 1},
98         {{0, 0}, {0}, 0}, /* reserved */
99         {{0, 1}, {1}, 0},
100         {{1, 1}, {1}, 0},
101         {{0, 1}, {1}, 1},
102         {{1, 1}, {1}, 1}
103 };
104
105 /* Correlate port width POR bits to usable info. Table 4-13 */
106 struct io_port_cfg_t {
107         uchar pcie_width[1];
108         uchar rio_width;
109 } io_port_cfg[8] = {
110         {{0}, 0},
111         {{0}, 0},
112         {{0}, 0},
113         {{4}, 4},
114         {{4}, 4},
115         {{0}, 4},
116         {{0}, 4},
117         {{8}, 0},
118 };
119 #endif
120
121 void pci_init_board(void)
122 {
123         struct pci_controller *hose;
124         volatile ccsr_fsl_pci_t *pci;
125         int width;
126         int host;
127         volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
128         uint devdisr = gur->devdisr;
129         uint io_sel = (gur->pordevsr & MPC85xx_PORDEVSR_IO_SEL) >> 19;
130         uint host_agent = (gur->porbmsr & MPC85xx_PORBMSR_HA) >> 16;
131         struct pci_region *r;
132
133 #ifdef CONFIG_PCI1
134         uint pci_spd_norm = (gur->pordevsr & MPC85xx_PORDEVSR_PCI1_SPD);
135         uint pci_32 = gur->pordevsr & MPC85xx_PORDEVSR_PCI1_PCI32;
136         uint pci_arb = gur->pordevsr & MPC85xx_PORDEVSR_PCI1_ARB;
137         uint pcix = gur->pordevsr & MPC85xx_PORDEVSR_PCI1;
138         uint freq = CONFIG_SYS_CLK_FREQ / 1000 / 1000;
139
140         width = 0; /* Silence compiler warning... */
141         io_sel &= 0xf; /* Silence compiler warning... */
142         pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCI1_ADDR;
143         hose = &pci1_hose;
144         host = host_agent_cfg[host_agent].pci_host[0];
145         r = hose->regions;
146
147
148         if (!(devdisr & MPC85xx_DEVDISR_PCI1)) {
149                 printf("\n    PCI1: %d bit %s, %s %d MHz, %s, %s\n",
150                         pci_32 ? 32 : 64,
151                         pcix ? "PCIX" : "PCI",
152                         pci_spd_norm ?  ">=" : "<=",
153                         pcix ? freq * 2 : freq,
154                         host ? "host" : "agent",
155                         pci_arb ? "arbiter" : "external-arbiter");
156
157                 /* inbound */
158                 r += fsl_pci_setup_inbound_windows(r);
159
160                 /* outbound memory */
161                 pci_set_region(r++,
162                                 CONFIG_SYS_PCI1_MEM_BASE,
163                                 CONFIG_SYS_PCI1_MEM_PHYS,
164                                 CONFIG_SYS_PCI1_MEM_SIZE,
165                                 PCI_REGION_MEM);
166
167                 /* outbound io */
168                 pci_set_region(r++,
169                                 CONFIG_SYS_PCI1_IO_BASE,
170                                 CONFIG_SYS_PCI1_IO_PHYS,
171                                 CONFIG_SYS_PCI1_IO_SIZE,
172                                 PCI_REGION_IO);
173
174                 hose->region_count = r - hose->regions;
175
176                 hose->first_busno = first_free_busno;
177                 pci_setup_indirect(hose, (int)&pci->cfg_addr,
178                                    (int)&pci->cfg_data);
179
180                 fsl_pci_init(hose);
181
182                 /* Unlock inbound PCI configuration cycles */
183                 if (!host)
184                         fsl_pci_config_unlock(hose);
185
186                 first_free_busno = hose->last_busno + 1;
187                 printf("    PCI1 on bus %02x - %02x\n",
188                         hose->first_busno, hose->last_busno);
189         } else {
190                 printf("    PCI1: disabled\n");
191         }
192 #elif defined CONFIG_MPC8548
193         /* PCI1 not present on MPC8572 */
194         gur->devdisr |= MPC85xx_DEVDISR_PCI1; /* disable */
195 #endif
196 #ifdef CONFIG_PCIE1
197         pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE1_ADDR;
198         hose = &pcie1_hose;
199         host = host_agent_cfg[host_agent].pcie_root[0];
200         width = io_port_cfg[io_sel].pcie_width[0];
201         r = hose->regions;
202
203         if (width && !(devdisr & MPC85xx_DEVDISR_PCIE)) {
204                 printf("\n    PCIE1 connected as %s (x%d)",
205                         host ? "Root Complex" : "End Point", width);
206                 if (pci->pme_msg_det) {
207                         pci->pme_msg_det = 0xffffffff;
208                         debug(" with errors.  Clearing.  Now 0x%08x",
209                                 pci->pme_msg_det);
210                 }
211                 printf("\n");
212
213                 /* inbound */
214                 r += fsl_pci_setup_inbound_windows(r);
215
216                 /* outbound memory */
217                 pci_set_region(r++,
218                                 CONFIG_SYS_PCIE1_MEM_BASE,
219                                 CONFIG_SYS_PCIE1_MEM_PHYS,
220                                 CONFIG_SYS_PCIE1_MEM_SIZE,
221                                 PCI_REGION_MEM);
222
223                 /* outbound io */
224                 pci_set_region(r++,
225                                 CONFIG_SYS_PCIE1_IO_BASE,
226                                 CONFIG_SYS_PCIE1_IO_PHYS,
227                                 CONFIG_SYS_PCIE1_IO_SIZE,
228                                 PCI_REGION_IO);
229
230                 hose->region_count = r - hose->regions;
231
232                 hose->first_busno = first_free_busno;
233                 pci_setup_indirect(hose, (int)&pci->cfg_addr,
234                                         (int) &pci->cfg_data);
235
236                 fsl_pci_init(hose);
237
238                 /* Unlock inbound PCI configuration cycles */
239                 if (!host)
240                         fsl_pci_config_unlock(hose);
241
242                 first_free_busno = hose->last_busno + 1;
243                 printf("    PCIE1 on bus %02x - %02x\n",
244                                 hose->first_busno, hose->last_busno);
245         }
246 #else
247         gur->devdisr |= MPC85xx_DEVDISR_PCIE; /* disable */
248 #endif /* CONFIG_PCIE1 */
249
250 #ifdef CONFIG_PCIE2
251         pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE2_ADDR;
252         hose = &pcie2_hose;
253         host = host_agent_cfg[host_agent].pcie_root[1];
254         width = io_port_cfg[io_sel].pcie_width[1];
255         r = hose->regions;
256
257         if (width && !(devdisr & MPC85xx_DEVDISR_PCIE2)) {
258                 printf("\n    PCIE2 connected as %s (x%d)",
259                         host ? "Root Complex" : "End Point", width);
260                 if (pci->pme_msg_det) {
261                         pci->pme_msg_det = 0xffffffff;
262                         debug(" with errors.  Clearing.  Now 0x%08x",
263                                 pci->pme_msg_det);
264                 }
265                 printf("\n");
266
267                 /* inbound */
268                 r += fsl_pci_setup_inbound_windows(r);
269
270                 /* outbound memory */
271                 pci_set_region(r++,
272                                 CONFIG_SYS_PCIE2_MEM_BASE,
273                                 CONFIG_SYS_PCIE2_MEM_PHYS,
274                                 CONFIG_SYS_PCIE2_MEM_SIZE,
275                                 PCI_REGION_MEM);
276
277                 /* outbound io */
278                 pci_set_region(r++,
279                                 CONFIG_SYS_PCIE2_IO_BASE,
280                                 CONFIG_SYS_PCIE2_IO_PHYS,
281                                 CONFIG_SYS_PCIE2_IO_SIZE,
282                                 PCI_REGION_IO);
283
284                 hose->region_count = r - hose->regions;
285
286                 hose->first_busno = first_free_busno;
287                 pci_setup_indirect(hose, (int)&pci->cfg_addr,
288                                         (int)&pci->cfg_data);
289
290                 fsl_pci_init(hose);
291
292                 /* Unlock inbound PCI configuration cycles */
293                 if (!host)
294                         fsl_pci_config_unlock(hose);
295
296                 first_free_busno = hose->last_busno + 1;
297                 printf("    PCIE2 on bus %02x - %02x\n",
298                                 hose->first_busno, hose->last_busno);
299         }
300 #else
301         gur->devdisr |= MPC85xx_DEVDISR_PCIE2; /* disable */
302 #endif /* CONFIG_PCIE2 */
303
304 #ifdef CONFIG_PCIE3
305         pci = (ccsr_fsl_pci_t *) CONFIG_SYS_PCIE3_ADDR;
306         hose = &pcie3_hose;
307         host = host_agent_cfg[host_agent].pcie_root[2];
308         width = io_port_cfg[io_sel].pcie_width[2];
309         r = hose->regions;
310
311         if (width && !(devdisr & MPC85xx_DEVDISR_PCIE3)) {
312                 printf("\n    PCIE3 connected as %s (x%d)",
313                         host ? "Root Complex" : "End Point", width);
314                 if (pci->pme_msg_det) {
315                         pci->pme_msg_det = 0xffffffff;
316                         debug(" with errors.  Clearing.  Now 0x%08x",
317                                 pci->pme_msg_det);
318                 }
319                 printf("\n");
320
321                 /* inbound */
322                 r += fsl_pci_setup_inbound_windows(r);
323
324                 /* outbound memory */
325                 pci_set_region(r++,
326                                 CONFIG_SYS_PCIE3_MEM_BASE,
327                                 CONFIG_SYS_PCIE3_MEM_PHYS,
328                                 CONFIG_SYS_PCIE3_MEM_SIZE,
329                                 PCI_REGION_MEM);
330
331                 /* outbound io */
332                 pci_set_region(r++,
333                                 CONFIG_SYS_PCIE3_IO_BASE,
334                                 CONFIG_SYS_PCIE3_IO_PHYS,
335                                 CONFIG_SYS_PCIE3_IO_SIZE,
336                                 PCI_REGION_IO);
337
338                 hose->region_count = r - hose->regions;
339
340                 hose->first_busno = first_free_busno;
341                 pci_setup_indirect(hose, (int)&pci->cfg_addr,
342                                         (int)&pci->cfg_data);
343
344                 fsl_pci_init(hose);
345
346                 /* Unlock inbound PCI configuration cycles */
347                 if (!host)
348                         fsl_pci_config_unlock(hose);
349
350                 first_free_busno = hose->last_busno + 1;
351                 printf("    PCIE3 on bus %02x - %02x\n",
352                                 hose->first_busno, hose->last_busno);
353         }
354 #else
355         gur->devdisr |= MPC85xx_DEVDISR_PCIE3; /* disable */
356 #endif /* CONFIG_PCIE3 */
357 }
358
359 #if defined(CONFIG_OF_BOARD_SETUP)
360 extern void ft_fsl_pci_setup(void *blob, const char *pci_alias,
361                                 struct pci_controller *hose);
362
363 void ft_board_pci_setup(void *blob, bd_t *bd)
364 {
365         /* TODO - make node name (eg pci0) dynamic */
366 #ifdef CONFIG_PCI1
367         ft_fsl_pci_setup(blob, "pci0", &pci1_hose);
368 #endif
369 #ifdef CONFIG_PCIE1
370         ft_fsl_pci_setup(blob, "pci2", &pcie1_hose);
371 #endif
372 #ifdef CONFIG_PCIE2
373         ft_fsl_pci_setup(blob, "pci1", &pcie2_hose);
374 #endif
375 #ifdef CONFIG_PCIE3
376         ft_fsl_pci_setup(blob, "pci0", &pcie3_hose);
377 #endif
378 }
379 #endif /* CONFIG_OF_BOARD_SETUP */