blob: e59f9f9a59ab18a586ae7433d351b3441a367f97 [file] [log] [blame]
Paul Gortmaker91e25762007-01-16 11:38:14 -05001/*
2 * pci.c -- WindRiver SBC8349 PCI board support.
3 * Copyright (c) 2006 Wind River Systems, Inc.
4 *
5 * Based on MPC8349 PCI support but w/o PIB related code.
6 *
7 * See file CREDITS for list of people who contributed to this
8 * project.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23 * MA 02111-1307 USA
24 *
25 */
26
27#include <asm/mmu.h>
28#include <common.h>
29#include <asm/global_data.h>
30#include <pci.h>
31#include <asm/mpc8349_pci.h>
32#include <i2c.h>
Kim Phillips5b8bc602007-12-20 14:09:22 -060033#if defined(CONFIG_OF_FLAT_TREE)
34#include <ft_build.h>
35#elif defined(CONFIG_OF_LIBFDT)
36#include <libfdt.h>
37#include <fdt_support.h>
38#endif
Paul Gortmaker91e25762007-01-16 11:38:14 -050039
40DECLARE_GLOBAL_DATA_PTR;
41
42#ifdef CONFIG_PCI
43
44/* System RAM mapped to PCI space */
45#define CONFIG_PCI_SYS_MEM_BUS CFG_SDRAM_BASE
46#define CONFIG_PCI_SYS_MEM_PHYS CFG_SDRAM_BASE
47
48#ifndef CONFIG_PCI_PNP
49static struct pci_config_table pci_mpc8349emds_config_table[] = {
50 {PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
51 PCI_IDSEL_NUMBER, PCI_ANY_ID,
52 pci_cfgfunc_config_device, {PCI_ENET0_IOADDR,
53 PCI_ENET0_MEMADDR,
54 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
55 }
56 },
57 {}
58};
59#endif
60
61static struct pci_controller pci_hose[] = {
62 {
63#ifndef CONFIG_PCI_PNP
64 config_table:pci_mpc8349emds_config_table,
65#endif
66 },
67 {
68#ifndef CONFIG_PCI_PNP
69 config_table:pci_mpc8349emds_config_table,
70#endif
71 }
72};
73
74/**************************************************************************
75 * pci_init_board()
76 *
77 * NOTICE: PCI2 is not supported. There is only one
78 * physical PCI slot on the board.
79 *
80 */
81void
82pci_init_board(void)
83{
84 volatile immap_t * immr;
85 volatile clk83xx_t * clk;
86 volatile law83xx_t * pci_law;
87 volatile pot83xx_t * pci_pot;
88 volatile pcictrl83xx_t * pci_ctrl;
89 volatile pciconf83xx_t * pci_conf;
90 u16 reg16;
91 u32 reg32;
92 u32 dev;
93 struct pci_controller * hose;
94
95 immr = (immap_t *)CFG_IMMR;
96 clk = (clk83xx_t *)&immr->clk;
97 pci_law = immr->sysconf.pcilaw;
98 pci_pot = immr->ios.pot;
99 pci_ctrl = immr->pci_ctrl;
100 pci_conf = immr->pci_conf;
101
102 hose = &pci_hose[0];
103
104 /*
105 * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
106 */
107
108 reg32 = clk->occr;
109 udelay(2000);
110 clk->occr = 0xff000000;
111 udelay(2000);
112
113 /*
114 * Release PCI RST Output signal
115 */
116 pci_ctrl[0].gcr = 0;
117 udelay(2000);
118 pci_ctrl[0].gcr = 1;
119
120#ifdef CONFIG_MPC83XX_PCI2
121 pci_ctrl[1].gcr = 0;
122 udelay(2000);
123 pci_ctrl[1].gcr = 1;
124#endif
125
126 /* We need to wait at least a 1sec based on PCI specs */
127 {
128 int i;
129
130 for (i = 0; i < 1000; ++i)
131 udelay (1000);
132 }
133
134 /*
135 * Configure PCI Local Access Windows
136 */
137 pci_law[0].bar = CFG_PCI1_MEM_PHYS & LAWBAR_BAR;
138 pci_law[0].ar = LAWAR_EN | LAWAR_SIZE_1G;
139
140 pci_law[1].bar = CFG_PCI1_IO_PHYS & LAWBAR_BAR;
141 pci_law[1].ar = LAWAR_EN | LAWAR_SIZE_4M;
142
143 /*
144 * Configure PCI Outbound Translation Windows
145 */
146
147 /* PCI1 mem space - prefetch */
148 pci_pot[0].potar = (CFG_PCI1_MEM_BASE >> 12) & POTAR_TA_MASK;
149 pci_pot[0].pobar = (CFG_PCI1_MEM_PHYS >> 12) & POBAR_BA_MASK;
150 pci_pot[0].pocmr = POCMR_EN | POCMR_PREFETCH_EN | (POCMR_CM_256M & POCMR_CM_MASK);
151
152 /* PCI1 IO space */
153 pci_pot[1].potar = (CFG_PCI1_IO_BASE >> 12) & POTAR_TA_MASK;
154 pci_pot[1].pobar = (CFG_PCI1_IO_PHYS >> 12) & POBAR_BA_MASK;
155 pci_pot[1].pocmr = POCMR_EN | POCMR_IO | (POCMR_CM_1M & POCMR_CM_MASK);
156
157 /* PCI1 mmio - non-prefetch mem space */
158 pci_pot[2].potar = (CFG_PCI1_MMIO_BASE >> 12) & POTAR_TA_MASK;
159 pci_pot[2].pobar = (CFG_PCI1_MMIO_PHYS >> 12) & POBAR_BA_MASK;
160 pci_pot[2].pocmr = POCMR_EN | (POCMR_CM_256M & POCMR_CM_MASK);
161
162 /*
163 * Configure PCI Inbound Translation Windows
164 */
165
166 /* we need RAM mapped to PCI space for the devices to
167 * access main memory */
168 pci_ctrl[0].pitar1 = 0x0;
169 pci_ctrl[0].pibar1 = 0x0;
170 pci_ctrl[0].piebar1 = 0x0;
171 pci_ctrl[0].piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1);
172
173 hose->first_busno = 0;
174 hose->last_busno = 0xff;
175
176 /* PCI memory prefetch space */
177 pci_set_region(hose->regions + 0,
178 CFG_PCI1_MEM_BASE,
179 CFG_PCI1_MEM_PHYS,
180 CFG_PCI1_MEM_SIZE,
181 PCI_REGION_MEM|PCI_REGION_PREFETCH);
182
183 /* PCI memory space */
184 pci_set_region(hose->regions + 1,
185 CFG_PCI1_MMIO_BASE,
186 CFG_PCI1_MMIO_PHYS,
187 CFG_PCI1_MMIO_SIZE,
188 PCI_REGION_MEM);
189
190 /* PCI IO space */
191 pci_set_region(hose->regions + 2,
192 CFG_PCI1_IO_BASE,
193 CFG_PCI1_IO_PHYS,
194 CFG_PCI1_IO_SIZE,
195 PCI_REGION_IO);
196
197 /* System memory space */
198 pci_set_region(hose->regions + 3,
199 CONFIG_PCI_SYS_MEM_BUS,
200 CONFIG_PCI_SYS_MEM_PHYS,
201 gd->ram_size,
202 PCI_REGION_MEM | PCI_REGION_MEMORY);
203
204 hose->region_count = 4;
205
206 pci_setup_indirect(hose,
207 (CFG_IMMR+0x8300),
208 (CFG_IMMR+0x8304));
209
210 pci_register_hose(hose);
211
212 /*
213 * Write to Command register
214 */
215 reg16 = 0xff;
216 dev = PCI_BDF(hose->first_busno, 0, 0);
217 pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
218 reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
219 pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
220
221 /*
222 * Clear non-reserved bits in status register.
223 */
224 pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
225 pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
226 pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
227
228#ifdef CONFIG_PCI_SCAN_SHOW
229 printf("PCI: Bus Dev VenId DevId Class Int\n");
230#endif
231 /*
232 * Hose scan.
233 */
234 hose->last_busno = pci_hose_scan(hose);
235
236#ifdef CONFIG_MPC83XX_PCI2
237 hose = &pci_hose[1];
238
239 /*
240 * Configure PCI Outbound Translation Windows
241 */
242
243 /* PCI2 mem space - prefetch */
244 pci_pot[3].potar = (CFG_PCI2_MEM_BASE >> 12) & POTAR_TA_MASK;
245 pci_pot[3].pobar = (CFG_PCI2_MEM_PHYS >> 12) & POBAR_BA_MASK;
246 pci_pot[3].pocmr = POCMR_EN | POCMR_PCI2 | POCMR_PREFETCH_EN | (POCMR_CM_256M & POCMR_CM_MASK);
247
248 /* PCI2 IO space */
249 pci_pot[4].potar = (CFG_PCI2_IO_BASE >> 12) & POTAR_TA_MASK;
250 pci_pot[4].pobar = (CFG_PCI2_IO_PHYS >> 12) & POBAR_BA_MASK;
251 pci_pot[4].pocmr = POCMR_EN | POCMR_PCI2 | POCMR_IO | (POCMR_CM_1M & POCMR_CM_MASK);
252
253 /* PCI2 mmio - non-prefetch mem space */
254 pci_pot[5].potar = (CFG_PCI2_MMIO_BASE >> 12) & POTAR_TA_MASK;
255 pci_pot[5].pobar = (CFG_PCI2_MMIO_PHYS >> 12) & POBAR_BA_MASK;
256 pci_pot[5].pocmr = POCMR_EN | POCMR_PCI2 | (POCMR_CM_256M & POCMR_CM_MASK);
257
258 /*
259 * Configure PCI Inbound Translation Windows
260 */
261
262 /* we need RAM mapped to PCI space for the devices to
263 * access main memory */
264 pci_ctrl[1].pitar1 = 0x0;
265 pci_ctrl[1].pibar1 = 0x0;
266 pci_ctrl[1].piebar1 = 0x0;
267 pci_ctrl[1].piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1);
268
269 hose->first_busno = pci_hose[0].last_busno + 1;
270 hose->last_busno = 0xff;
271
272 /* PCI memory prefetch space */
273 pci_set_region(hose->regions + 0,
274 CFG_PCI2_MEM_BASE,
275 CFG_PCI2_MEM_PHYS,
276 CFG_PCI2_MEM_SIZE,
277 PCI_REGION_MEM|PCI_REGION_PREFETCH);
278
279 /* PCI memory space */
280 pci_set_region(hose->regions + 1,
281 CFG_PCI2_MMIO_BASE,
282 CFG_PCI2_MMIO_PHYS,
283 CFG_PCI2_MMIO_SIZE,
284 PCI_REGION_MEM);
285
286 /* PCI IO space */
287 pci_set_region(hose->regions + 2,
288 CFG_PCI2_IO_BASE,
289 CFG_PCI2_IO_PHYS,
290 CFG_PCI2_IO_SIZE,
291 PCI_REGION_IO);
292
293 /* System memory space */
294 pci_set_region(hose->regions + 3,
295 CONFIG_PCI_SYS_MEM_BUS,
296 CONFIG_PCI_SYS_MEM_PHYS,
297 gd->ram_size,
298 PCI_REGION_MEM | PCI_REGION_MEMORY);
299
300 hose->region_count = 4;
301
302 pci_setup_indirect(hose,
303 (CFG_IMMR+0x8380),
304 (CFG_IMMR+0x8384));
305
306 pci_register_hose(hose);
307
308 /*
309 * Write to Command register
310 */
311 reg16 = 0xff;
312 dev = PCI_BDF(hose->first_busno, 0, 0);
313 pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
314 reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
315 pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
316
317 /*
318 * Clear non-reserved bits in status register.
319 */
320 pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
321 pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
322 pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
323
324 /*
325 * Hose scan.
326 */
327 hose->last_busno = pci_hose_scan(hose);
328#endif
329
330}
331
Kim Phillips5b8bc602007-12-20 14:09:22 -0600332#if defined(CONFIG_OF_LIBFDT)
333void ft_pci_setup(void *blob, bd_t *bd)
334{
335 int nodeoffset;
336 int tmp[2];
337 const char *path;
338
339 nodeoffset = fdt_path_offset(blob, "/aliases");
340 if (nodeoffset >= 0) {
341 path = fdt_getprop(blob, nodeoffset, "pci0", NULL);
342 if (path) {
343 tmp[0] = cpu_to_be32(pci_hose[0].first_busno);
344 tmp[1] = cpu_to_be32(pci_hose[0].last_busno);
345 do_fixup_by_path(blob, path, "bus-range",
346 &tmp, sizeof(tmp), 1);
347
348 tmp[0] = cpu_to_be32(gd->pci_clk);
349 do_fixup_by_path(blob, path, "clock-frequency",
350 &tmp, sizeof(tmp[0]), 1);
351 }
352#ifdef CONFIG_MPC83XX_PCI2
353 path = fdt_getprop(blob, nodeoffset, "pci1", NULL);
354 if (path) {
355 tmp[0] = cpu_to_be32(pci_hose[0].first_busno);
356 tmp[1] = cpu_to_be32(pci_hose[0].last_busno);
357 do_fixup_by_path(blob, path, "bus-range",
358 &tmp, sizeof(tmp), 1);
359
360 tmp[0] = cpu_to_be32(gd->pci_clk);
361 do_fixup_by_path(blob, path, "clock-frequency",
362 &tmp, sizeof(tmp[0]), 1);
363 }
364#endif
365 }
366}
367#elif defined(CONFIG_OF_FLAT_TREE)
Paul Gortmaker91e25762007-01-16 11:38:14 -0500368void
369ft_pci_setup(void *blob, bd_t *bd)
370{
371 u32 *p;
372 int len;
373
374 p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8500/bus-range", &len);
375 if (p != NULL) {
376 p[0] = pci_hose[0].first_busno;
377 p[1] = pci_hose[0].last_busno;
378 }
379
380#ifdef CONFIG_MPC83XX_PCI2
381 p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8600/bus-range", &len);
382 if (p != NULL) {
383 p[0] = pci_hose[1].first_busno;
384 p[1] = pci_hose[1].last_busno;
385 }
386#endif
387}
388#endif /* CONFIG_OF_FLAT_TREE */
389#endif /* CONFIG_PCI */