• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 /*
4  * Derived from Cavium's BSD-3 Clause OCTEONTX-SDK-6.2.0.
5  */
6 
7 #define __SIMPLE_DEVICE__
8 
9 #include <device/pci_ops.h>
10 #include <device/pci.h>
11 #include <soc/addressmap.h>
12 #include <soc/ecam.h>
13 
14 /**
15  * Get PCI BAR address from cavium specific extended capability.
16  * Use regular BAR if not found in extended capability space.
17  *
18  * @return The physical address of the BAR, zero on error
19  */
ecam0_get_bar_val(pci_devfn_t dev,u8 bar)20 uint64_t ecam0_get_bar_val(pci_devfn_t dev, u8 bar)
21 {
22 	size_t cap_offset = pci_s_find_capability(dev, 0x14);
23 	uint64_t h, l, ret = 0;
24 	if (cap_offset) {
25 		/* Found EA */
26 		u8 es, bei;
27 		u8 ne = pci_read_config8(dev, cap_offset + 2) & 0x3f;
28 
29 		cap_offset += 4;
30 		while (ne) {
31 			uint32_t dw0 = pci_read_config32(dev, cap_offset);
32 
33 			es = dw0 & 7;
34 			bei = (dw0 >> 4) & 0xf;
35 			if (bei == bar) {
36 				h = 0;
37 				l = pci_read_config32(dev, cap_offset + 4);
38 				if (l & 2)
39 					h = pci_read_config32(dev,
40 							      cap_offset + 12);
41 				ret = (h << 32) | (l & ~0xfull);
42 				break;
43 			}
44 			cap_offset += (es + 1) * 4;
45 			ne--;
46 		}
47 	} else {
48 		h = 0;
49 		l = pci_read_config32(dev, bar * 4 + PCI_BASE_ADDRESS_0);
50 		if (l & 4)
51 			h = pci_read_config32(dev, bar * 4 + PCI_BASE_ADDRESS_0
52 					      + 4);
53 		ret = (h << 32) | (l & ~0xfull);
54 	}
55 	return ret;
56 }
57