1 /*
2  * Copyright (C) 2006 Freescale Semiconductor, Inc.
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  */
12 
13 /*
14  * PCI Configuration space access support for MPC83xx PCI Bridge
15  */
16 #include <asm/mmu.h>
17 #include <asm/io.h>
18 #include <common.h>
19 #include <pci.h>
20 #include <i2c.h>
21 #if defined(CONFIG_OF_LIBFDT)
22 #include <libfdt.h>
23 #include <fdt_support.h>
24 #endif
25 
26 #include <asm/fsl_i2c.h>
27 
28 DECLARE_GLOBAL_DATA_PTR;
29 
30 #if defined(CONFIG_PCI)
31 #define PCI_FUNCTION_CONFIG   0x44
32 #define PCI_FUNCTION_CFG_LOCK 0x20
33 
34 /*
35  * Initialize PCI Devices, report devices found
36  */
37 #ifndef CONFIG_PCI_PNP
38 static struct pci_config_table pci_mpc83xxemds_config_table[] = {
39 	{
40 		PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
41 		pci_cfgfunc_config_device,
42 		{PCI_ENET0_IOADDR,
43 		PCI_ENET0_MEMADDR,
44 		PCI_COMMON_MEMORY | PCI_COMMAND_MASTER}
45 	},
46 	{}
47 }
48 #endif
49 static struct pci_controller hose[] = {
50 	{
51 #ifndef CONFIG_PCI_PNP
52 		config_table:pci_mpc83xxemds_config_table,
53 #endif
54 	},
55 };
56 
57 /**********************************************************************
58  * pci_init_board()
59  *********************************************************************/
60 void pci_init_board(void)
61 #ifdef CONFIG_PCISLAVE
62 {
63 	u16 reg16;
64 	volatile immap_t *immr;
65 	volatile law83xx_t *pci_law;
66 	volatile pot83xx_t *pci_pot;
67 	volatile pcictrl83xx_t *pci_ctrl;
68 	volatile pciconf83xx_t *pci_conf;
69 
70 	immr = (immap_t *) CONFIG_SYS_IMMR;
71 	pci_law = immr->sysconf.pcilaw;
72 	pci_pot = immr->ios.pot;
73 	pci_ctrl = immr->pci_ctrl;
74 	pci_conf = immr->pci_conf;
75 	/*
76 	 * Configure PCI Inbound Translation Windows
77 	 */
78 	pci_ctrl[0].pitar0 = 0x0;
79 	pci_ctrl[0].pibar0 = 0x0;
80 	pci_ctrl[0].piwar0 = PIWAR_EN | PIWAR_RTT_SNOOP |
81 	    PIWAR_WTT_SNOOP | PIWAR_IWS_4K;
82 
83 	pci_ctrl[0].pitar1 = 0x0;
84 	pci_ctrl[0].pibar1 = 0x0;
85 	pci_ctrl[0].piebar1 = 0x0;
86 	pci_ctrl[0].piwar1 &= ~PIWAR_EN;
87 
88 	pci_ctrl[0].pitar2 = 0x0;
89 	pci_ctrl[0].pibar2 = 0x0;
90 	pci_ctrl[0].piebar2 = 0x0;
91 	pci_ctrl[0].piwar2 &= ~PIWAR_EN;
92 
93 	hose[0].first_busno = 0;
94 	hose[0].last_busno = 0xff;
95 	pci_setup_indirect(&hose[0],
96 			   (CONFIG_SYS_IMMR + 0x8300), (CONFIG_SYS_IMMR + 0x8304));
97 	reg16 = 0xff;
98 
99 	pci_hose_read_config_word(&hose[0], PCI_BDF(0, 0, 0),
100 				  PCI_COMMAND, &reg16);
101 	reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MEMORY;
102 	pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
103 				   PCI_COMMAND, reg16);
104 
105 	/*
106 	 * Clear non-reserved bits in status register.
107 	 */
108 	pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
109 				   PCI_STATUS, 0xffff);
110 	pci_hose_write_config_byte(&hose[0], PCI_BDF(0, 0, 0),
111 				   PCI_LATENCY_TIMER, 0x80);
112 
113 	/*
114 	 * Unlock configuration lock in PCI function configuration register.
115 	 */
116 	pci_hose_read_config_word(&hose[0], PCI_BDF(0, 0, 0),
117 				  PCI_FUNCTION_CONFIG, &reg16);
118 	reg16 &= ~(PCI_FUNCTION_CFG_LOCK);
119 	pci_hose_write_config_word(&hose[0], PCI_BDF(0, 0, 0),
120 				   PCI_FUNCTION_CONFIG, reg16);
121 
122 	printf("Enabled PCI 32bit Agent Mode\n");
123 }
124 #else
125 {
126 	volatile immap_t *immr;
127 	volatile clk83xx_t *clk;
128 	volatile law83xx_t *pci_law;
129 	volatile pot83xx_t *pci_pot;
130 	volatile pcictrl83xx_t *pci_ctrl;
131 	volatile pciconf83xx_t *pci_conf;
132 
133 	u16 reg16;
134 	u32 val32;
135 	u32 dev;
136 
137 	immr = (immap_t *) CONFIG_SYS_IMMR;
138 	clk = (clk83xx_t *) & immr->clk;
139 	pci_law = immr->sysconf.pcilaw;
140 	pci_pot = immr->ios.pot;
141 	pci_ctrl = immr->pci_ctrl;
142 	pci_conf = immr->pci_conf;
143 	/*
144 	 * Configure PCI controller and PCI_CLK_OUTPUT both in 66M mode
145 	 */
146 	val32 = clk->occr;
147 	udelay(2000);
148 #if defined(PCI_66M)
149 	clk->occr = OCCR_PCICOE0 | OCCR_PCICOE1 | OCCR_PCICOE2;
150 	printf("PCI clock is 66MHz\n");
151 #elif defined(PCI_33M)
152 	clk->occr = OCCR_PCICOE0 | OCCR_PCICOE1 | OCCR_PCICOE2 |
153 	    OCCR_PCICD0 | OCCR_PCICD1 | OCCR_PCICD2 | OCCR_PCICR;
154 	printf("PCI clock is 33MHz\n");
155 #else
156 	clk->occr = OCCR_PCICOE0 | OCCR_PCICOE1 | OCCR_PCICOE2;
157 	printf("PCI clock is 66MHz\n");
158 #endif
159 	udelay(2000);
160 
161 	/*
162 	 * Configure PCI Local Access Windows
163 	 */
164 	pci_law[0].bar = CONFIG_SYS_PCI_MEM_PHYS & LAWBAR_BAR;
165 	pci_law[0].ar = LAWAR_EN | LAWAR_SIZE_512M;
166 
167 	pci_law[1].bar = CONFIG_SYS_PCI_IO_PHYS & LAWBAR_BAR;
168 	pci_law[1].ar = LAWAR_EN | LAWAR_SIZE_1M;
169 
170 	/*
171 	 * Configure PCI Outbound Translation Windows
172 	 */
173 
174 	/* PCI mem space - prefetch */
175 	pci_pot[0].potar = (CONFIG_SYS_PCI_MEM_BASE >> 12) & POTAR_TA_MASK;
176 	pci_pot[0].pobar = (CONFIG_SYS_PCI_MEM_PHYS >> 12) & POBAR_BA_MASK;
177 	pci_pot[0].pocmr =
178 	    POCMR_EN | POCMR_SE | (POCMR_CM_256M & POCMR_CM_MASK);
179 
180 	/* PCI mmio - non-prefetch mem space */
181 	pci_pot[1].potar = (CONFIG_SYS_PCI_MMIO_BASE >> 12) & POTAR_TA_MASK;
182 	pci_pot[1].pobar = (CONFIG_SYS_PCI_MMIO_PHYS >> 12) & POBAR_BA_MASK;
183 	pci_pot[1].pocmr = POCMR_EN | (POCMR_CM_256M & POCMR_CM_MASK);
184 
185 	/* PCI IO space */
186 	pci_pot[2].potar = (CONFIG_SYS_PCI_IO_BASE >> 12) & POTAR_TA_MASK;
187 	pci_pot[2].pobar = (CONFIG_SYS_PCI_IO_PHYS >> 12) & POBAR_BA_MASK;
188 	pci_pot[2].pocmr = POCMR_EN | POCMR_IO | (POCMR_CM_1M & POCMR_CM_MASK);
189 
190 	/*
191 	 * Configure PCI Inbound Translation Windows
192 	 */
193 	pci_ctrl[0].pitar1 = (CONFIG_SYS_PCI_SLV_MEM_LOCAL >> 12) & PITAR_TA_MASK;
194 	pci_ctrl[0].pibar1 = (CONFIG_SYS_PCI_SLV_MEM_BUS >> 12) & PIBAR_MASK;
195 	pci_ctrl[0].piebar1 = 0x0;
196 	pci_ctrl[0].piwar1 =
197 	    PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP | PIWAR_WTT_SNOOP |
198 	    PIWAR_IWS_2G;
199 
200 	/*
201 	 * Release PCI RST Output signal
202 	 */
203 	udelay(2000);
204 	pci_ctrl[0].gcr = 1;
205 	udelay(2000);
206 
207 	hose[0].first_busno = 0;
208 	hose[0].last_busno = 0xff;
209 
210 	/* PCI memory prefetch space */
211 	pci_set_region(hose[0].regions + 0,
212 		       CONFIG_SYS_PCI_MEM_BASE,
213 		       CONFIG_SYS_PCI_MEM_PHYS,
214 		       CONFIG_SYS_PCI_MEM_SIZE, PCI_REGION_MEM | PCI_REGION_PREFETCH);
215 
216 	/* PCI memory space */
217 	pci_set_region(hose[0].regions + 1,
218 		       CONFIG_SYS_PCI_MMIO_BASE,
219 		       CONFIG_SYS_PCI_MMIO_PHYS, CONFIG_SYS_PCI_MMIO_SIZE, PCI_REGION_MEM);
220 
221 	/* PCI IO space */
222 	pci_set_region(hose[0].regions + 2,
223 		       CONFIG_SYS_PCI_IO_BASE,
224 		       CONFIG_SYS_PCI_IO_PHYS, CONFIG_SYS_PCI_IO_SIZE, PCI_REGION_IO);
225 
226 	/* System memory space */
227 	pci_set_region(hose[0].regions + 3,
228 		       CONFIG_SYS_PCI_SLV_MEM_LOCAL,
229 		       CONFIG_SYS_PCI_SLV_MEM_BUS,
230 		       CONFIG_SYS_PCI_SLV_MEM_SIZE,
231 		       PCI_REGION_MEM | PCI_REGION_MEMORY);
232 
233 	hose[0].region_count = 4;
234 
235 	pci_setup_indirect(&hose[0],
236 			   (CONFIG_SYS_IMMR + 0x8300), (CONFIG_SYS_IMMR + 0x8304));
237 
238 	pci_register_hose(hose);
239 
240 	/*
241 	 * Write command register
242 	 */
243 	reg16 = 0xff;
244 	dev = PCI_BDF(0, 0, 0);
245 	pci_hose_read_config_word(&hose[0], dev, PCI_COMMAND, &reg16);
246 	reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
247 	pci_hose_write_config_word(&hose[0], dev, PCI_COMMAND, reg16);
248 
249 	/*
250 	 * Clear non-reserved bits in status register.
251 	 */
252 	pci_hose_write_config_word(&hose[0], dev, PCI_STATUS, 0xffff);
253 	pci_hose_write_config_byte(&hose[0], dev, PCI_LATENCY_TIMER, 0x80);
254 	pci_hose_write_config_byte(&hose[0], dev, PCI_CACHE_LINE_SIZE, 0x08);
255 
256 	/*
257 	 * Hose scan.
258 	 */
259 	hose->last_busno = pci_hose_scan(hose);
260 }
261 #endif				/* CONFIG_PCISLAVE */
262 
263 #if defined(CONFIG_OF_LIBFDT)
264 void ft_pci_setup(void *blob, bd_t *bd)
265 {
266 	int nodeoffset;
267 	int tmp[2];
268 	const char *path;
269 
270 	nodeoffset = fdt_path_offset(blob, "/aliases");
271 	if (nodeoffset >= 0) {
272 		path = fdt_getprop(blob, nodeoffset, "pci0", NULL);
273 		if (path) {
274 			tmp[0] = cpu_to_be32(hose[0].first_busno);
275 			tmp[1] = cpu_to_be32(hose[0].last_busno);
276 			do_fixup_by_path(blob, path, "bus-range",
277 				&tmp, sizeof(tmp), 1);
278 
279 			tmp[0] = cpu_to_be32(gd->pci_clk);
280 			do_fixup_by_path(blob, path, "clock-frequency",
281 				&tmp, sizeof(tmp[0]), 1);
282 		}
283 	}
284 }
285 #endif				/* CONFIG_OF_LIBFDT */
286 #endif				/* CONFIG_PCI */
287