]> git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/pci/pci_ixp.c
Add GPL-2.0+ SPDX-License-Identifier to source files
[people/ms/u-boot.git] / drivers / pci / pci_ixp.c
1 /*
2 * IXP PCI Init
3 *
4 * (C) Copyright 2011
5 * Michael Schwingen, michael@schwingen.org
6 * (C) Copyright 2004 eslab.whut.edu.cn
7 * Yue Hu(huyue_whut@yahoo.com.cn), Ligong Xue(lgxue@hotmail.com)
8 *
9 * SPDX-License-Identifier: GPL-2.0+
10 */
11
12 #include <common.h>
13 #include <asm/processor.h>
14 #include <asm/io.h>
15 #include <pci.h>
16 #include <asm/arch/ixp425.h>
17 #include <asm/arch/ixp425pci.h>
18
19 DECLARE_GLOBAL_DATA_PTR;
20
21 static void non_prefetch_read(unsigned int addr, unsigned int cmd,
22 unsigned int *data);
23 static void non_prefetch_write(unsigned int addr, unsigned int cmd,
24 unsigned int data);
25
26 /*define the sub vendor and subsystem to be used */
27 #define IXP425_PCI_SUB_VENDOR_SYSTEM 0x00000000
28
29 #define PCI_MEMORY_BUS 0x00000000
30 #define PCI_MEMORY_PHY 0x00000000
31 #define PCI_MEMORY_SIZE 0x04000000
32
33 #define PCI_MEM_BUS 0x48000000
34 #define PCI_MEM_PHY 0x00000000
35 #define PCI_MEM_SIZE 0x04000000
36
37 #define PCI_IO_BUS 0x00000000
38 #define PCI_IO_PHY 0x00000000
39 #define PCI_IO_SIZE 0x00010000
40
41 /* build address value for config sycle */
42 static unsigned int pci_config_addr(pci_dev_t bdf, unsigned int reg)
43 {
44 unsigned int bus = PCI_BUS(bdf);
45 unsigned int dev = PCI_DEV(bdf);
46 unsigned int func = PCI_FUNC(bdf);
47 unsigned int addr;
48
49 if (bus) { /* secondary bus, use type 1 config cycle */
50 addr = bdf | (reg & ~3) | 1;
51 } else {
52 /*
53 primary bus, type 0 config cycle. address bits 31:28
54 specify the device 10:8 specify the function
55 */
56 addr = BIT((31 - dev)) | (func << 8) | (reg & ~3);
57 }
58
59 return addr;
60 }
61
62 static int pci_config_status(void)
63 {
64 unsigned int regval;
65
66 regval = readl(PCI_CSR_BASE + PCI_ISR_OFFSET);
67 if ((regval & PCI_ISR_PFE) == 0)
68 return OK;
69
70 /* no device present, make sure that the master abort bit is reset */
71 writel(PCI_ISR_PFE, PCI_CSR_BASE + PCI_ISR_OFFSET);
72 return ERROR;
73 }
74
75 static int pci_ixp_hose_read_config_dword(struct pci_controller *hose,
76 pci_dev_t bdf, int where, unsigned int *val)
77 {
78 unsigned int retval;
79 unsigned int addr;
80 int stat;
81
82 debug("pci_ixp_hose_read_config_dword: bdf %x, reg %x", bdf, where);
83 /*Set the address to be read */
84 addr = pci_config_addr(bdf, where);
85 non_prefetch_read(addr, NP_CMD_CONFIGREAD, &retval);
86 *val = retval;
87
88 stat = pci_config_status();
89 if (stat < 0)
90 *val = -1;
91 debug("-> val %x, status %x\n", *val, stat);
92 return stat;
93 }
94
95 static int pci_ixp_hose_read_config_word(struct pci_controller *hose,
96 pci_dev_t bdf, int where, unsigned short *val)
97 {
98 unsigned int n;
99 unsigned int retval;
100 unsigned int addr;
101 unsigned int byteEnables;
102 int stat;
103
104 debug("pci_ixp_hose_read_config_word: bdf %x, reg %x", bdf, where);
105 n = where % 4;
106 /*byte enables are 4 bits active low, the position of each
107 bit maps to the byte that it enables */
108 byteEnables =
109 (~(BIT(n) | BIT((n + 1)))) &
110 IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
111 byteEnables = byteEnables << PCI_NP_CBE_BESL;
112 /*Set the address to be read */
113 addr = pci_config_addr(bdf, where);
114 non_prefetch_read(addr, byteEnables | NP_CMD_CONFIGREAD, &retval);
115
116 /*Pick out the word we are interested in */
117 *val = retval >> (8 * n);
118
119 stat = pci_config_status();
120 if (stat < 0)
121 *val = -1;
122 debug("-> val %x, status %x\n", *val, stat);
123 return stat;
124 }
125
126 static int pci_ixp_hose_read_config_byte(struct pci_controller *hose,
127 pci_dev_t bdf, int where, unsigned char *val)
128 {
129 unsigned int retval;
130 unsigned int n;
131 unsigned int byteEnables;
132 unsigned int addr;
133 int stat;
134
135 debug("pci_ixp_hose_read_config_byte: bdf %x, reg %x", bdf, where);
136 n = where % 4;
137 /*byte enables are 4 bits, active low, the position of each
138 bit maps to the byte that it enables */
139 byteEnables = (~BIT(n)) & IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
140 byteEnables = byteEnables << PCI_NP_CBE_BESL;
141
142 /*Set the address to be read */
143 addr = pci_config_addr(bdf, where);
144 non_prefetch_read(addr, byteEnables | NP_CMD_CONFIGREAD, &retval);
145 /*Pick out the byte we are interested in */
146 *val = retval >> (8 * n);
147
148 stat = pci_config_status();
149 if (stat < 0)
150 *val = -1;
151 debug("-> val %x, status %x\n", *val, stat);
152 return stat;
153 }
154
155 static int pci_ixp_hose_write_config_byte(struct pci_controller *hose,
156 pci_dev_t bdf, int where, unsigned char val)
157 {
158 unsigned int addr;
159 unsigned int byteEnables;
160 unsigned int n;
161 unsigned int ldata;
162 int stat;
163
164 debug("pci_ixp_hose_write_config_byte: bdf %x, reg %x, val %x",
165 bdf, where, val);
166 n = where % 4;
167 /*byte enables are 4 bits active low, the position of each
168 bit maps to the byte that it enables */
169 byteEnables = (~BIT(n)) & IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
170 byteEnables = byteEnables << PCI_NP_CBE_BESL;
171 ldata = val << (8 * n);
172 /*Set the address to be written */
173 addr = pci_config_addr(bdf, where);
174 non_prefetch_write(addr, byteEnables | NP_CMD_CONFIGWRITE, ldata);
175
176 stat = pci_config_status();
177 debug("-> status %x\n", stat);
178 return stat;
179 }
180
181 static int pci_ixp_hose_write_config_word(struct pci_controller *hose,
182 pci_dev_t bdf, int where, unsigned short val)
183 {
184 unsigned int addr;
185 unsigned int byteEnables;
186 unsigned int n;
187 unsigned int ldata;
188 int stat;
189
190 debug("pci_ixp_hose_write_config_word: bdf %x, reg %x, val %x",
191 bdf, where, val);
192 n = where % 4;
193 /*byte enables are 4 bits active low, the position of each
194 bit maps to the byte that it enables */
195 byteEnables =
196 (~(BIT(n) | BIT((n + 1)))) &
197 IXP425_PCI_BOTTOM_NIBBLE_OF_LONG_MASK;
198 byteEnables = byteEnables << PCI_NP_CBE_BESL;
199 ldata = val << (8 * n);
200 /*Set the address to be written */
201 addr = pci_config_addr(bdf, where);
202 non_prefetch_write(addr, byteEnables | NP_CMD_CONFIGWRITE, ldata);
203
204 stat = pci_config_status();
205 debug("-> status %x\n", stat);
206 return stat;
207 }
208
209 static int pci_ixp_hose_write_config_dword(struct pci_controller *hose,
210 pci_dev_t bdf, int where, unsigned int val)
211 {
212 unsigned int addr;
213 int stat;
214
215 debug("pci_ixp_hose_write_config_dword: bdf %x, reg %x, val %x",
216 bdf, where, val);
217 /*Set the address to be written */
218 addr = pci_config_addr(bdf, where);
219 non_prefetch_write(addr, NP_CMD_CONFIGWRITE, val);
220
221 stat = pci_config_status();
222 debug("-> status %x\n", stat);
223 return stat;
224 }
225
226 static void non_prefetch_read(unsigned int addr,
227 unsigned int cmd, unsigned int *data)
228 {
229 writel(addr, PCI_CSR_BASE + PCI_NP_AD_OFFSET);
230
231 /*set up and execute the read */
232 writel(cmd, PCI_CSR_BASE + PCI_NP_CBE_OFFSET);
233
234 /*The result of the read is now in np_rdata */
235 *data = readl(PCI_CSR_BASE + PCI_NP_RDATA_OFFSET);
236
237 return;
238 }
239
240 static void non_prefetch_write(unsigned int addr,
241 unsigned int cmd, unsigned int data)
242 {
243
244 writel(addr, PCI_CSR_BASE + PCI_NP_AD_OFFSET);
245 /*set up the write */
246 writel(cmd, PCI_CSR_BASE + PCI_NP_CBE_OFFSET);
247 /*Execute the write by writing to NP_WDATA */
248 writel(data, PCI_CSR_BASE + PCI_NP_WDATA_OFFSET);
249
250 return;
251 }
252
253 static void crp_write(unsigned int offset, unsigned int data)
254 {
255 /*
256 * The CRP address register bit 16 indicates that we want to do a
257 * write
258 */
259 writel(PCI_CRP_WRITE | offset, PCI_CSR_BASE + PCI_CRP_AD_CBE_OFFSET);
260 writel(data, PCI_CSR_BASE + PCI_CRP_WDATA_OFFSET);
261 }
262
263 void pci_ixp_init(struct pci_controller *hose)
264 {
265 unsigned int csr;
266
267 /*
268 * Specify that the AHB bus is operating in big endian mode. Set up
269 * byte lane swapping between little-endian PCI and the big-endian
270 * AHB bus
271 */
272 #ifdef __ARMEB__
273 csr = PCI_CSR_ABE | PCI_CSR_PDS | PCI_CSR_ADS;
274 #else
275 csr = PCI_CSR_ABE;
276 #endif
277 writel(csr, PCI_CSR_BASE + PCI_CSR_OFFSET);
278
279 writel(0, PCI_CSR_BASE + PCI_INTEN_OFFSET);
280
281 /*
282 * We configure the PCI inbound memory windows to be
283 * 1:1 mapped to SDRAM
284 */
285 crp_write(PCI_CFG_BASE_ADDRESS_0, 0x00000000);
286 crp_write(PCI_CFG_BASE_ADDRESS_1, 0x01000000);
287 crp_write(PCI_CFG_BASE_ADDRESS_2, 0x02000000);
288 crp_write(PCI_CFG_BASE_ADDRESS_3, 0x03000000);
289
290 /*
291 * Enable CSR window at 64 MiB to allow PCI masters
292 * to continue prefetching past 64 MiB boundary.
293 */
294 crp_write(PCI_CFG_BASE_ADDRESS_4, 0x04000000);
295 /*
296 * Enable the IO window to be way up high, at 0xfffffc00
297 */
298 crp_write(PCI_CFG_BASE_ADDRESS_5, 0xfffffc01);
299
300 /*Setup PCI-AHB and AHB-PCI address mappings */
301 writel(0x00010203, PCI_CSR_BASE + PCI_AHBMEMBASE_OFFSET);
302
303 writel(0x00000000, PCI_CSR_BASE + PCI_AHBIOBASE_OFFSET);
304
305 writel(0x48494a4b, PCI_CSR_BASE + PCI_PCIMEMBASE_OFFSET);
306
307 crp_write(PCI_CFG_SUB_VENDOR_ID, IXP425_PCI_SUB_VENDOR_SYSTEM);
308
309 crp_write(PCI_CFG_COMMAND, PCI_CFG_CMD_MAE | PCI_CFG_CMD_BME);
310 udelay(1000);
311
312 /* clear error bits in status register */
313 writel(PCI_ISR_PSE | PCI_ISR_PFE | PCI_ISR_PPE | PCI_ISR_AHBE,
314 PCI_CSR_BASE + PCI_ISR_OFFSET);
315
316 /*
317 * Set Initialize Complete in PCI Control Register: allow IXP4XX to
318 * respond to PCI configuration cycles.
319 */
320 csr |= PCI_CSR_IC;
321 writel(csr, PCI_CSR_BASE + PCI_CSR_OFFSET);
322
323 hose->first_busno = 0;
324 hose->last_busno = 0;
325
326 /* System memory space */
327 pci_set_region(hose->regions + 0,
328 PCI_MEMORY_BUS,
329 PCI_MEMORY_PHY, PCI_MEMORY_SIZE, PCI_REGION_SYS_MEMORY);
330
331 /* PCI memory space */
332 pci_set_region(hose->regions + 1,
333 PCI_MEM_BUS,
334 PCI_MEM_PHY, PCI_MEM_SIZE, PCI_REGION_MEM);
335 /* PCI I/O space */
336 pci_set_region(hose->regions + 2,
337 PCI_IO_BUS, PCI_IO_PHY, PCI_IO_SIZE, PCI_REGION_IO);
338
339 hose->region_count = 3;
340
341 pci_set_ops(hose,
342 pci_ixp_hose_read_config_byte,
343 pci_ixp_hose_read_config_word,
344 pci_ixp_hose_read_config_dword,
345 pci_ixp_hose_write_config_byte,
346 pci_ixp_hose_write_config_word,
347 pci_ixp_hose_write_config_dword);
348
349 pci_register_hose(hose);
350 hose->last_busno = pci_hose_scan(hose);
351 }