/ src / include / device / pci_ops.h
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 */