pci_ops.h
1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 3 #ifndef PCI_OPS_H 4 #define PCI_OPS_H 5 6 #include <stdint.h> 7 #include <device/device.h> 8 #include <device/pci_type.h> 9 #include <arch/pci_ops.h> /* IWYU pragma: export */ 10 11 void __noreturn pcidev_die(void); 12 13 static __always_inline pci_devfn_t pcidev_bdf(const struct device *dev) 14 { 15 return (dev->path.pci.devfn << 12) | (dev->upstream->secondary << 20) | 16 (dev->upstream->segment_group << 28); 17 } 18 19 static __always_inline pci_devfn_t pcidev_assert(const struct device *dev) 20 { 21 if (!dev) 22 pcidev_die(); 23 return pcidev_bdf(dev); 24 } 25 26 #if defined(__SIMPLE_DEVICE__) 27 #define ENV_PCI_SIMPLE_DEVICE 1 28 #else 29 #define ENV_PCI_SIMPLE_DEVICE 0 30 #endif 31 32 #if ENV_PCI_SIMPLE_DEVICE 33 34 /* Avoid name collisions as different stages have different signature 35 * for these functions. The _s_ stands for simple, fundamental IO or 36 * MMIO variant. 37 */ 38 #define pci_read_config8 pci_s_read_config8 39 #define pci_read_config16 pci_s_read_config16 40 #define pci_read_config32 pci_s_read_config32 41 #define pci_write_config8 pci_s_write_config8 42 #define pci_write_config16 pci_s_write_config16 43 #define pci_write_config32 pci_s_write_config32 44 #else 45 46 static __always_inline 47 u8 pci_read_config8(const struct device *dev, u16 reg) 48 { 49 return pci_s_read_config8(PCI_BDF(dev), reg); 50 } 51 52 static __always_inline 53 u16 pci_read_config16(const struct device *dev, u16 reg) 54 { 55 return pci_s_read_config16(PCI_BDF(dev), reg); 56 } 57 58 static __always_inline 59 u32 pci_read_config32(const struct device *dev, u16 reg) 60 { 61 return pci_s_read_config32(PCI_BDF(dev), reg); 62 } 63 64 static __always_inline 65 void pci_write_config8(const struct device *dev, u16 reg, u8 val) 66 { 67 pci_s_write_config8(PCI_BDF(dev), reg, val); 68 } 69 70 static __always_inline 71 void pci_write_config16(const struct device *dev, u16 reg, u16 val) 72 { 73 pci_s_write_config16(PCI_BDF(dev), reg, val); 74 } 75 76 static __always_inline 77 void pci_write_config32(const struct device *dev, u16 reg, u32 val) 78 { 79 pci_s_write_config32(PCI_BDF(dev), reg, val); 80 } 81 82 #endif 83 84 #if ENV_PCI_SIMPLE_DEVICE 85 static __always_inline 86 void pci_update_config8(pci_devfn_t dev, u16 reg, u8 mask, u8 or) 87 #else 88 static __always_inline 89 void pci_update_config8(const struct device *dev, u16 reg, u8 mask, u8 or) 90 #endif 91 { 92 u8 reg8; 93 94 reg8 = pci_read_config8(dev, reg); 95 reg8 &= mask; 96 reg8 |= or; 97 pci_write_config8(dev, reg, reg8); 98 } 99 100 #if ENV_PCI_SIMPLE_DEVICE 101 static __always_inline 102 void pci_update_config16(pci_devfn_t dev, u16 reg, u16 mask, u16 or) 103 #else 104 static __always_inline 105 void pci_update_config16(const struct device *dev, u16 reg, u16 mask, u16 or) 106 #endif 107 { 108 u16 reg16; 109 110 reg16 = pci_read_config16(dev, reg); 111 reg16 &= mask; 112 reg16 |= or; 113 pci_write_config16(dev, reg, reg16); 114 } 115 116 #if ENV_PCI_SIMPLE_DEVICE 117 static __always_inline 118 void pci_update_config32(pci_devfn_t dev, u16 reg, u32 mask, u32 or) 119 #else 120 static __always_inline 121 void pci_update_config32(const struct device *dev, u16 reg, u32 mask, u32 or) 122 #endif 123 { 124 u32 reg32; 125 126 reg32 = pci_read_config32(dev, reg); 127 reg32 &= mask; 128 reg32 |= or; 129 pci_write_config32(dev, reg, reg32); 130 } 131 132 #if ENV_PCI_SIMPLE_DEVICE 133 static __always_inline 134 void pci_and_config8(pci_devfn_t dev, u16 reg, u8 andmask) 135 #else 136 static __always_inline 137 void pci_and_config8(const struct device *dev, u16 reg, u8 andmask) 138 #endif 139 { 140 pci_update_config8(dev, reg, andmask, 0); 141 } 142 143 #if ENV_PCI_SIMPLE_DEVICE 144 static __always_inline 145 void pci_and_config16(pci_devfn_t dev, u16 reg, u16 andmask) 146 #else 147 static __always_inline 148 void pci_and_config16(const struct device *dev, u16 reg, u16 andmask) 149 #endif 150 { 151 pci_update_config16(dev, reg, andmask, 0); 152 } 153 154 #if ENV_PCI_SIMPLE_DEVICE 155 static __always_inline 156 void pci_and_config32(pci_devfn_t dev, u16 reg, u32 andmask) 157 #else 158 static __always_inline 159 void pci_and_config32(const struct device *dev, u16 reg, u32 andmask) 160 #endif 161 { 162 pci_update_config32(dev, reg, andmask, 0); 163 } 164 165 #if ENV_PCI_SIMPLE_DEVICE 166 static __always_inline 167 void pci_or_config8(pci_devfn_t dev, u16 reg, u8 ormask) 168 #else 169 static __always_inline 170 void pci_or_config8(const struct device *dev, u16 reg, u8 ormask) 171 #endif 172 { 173 pci_update_config8(dev, reg, 0xff, ormask); 174 } 175 176 #if ENV_PCI_SIMPLE_DEVICE 177 static __always_inline 178 void pci_or_config16(pci_devfn_t dev, u16 reg, u16 ormask) 179 #else 180 static __always_inline 181 void pci_or_config16(const struct device *dev, u16 reg, u16 ormask) 182 #endif 183 { 184 pci_update_config16(dev, reg, 0xffff, ormask); 185 } 186 187 #if ENV_PCI_SIMPLE_DEVICE 188 static __always_inline 189 void pci_or_config32(pci_devfn_t dev, u16 reg, u32 ormask) 190 #else 191 static __always_inline 192 void pci_or_config32(const struct device *dev, u16 reg, u32 ormask) 193 #endif 194 { 195 pci_update_config32(dev, reg, 0xffffffff, ormask); 196 } 197 198 u16 pci_s_find_next_capability(pci_devfn_t dev, u16 cap, u16 last); 199 u16 pci_s_find_capability(pci_devfn_t dev, u16 cap); 200 201 static __always_inline 202 u16 pci_find_next_capability(const struct device *dev, u16 cap, u16 last) 203 { 204 return pci_s_find_next_capability(PCI_BDF(dev), cap, last); 205 } 206 207 static __always_inline 208 u16 pci_find_capability(const struct device *dev, u16 cap) 209 { 210 return pci_s_find_capability(PCI_BDF(dev), cap); 211 } 212 213 /* 214 * Determine if the given PCI device is the source of wake from sleep by checking PME_STATUS and 215 * PME_ENABLE bits in PM control and status register. 216 * 217 * Returns true if PCI device is wake source, false otherwise. 218 */ 219 bool pci_dev_is_wake_source(pci_devfn_t dev); 220 221 #endif /* PCI_OPS_H */