xref: /rk3399_rockchip-uboot/board/sbc8349/pci.c (revision b3458d2cd55d01732e30a76d898afd99e871cd67)
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 #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
39 
40 DECLARE_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
49 static 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 
61 static 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  */
81 void
82 pci_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 
332 #if defined(CONFIG_OF_LIBFDT)
333 void 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)
368 void
369 ft_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 */
390