xref: /openbmc/u-boot/board/sbc8349/pci.c (revision 69df3c4d)
1 /*
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>
33 
34 DECLARE_GLOBAL_DATA_PTR;
35 
36 #ifdef CONFIG_PCI
37 
38 /* System RAM mapped to PCI space */
39 #define CONFIG_PCI_SYS_MEM_BUS	CFG_SDRAM_BASE
40 #define CONFIG_PCI_SYS_MEM_PHYS	CFG_SDRAM_BASE
41 
42 #ifndef CONFIG_PCI_PNP
43 static struct pci_config_table pci_mpc8349emds_config_table[] = {
44 	{PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
45 	 PCI_IDSEL_NUMBER, PCI_ANY_ID,
46 	 pci_cfgfunc_config_device, {PCI_ENET0_IOADDR,
47 				     PCI_ENET0_MEMADDR,
48 				     PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER
49 		}
50 	},
51 	{}
52 };
53 #endif
54 
55 static struct pci_controller pci_hose[] = {
56        {
57 #ifndef CONFIG_PCI_PNP
58        config_table:pci_mpc8349emds_config_table,
59 #endif
60        },
61        {
62 #ifndef CONFIG_PCI_PNP
63        config_table:pci_mpc8349emds_config_table,
64 #endif
65        }
66 };
67 
68 /**************************************************************************
69  * pci_init_board()
70  *
71  * NOTICE: PCI2 is not supported. There is only one
72  * physical PCI slot on the board.
73  *
74  */
75 void
76 pci_init_board(void)
77 {
78 	volatile immap_t *	immr;
79 	volatile clk83xx_t *	clk;
80 	volatile law83xx_t *	pci_law;
81 	volatile pot83xx_t *	pci_pot;
82 	volatile pcictrl83xx_t *	pci_ctrl;
83 	volatile pciconf83xx_t *	pci_conf;
84 	u16 reg16;
85 	u32 reg32;
86 	u32 dev;
87 	struct	pci_controller * hose;
88 
89 	immr = (immap_t *)CFG_IMMR;
90 	clk = (clk83xx_t *)&immr->clk;
91 	pci_law = immr->sysconf.pcilaw;
92 	pci_pot = immr->ios.pot;
93 	pci_ctrl = immr->pci_ctrl;
94 	pci_conf = immr->pci_conf;
95 
96 	hose = &pci_hose[0];
97 
98 	/*
99 	 * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
100 	 */
101 
102 	reg32 = clk->occr;
103 	udelay(2000);
104 	clk->occr = 0xff000000;
105 	udelay(2000);
106 
107 	/*
108 	 * Release PCI RST Output signal
109 	 */
110 	pci_ctrl[0].gcr = 0;
111 	udelay(2000);
112 	pci_ctrl[0].gcr = 1;
113 
114 #ifdef CONFIG_MPC83XX_PCI2
115 	pci_ctrl[1].gcr = 0;
116 	udelay(2000);
117 	pci_ctrl[1].gcr = 1;
118 #endif
119 
120 	/* We need to wait at least a 1sec based on PCI specs */
121 	{
122 		int i;
123 
124 		for (i = 0; i < 1000; ++i)
125 			udelay (1000);
126 	}
127 
128 	/*
129 	 * Configure PCI Local Access Windows
130 	 */
131 	pci_law[0].bar = CFG_PCI1_MEM_PHYS & LAWBAR_BAR;
132 	pci_law[0].ar = LAWAR_EN | LAWAR_SIZE_1G;
133 
134 	pci_law[1].bar = CFG_PCI1_IO_PHYS & LAWBAR_BAR;
135 	pci_law[1].ar = LAWAR_EN | LAWAR_SIZE_4M;
136 
137 	/*
138 	 * Configure PCI Outbound Translation Windows
139 	 */
140 
141 	/* PCI1 mem space - prefetch */
142 	pci_pot[0].potar = (CFG_PCI1_MEM_BASE >> 12) & POTAR_TA_MASK;
143 	pci_pot[0].pobar = (CFG_PCI1_MEM_PHYS >> 12) & POBAR_BA_MASK;
144 	pci_pot[0].pocmr = POCMR_EN | POCMR_PREFETCH_EN | (POCMR_CM_256M & POCMR_CM_MASK);
145 
146 	/* PCI1 IO space */
147 	pci_pot[1].potar = (CFG_PCI1_IO_BASE >> 12) & POTAR_TA_MASK;
148 	pci_pot[1].pobar = (CFG_PCI1_IO_PHYS >> 12) & POBAR_BA_MASK;
149 	pci_pot[1].pocmr = POCMR_EN | POCMR_IO | (POCMR_CM_1M & POCMR_CM_MASK);
150 
151 	/* PCI1 mmio - non-prefetch mem space */
152 	pci_pot[2].potar = (CFG_PCI1_MMIO_BASE >> 12) & POTAR_TA_MASK;
153 	pci_pot[2].pobar = (CFG_PCI1_MMIO_PHYS >> 12) & POBAR_BA_MASK;
154 	pci_pot[2].pocmr = POCMR_EN | (POCMR_CM_256M & POCMR_CM_MASK);
155 
156 	/*
157 	 * Configure PCI Inbound Translation Windows
158 	 */
159 
160 	/* we need RAM mapped to PCI space for the devices to
161 	 * access main memory */
162 	pci_ctrl[0].pitar1 = 0x0;
163 	pci_ctrl[0].pibar1 = 0x0;
164 	pci_ctrl[0].piebar1 = 0x0;
165 	pci_ctrl[0].piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1);
166 
167 	hose->first_busno = 0;
168 	hose->last_busno = 0xff;
169 
170 	/* PCI memory prefetch space */
171 	pci_set_region(hose->regions + 0,
172 		       CFG_PCI1_MEM_BASE,
173 		       CFG_PCI1_MEM_PHYS,
174 		       CFG_PCI1_MEM_SIZE,
175 		       PCI_REGION_MEM|PCI_REGION_PREFETCH);
176 
177 	/* PCI memory space */
178 	pci_set_region(hose->regions + 1,
179 		       CFG_PCI1_MMIO_BASE,
180 		       CFG_PCI1_MMIO_PHYS,
181 		       CFG_PCI1_MMIO_SIZE,
182 		       PCI_REGION_MEM);
183 
184 	/* PCI IO space */
185 	pci_set_region(hose->regions + 2,
186 		       CFG_PCI1_IO_BASE,
187 		       CFG_PCI1_IO_PHYS,
188 		       CFG_PCI1_IO_SIZE,
189 		       PCI_REGION_IO);
190 
191 	/* System memory space */
192 	pci_set_region(hose->regions + 3,
193 		       CONFIG_PCI_SYS_MEM_BUS,
194 		       CONFIG_PCI_SYS_MEM_PHYS,
195 		       gd->ram_size,
196 		       PCI_REGION_MEM | PCI_REGION_MEMORY);
197 
198 	hose->region_count = 4;
199 
200 	pci_setup_indirect(hose,
201 			   (CFG_IMMR+0x8300),
202 			   (CFG_IMMR+0x8304));
203 
204 	pci_register_hose(hose);
205 
206 	/*
207 	 * Write to Command register
208 	 */
209 	reg16 = 0xff;
210 	dev = PCI_BDF(hose->first_busno, 0, 0);
211 	pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
212 	reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
213 	pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
214 
215 	/*
216 	 * Clear non-reserved bits in status register.
217 	 */
218 	pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
219 	pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
220 	pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
221 
222 #ifdef CONFIG_PCI_SCAN_SHOW
223 	printf("PCI:   Bus Dev VenId DevId Class Int\n");
224 #endif
225 	/*
226 	 * Hose scan.
227 	 */
228 	hose->last_busno = pci_hose_scan(hose);
229 
230 #ifdef CONFIG_MPC83XX_PCI2
231 	hose = &pci_hose[1];
232 
233 	/*
234 	 * Configure PCI Outbound Translation Windows
235 	 */
236 
237 	/* PCI2 mem space - prefetch */
238 	pci_pot[3].potar = (CFG_PCI2_MEM_BASE >> 12) & POTAR_TA_MASK;
239 	pci_pot[3].pobar = (CFG_PCI2_MEM_PHYS >> 12) & POBAR_BA_MASK;
240 	pci_pot[3].pocmr = POCMR_EN | POCMR_PCI2 | POCMR_PREFETCH_EN | (POCMR_CM_256M & POCMR_CM_MASK);
241 
242 	/* PCI2 IO space */
243 	pci_pot[4].potar = (CFG_PCI2_IO_BASE >> 12) & POTAR_TA_MASK;
244 	pci_pot[4].pobar = (CFG_PCI2_IO_PHYS >> 12) & POBAR_BA_MASK;
245 	pci_pot[4].pocmr = POCMR_EN | POCMR_PCI2 | POCMR_IO | (POCMR_CM_1M & POCMR_CM_MASK);
246 
247 	/* PCI2 mmio - non-prefetch mem space */
248 	pci_pot[5].potar = (CFG_PCI2_MMIO_BASE >> 12) & POTAR_TA_MASK;
249 	pci_pot[5].pobar = (CFG_PCI2_MMIO_PHYS >> 12) & POBAR_BA_MASK;
250 	pci_pot[5].pocmr = POCMR_EN | POCMR_PCI2 | (POCMR_CM_256M & POCMR_CM_MASK);
251 
252 	/*
253 	 * Configure PCI Inbound Translation Windows
254 	 */
255 
256 	/* we need RAM mapped to PCI space for the devices to
257 	 * access main memory */
258 	pci_ctrl[1].pitar1 = 0x0;
259 	pci_ctrl[1].pibar1 = 0x0;
260 	pci_ctrl[1].piebar1 = 0x0;
261 	pci_ctrl[1].piwar1 = PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1);
262 
263 	hose->first_busno = pci_hose[0].last_busno + 1;
264 	hose->last_busno = 0xff;
265 
266 	/* PCI memory prefetch space */
267 	pci_set_region(hose->regions + 0,
268 		       CFG_PCI2_MEM_BASE,
269 		       CFG_PCI2_MEM_PHYS,
270 		       CFG_PCI2_MEM_SIZE,
271 		       PCI_REGION_MEM|PCI_REGION_PREFETCH);
272 
273 	/* PCI memory space */
274 	pci_set_region(hose->regions + 1,
275 		       CFG_PCI2_MMIO_BASE,
276 		       CFG_PCI2_MMIO_PHYS,
277 		       CFG_PCI2_MMIO_SIZE,
278 		       PCI_REGION_MEM);
279 
280 	/* PCI IO space */
281 	pci_set_region(hose->regions + 2,
282 		       CFG_PCI2_IO_BASE,
283 		       CFG_PCI2_IO_PHYS,
284 		       CFG_PCI2_IO_SIZE,
285 		       PCI_REGION_IO);
286 
287 	/* System memory space */
288 	pci_set_region(hose->regions + 3,
289 		       CONFIG_PCI_SYS_MEM_BUS,
290 		       CONFIG_PCI_SYS_MEM_PHYS,
291 		       gd->ram_size,
292 		       PCI_REGION_MEM | PCI_REGION_MEMORY);
293 
294 	hose->region_count = 4;
295 
296 	pci_setup_indirect(hose,
297 			   (CFG_IMMR+0x8380),
298 			   (CFG_IMMR+0x8384));
299 
300 	pci_register_hose(hose);
301 
302 	/*
303 	 * Write to Command register
304 	 */
305 	reg16 = 0xff;
306 	dev = PCI_BDF(hose->first_busno, 0, 0);
307 	pci_hose_read_config_word (hose, dev, PCI_COMMAND, &reg16);
308 	reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
309 	pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
310 
311 	/*
312 	 * Clear non-reserved bits in status register.
313 	 */
314 	pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
315 	pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
316 	pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
317 
318 	/*
319 	 * Hose scan.
320 	 */
321 	hose->last_busno = pci_hose_scan(hose);
322 #endif
323 
324 }
325 
326 #ifdef CONFIG_OF_FLAT_TREE
327 void
328 ft_pci_setup(void *blob, bd_t *bd)
329 {
330 		u32 *p;
331 		int len;
332 
333 		p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8500/bus-range", &len);
334 		if (p != NULL) {
335 			p[0] = pci_hose[0].first_busno;
336 			p[1] = pci_hose[0].last_busno;
337 		}
338 
339 #ifdef CONFIG_MPC83XX_PCI2
340 	p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8600/bus-range", &len);
341 	if (p != NULL) {
342 		p[0] = pci_hose[1].first_busno;
343 		p[1] = pci_hose[1].last_busno;
344 	}
345 #endif
346 }
347 #endif /* CONFIG_OF_FLAT_TREE */
348 #endif /* CONFIG_PCI */
349