]>
Commit | Line | Data |
---|---|---|
affae2bf WD |
1 | /* |
2 | * Support for indirect PCI bridges. | |
3 | * | |
4 | * Copyright (C) 1998 Gabriel Paubert. | |
5 | * | |
1a459660 | 6 | * SPDX-License-Identifier: GPL-2.0+ |
affae2bf WD |
7 | */ |
8 | ||
9 | #include <common.h> | |
10 | ||
29161f47 | 11 | #if !defined(__I386__) |
affae2bf WD |
12 | |
13 | #include <asm/processor.h> | |
14 | #include <asm/io.h> | |
15 | #include <pci.h> | |
16 | ||
17 | #define cfg_read(val, addr, type, op) *val = op((type)(addr)) | |
18 | #define cfg_write(val, addr, type, op) op((type *)(addr), (val)) | |
19 | ||
2eb48ff7 | 20 | #if defined(CONFIG_E500) || defined(CONFIG_MPC86xx) |
42d1f039 WD |
21 | #define INDIRECT_PCI_OP(rw, size, type, op, mask) \ |
22 | static int \ | |
23 | indirect_##rw##_config_##size(struct pci_controller *hose, \ | |
24 | pci_dev_t dev, int offset, type val) \ | |
25 | { \ | |
dffb70f3 KG |
26 | u32 b, d,f; \ |
27 | b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev); \ | |
28 | b = b - hose->first_busno; \ | |
29 | dev = PCI_BDF(b, d, f); \ | |
571f49fa | 30 | *(hose->cfg_addr) = dev | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000; \ |
42d1f039 WD |
31 | sync(); \ |
32 | cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \ | |
33 | return 0; \ | |
34 | } | |
4d75a504 WD |
35 | #else |
36 | #define INDIRECT_PCI_OP(rw, size, type, op, mask) \ | |
37 | static int \ | |
53677ef1 | 38 | indirect_##rw##_config_##size(struct pci_controller *hose, \ |
4d75a504 WD |
39 | pci_dev_t dev, int offset, type val) \ |
40 | { \ | |
dffb70f3 KG |
41 | u32 b, d,f; \ |
42 | b = PCI_BUS(dev); d = PCI_DEV(dev); f = PCI_FUNC(dev); \ | |
43 | b = b - hose->first_busno; \ | |
44 | dev = PCI_BDF(b, d, f); \ | |
53677ef1 | 45 | out_le32(hose->cfg_addr, dev | (offset & 0xfc) | 0x80000000); \ |
4d75a504 | 46 | cfg_##rw(val, hose->cfg_data + (offset & mask), type, op); \ |
53677ef1 | 47 | return 0; \ |
4d75a504 WD |
48 | } |
49 | #endif | |
affae2bf | 50 | |
affae2bf WD |
51 | INDIRECT_PCI_OP(read, byte, u8 *, in_8, 3) |
52 | INDIRECT_PCI_OP(read, word, u16 *, in_le16, 2) | |
53 | INDIRECT_PCI_OP(read, dword, u32 *, in_le32, 0) | |
affae2bf WD |
54 | INDIRECT_PCI_OP(write, byte, u8, out_8, 3) |
55 | INDIRECT_PCI_OP(write, word, u16, out_le16, 2) | |
56 | INDIRECT_PCI_OP(write, dword, u32, out_le32, 0) | |
affae2bf WD |
57 | |
58 | void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data) | |
59 | { | |
60 | pci_set_ops(hose, | |
61 | indirect_read_config_byte, | |
62 | indirect_read_config_word, | |
63 | indirect_read_config_dword, | |
64 | indirect_write_config_byte, | |
65 | indirect_write_config_word, | |
66 | indirect_write_config_dword); | |
67 | ||
68 | hose->cfg_addr = (unsigned int *) cfg_addr; | |
69 | hose->cfg_data = (unsigned char *) cfg_data; | |
70 | } | |
71 | ||
29161f47 | 72 | #endif /* !__I386__ */ |