blob: ac5f30b46e9da375b8c85ddd941400029bd479c3 [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 Phillips94fab252007-12-20 16:28:34 -060033#if defined(CONFIG_OF_LIBFDT)
Kim Phillips5b8bc602007-12-20 14:09:22 -060034#include <libfdt.h>
35#include <fdt_support.h>
36#endif
Paul Gortmaker91e25762007-01-16 11:38:14 -050037
38DECLARE_GLOBAL_DATA_PTR;
39
40#ifdef CONFIG_PCI
41
42/* System RAM mapped to PCI space */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020043#define CONFIG_PCI_SYS_MEM_BUS CONFIG_SYS_SDRAM_BASE
44#define CONFIG_PCI_SYS_MEM_PHYS CONFIG_SYS_SDRAM_BASE
Paul Gortmaker91e25762007-01-16 11:38:14 -050045
46#ifndef CONFIG_PCI_PNP
47static struct pci_config_table pci_mpc8349emds_config_table[] = {
48 {PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
49 PCI_IDSEL_NUMBER, PCI_ANY_ID,
50 pci_cfgfunc_config_device, {PCI_ENET0_IOADDR,
51 PCI_ENET0_MEMADDR,
52 PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
53 }
54 },
55 {}
56};
57#endif
58
59static struct pci_controller pci_hose[] = {
60 {
61#ifndef CONFIG_PCI_PNP
62 config_table:pci_mpc8349emds_config_table,
63#endif
64 },
65 {
66#ifndef CONFIG_PCI_PNP
67 config_table:pci_mpc8349emds_config_table,
68#endif
69 }
70};
71
72/**************************************************************************
73 * pci_init_board()
74 *
75 * NOTICE: PCI2 is not supported. There is only one
76 * physical PCI slot on the board.
77 *
78 */
79void
80pci_init_board(void)
81{
82 volatile immap_t * immr;
83 volatile clk83xx_t * clk;
84 volatile law83xx_t * pci_law;
85 volatile pot83xx_t * pci_pot;
86 volatile pcictrl83xx_t * pci_ctrl;
87 volatile pciconf83xx_t * pci_conf;
88 u16 reg16;
89 u32 reg32;
90 u32 dev;
91 struct pci_controller * hose;
92
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020093 immr = (immap_t *)CONFIG_SYS_IMMR;
Paul Gortmaker91e25762007-01-16 11:38:14 -050094 clk = (clk83xx_t *)&immr->clk;
95 pci_law = immr->sysconf.pcilaw;
96 pci_pot = immr->ios.pot;
97 pci_ctrl = immr->pci_ctrl;
98 pci_conf = immr->pci_conf;
99
100 hose = &pci_hose[0];
101
102 /*
103 * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
104 */
105
106 reg32 = clk->occr;
107 udelay(2000);
108 clk->occr = 0xff000000;
109 udelay(2000);
110
111 /*
112 * Release PCI RST Output signal
113 */
114 pci_ctrl[0].gcr = 0;
115 udelay(2000);
116 pci_ctrl[0].gcr = 1;
117
118#ifdef CONFIG_MPC83XX_PCI2
119 pci_ctrl[1].gcr = 0;
120 udelay(2000);
121 pci_ctrl[1].gcr = 1;
122#endif
123
124 /* We need to wait at least a 1sec based on PCI specs */
125 {
126 int i;
127
128 for (i = 0; i < 1000; ++i)
129 udelay (1000);
130 }
131
132 /*
133 * Configure PCI Local Access Windows
134 */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200135 pci_law[0].bar = CONFIG_SYS_PCI1_MEM_PHYS & LAWBAR_BAR;
Paul Gortmaker91e25762007-01-16 11:38:14 -0500136 pci_law[0].ar = LAWAR_EN | LAWAR_SIZE_1G;
137
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200138 pci_law[1].bar = CONFIG_SYS_PCI1_IO_PHYS & LAWBAR_BAR;
Paul Gortmaker91e25762007-01-16 11:38:14 -0500139 pci_law[1].ar = LAWAR_EN | LAWAR_SIZE_4M;
140
141 /*
142 * Configure PCI Outbound Translation Windows
143 */
144
145 /* PCI1 mem space - prefetch */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200146 pci_pot[0].potar = (CONFIG_SYS_PCI1_MEM_BASE >> 12) & POTAR_TA_MASK;
147 pci_pot[0].pobar = (CONFIG_SYS_PCI1_MEM_PHYS >> 12) & POBAR_BA_MASK;
Paul Gortmaker91e25762007-01-16 11:38:14 -0500148 pci_pot[0].pocmr = POCMR_EN | POCMR_PREFETCH_EN | (POCMR_CM_256M & POCMR_CM_MASK);
149
150 /* PCI1 IO space */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200151 pci_pot[1].potar = (CONFIG_SYS_PCI1_IO_BASE >> 12) & POTAR_TA_MASK;
152 pci_pot[1].pobar = (CONFIG_SYS_PCI1_IO_PHYS >> 12) & POBAR_BA_MASK;
Paul Gortmaker91e25762007-01-16 11:38:14 -0500153 pci_pot[1].pocmr = POCMR_EN | POCMR_IO | (POCMR_CM_1M & POCMR_CM_MASK);
154
155 /* PCI1 mmio - non-prefetch mem space */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200156 pci_pot[2].potar = (CONFIG_SYS_PCI1_MMIO_BASE >> 12) & POTAR_TA_MASK;
157 pci_pot[2].pobar = (CONFIG_SYS_PCI1_MMIO_PHYS >> 12) & POBAR_BA_MASK;
Paul Gortmaker91e25762007-01-16 11:38:14 -0500158 pci_pot[2].pocmr = POCMR_EN | (POCMR_CM_256M & POCMR_CM_MASK);
159
160 /*
161 * Configure PCI Inbound Translation Windows
162 */
163
164 /* we need RAM mapped to PCI space for the devices to
165 * access main memory */
166 pci_ctrl[0].pitar1 = 0x0;
167 pci_ctrl[0].pibar1 = 0x0;
168 pci_ctrl[0].piebar1 = 0x0;
169 pci_ctrl[0].piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1);
170
171 hose->first_busno = 0;
172 hose->last_busno = 0xff;
173
174 /* PCI memory prefetch space */
175 pci_set_region(hose->regions + 0,
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200176 CONFIG_SYS_PCI1_MEM_BASE,
177 CONFIG_SYS_PCI1_MEM_PHYS,
178 CONFIG_SYS_PCI1_MEM_SIZE,
Paul Gortmaker91e25762007-01-16 11:38:14 -0500179 PCI_REGION_MEM|PCI_REGION_PREFETCH);
180
181 /* PCI memory space */
182 pci_set_region(hose->regions + 1,
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200183 CONFIG_SYS_PCI1_MMIO_BASE,
184 CONFIG_SYS_PCI1_MMIO_PHYS,
185 CONFIG_SYS_PCI1_MMIO_SIZE,
Paul Gortmaker91e25762007-01-16 11:38:14 -0500186 PCI_REGION_MEM);
187
188 /* PCI IO space */
189 pci_set_region(hose->regions + 2,
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200190 CONFIG_SYS_PCI1_IO_BASE,
191 CONFIG_SYS_PCI1_IO_PHYS,
192 CONFIG_SYS_PCI1_IO_SIZE,
Paul Gortmaker91e25762007-01-16 11:38:14 -0500193 PCI_REGION_IO);
194
195 /* System memory space */
196 pci_set_region(hose->regions + 3,
197 CONFIG_PCI_SYS_MEM_BUS,
198 CONFIG_PCI_SYS_MEM_PHYS,
199 gd->ram_size,
Kumar Galaff4e66e2009-02-06 09:49:31 -0600200 PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
Paul Gortmaker91e25762007-01-16 11:38:14 -0500201
202 hose->region_count = 4;
203
204 pci_setup_indirect(hose,
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200205 (CONFIG_SYS_IMMR+0x8300),
206 (CONFIG_SYS_IMMR+0x8304));
Paul Gortmaker91e25762007-01-16 11:38:14 -0500207
208 pci_register_hose(hose);
209
210 /*
211 * Write to Command register
212 */
213 reg16 = 0xff;
214 dev = PCI_BDF(hose->first_busno, 0, 0);
215 pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
216 reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
217 pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
218
219 /*
220 * Clear non-reserved bits in status register.
221 */
222 pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
223 pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
224 pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
225
226#ifdef CONFIG_PCI_SCAN_SHOW
227 printf("PCI: Bus Dev VenId DevId Class Int\n");
228#endif
229 /*
230 * Hose scan.
231 */
232 hose->last_busno = pci_hose_scan(hose);
233
234#ifdef CONFIG_MPC83XX_PCI2
235 hose = &pci_hose[1];
236
237 /*
238 * Configure PCI Outbound Translation Windows
239 */
240
241 /* PCI2 mem space - prefetch */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200242 pci_pot[3].potar = (CONFIG_SYS_PCI2_MEM_BASE >> 12) & POTAR_TA_MASK;
243 pci_pot[3].pobar = (CONFIG_SYS_PCI2_MEM_PHYS >> 12) & POBAR_BA_MASK;
Paul Gortmaker91e25762007-01-16 11:38:14 -0500244 pci_pot[3].pocmr = POCMR_EN | POCMR_PCI2 | POCMR_PREFETCH_EN | (POCMR_CM_256M & POCMR_CM_MASK);
245
246 /* PCI2 IO space */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200247 pci_pot[4].potar = (CONFIG_SYS_PCI2_IO_BASE >> 12) & POTAR_TA_MASK;
248 pci_pot[4].pobar = (CONFIG_SYS_PCI2_IO_PHYS >> 12) & POBAR_BA_MASK;
Paul Gortmaker91e25762007-01-16 11:38:14 -0500249 pci_pot[4].pocmr = POCMR_EN | POCMR_PCI2 | POCMR_IO | (POCMR_CM_1M & POCMR_CM_MASK);
250
251 /* PCI2 mmio - non-prefetch mem space */
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200252 pci_pot[5].potar = (CONFIG_SYS_PCI2_MMIO_BASE >> 12) & POTAR_TA_MASK;
253 pci_pot[5].pobar = (CONFIG_SYS_PCI2_MMIO_PHYS >> 12) & POBAR_BA_MASK;
Paul Gortmaker91e25762007-01-16 11:38:14 -0500254 pci_pot[5].pocmr = POCMR_EN | POCMR_PCI2 | (POCMR_CM_256M & POCMR_CM_MASK);
255
256 /*
257 * Configure PCI Inbound Translation Windows
258 */
259
260 /* we need RAM mapped to PCI space for the devices to
261 * access main memory */
262 pci_ctrl[1].pitar1 = 0x0;
263 pci_ctrl[1].pibar1 = 0x0;
264 pci_ctrl[1].piebar1 = 0x0;
265 pci_ctrl[1].piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1);
266
267 hose->first_busno = pci_hose[0].last_busno + 1;
268 hose->last_busno = 0xff;
269
270 /* PCI memory prefetch space */
271 pci_set_region(hose->regions + 0,
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200272 CONFIG_SYS_PCI2_MEM_BASE,
273 CONFIG_SYS_PCI2_MEM_PHYS,
274 CONFIG_SYS_PCI2_MEM_SIZE,
Paul Gortmaker91e25762007-01-16 11:38:14 -0500275 PCI_REGION_MEM|PCI_REGION_PREFETCH);
276
277 /* PCI memory space */
278 pci_set_region(hose->regions + 1,
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200279 CONFIG_SYS_PCI2_MMIO_BASE,
280 CONFIG_SYS_PCI2_MMIO_PHYS,
281 CONFIG_SYS_PCI2_MMIO_SIZE,
Paul Gortmaker91e25762007-01-16 11:38:14 -0500282 PCI_REGION_MEM);
283
284 /* PCI IO space */
285 pci_set_region(hose->regions + 2,
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200286 CONFIG_SYS_PCI2_IO_BASE,
287 CONFIG_SYS_PCI2_IO_PHYS,
288 CONFIG_SYS_PCI2_IO_SIZE,
Paul Gortmaker91e25762007-01-16 11:38:14 -0500289 PCI_REGION_IO);
290
291 /* System memory space */
292 pci_set_region(hose->regions + 3,
293 CONFIG_PCI_SYS_MEM_BUS,
294 CONFIG_PCI_SYS_MEM_PHYS,
295 gd->ram_size,
Kumar Galaff4e66e2009-02-06 09:49:31 -0600296 PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
Paul Gortmaker91e25762007-01-16 11:38:14 -0500297
298 hose->region_count = 4;
299
300 pci_setup_indirect(hose,
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200301 (CONFIG_SYS_IMMR+0x8380),
302 (CONFIG_SYS_IMMR+0x8384));
Paul Gortmaker91e25762007-01-16 11:38:14 -0500303
304 pci_register_hose(hose);
305
306 /*
307 * Write to Command register
308 */
309 reg16 = 0xff;
310 dev = PCI_BDF(hose->first_busno, 0, 0);
311 pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
312 reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
313 pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
314
315 /*
316 * Clear non-reserved bits in status register.
317 */
318 pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
319 pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
320 pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
321
322 /*
323 * Hose scan.
324 */
325 hose->last_busno = pci_hose_scan(hose);
326#endif
327
328}
329
Kim Phillips5b8bc602007-12-20 14:09:22 -0600330#if defined(CONFIG_OF_LIBFDT)
331void ft_pci_setup(void *blob, bd_t *bd)
332{
333 int nodeoffset;
334 int tmp[2];
335 const char *path;
336
337 nodeoffset = fdt_path_offset(blob, "/aliases");
338 if (nodeoffset >= 0) {
339 path = fdt_getprop(blob, nodeoffset, "pci0", NULL);
340 if (path) {
341 tmp[0] = cpu_to_be32(pci_hose[0].first_busno);
342 tmp[1] = cpu_to_be32(pci_hose[0].last_busno);
343 do_fixup_by_path(blob, path, "bus-range",
344 &tmp, sizeof(tmp), 1);
345
346 tmp[0] = cpu_to_be32(gd->pci_clk);
347 do_fixup_by_path(blob, path, "clock-frequency",
348 &tmp, sizeof(tmp[0]), 1);
349 }
350#ifdef CONFIG_MPC83XX_PCI2
351 path = fdt_getprop(blob, nodeoffset, "pci1", NULL);
352 if (path) {
353 tmp[0] = cpu_to_be32(pci_hose[0].first_busno);
354 tmp[1] = cpu_to_be32(pci_hose[0].last_busno);
355 do_fixup_by_path(blob, path, "bus-range",
356 &tmp, sizeof(tmp), 1);
357
358 tmp[0] = cpu_to_be32(gd->pci_clk);
359 do_fixup_by_path(blob, path, "clock-frequency",
360 &tmp, sizeof(tmp[0]), 1);
361 }
362#endif
363 }
364}
Kim Phillips94fab252007-12-20 16:28:34 -0600365#endif /* CONFIG_OF_LIBFDT */
Paul Gortmaker91e25762007-01-16 11:38:14 -0500366#endif /* CONFIG_PCI */