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