blob: 680deb9d35a277f1e71978c269ad2f8e19aebff4 [file] [log] [blame]
Angel Pons32859fc2020-04-02 23:48:27 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +02002
Eric Biederman5899fd82003-04-24 06:25:08 +00003#ifndef PCI_OPS_H
4#define PCI_OPS_H
5
6#include <stdint.h>
Eric Biederman7a5416a2003-06-12 19:23:51 +00007#include <device/device.h>
Kyösti Mälkki3e6913b2019-03-02 16:26:10 +02008#include <device/pci_type.h>
Eric Biederman018d8dd2004-11-04 11:04:33 +00009#include <arch/pci_ops.h>
Eric Biederman5899fd82003-04-24 06:25:08 +000010
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020011void __noreturn pcidev_die(void);
12
Kyösti Mälkki34cf5612019-03-11 20:34:26 +020013static __always_inline pci_devfn_t pcidev_bdf(const struct device *dev)
14{
15 return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20);
16}
17
18static __always_inline pci_devfn_t pcidev_assert(const struct device *dev)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020019{
20 if (!dev)
21 pcidev_die();
Kyösti Mälkki34cf5612019-03-11 20:34:26 +020022 return pcidev_bdf(dev);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020023}
Kyösti Mälkki3f98d412019-07-29 16:38:14 +030024
Kyösti Mälkki9d5af5b2019-09-27 12:01:15 +030025#if defined(__SIMPLE_DEVICE__)
26#define ENV_PCI_SIMPLE_DEVICE 1
27#else
28#define ENV_PCI_SIMPLE_DEVICE 0
29#endif
30
31#if ENV_PCI_SIMPLE_DEVICE
Kyösti Mälkki3f98d412019-07-29 16:38:14 +030032
33/* Avoid name collisions as different stages have different signature
34 * for these functions. The _s_ stands for simple, fundamental IO or
35 * MMIO variant.
36 */
37#define pci_read_config8 pci_s_read_config8
38#define pci_read_config16 pci_s_read_config16
39#define pci_read_config32 pci_s_read_config32
40#define pci_write_config8 pci_s_write_config8
41#define pci_write_config16 pci_s_write_config16
42#define pci_write_config32 pci_s_write_config32
43#else
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020044
45static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020046u8 pci_read_config8(const struct device *dev, u16 reg)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020047{
Kyösti Mälkki4663f452019-03-07 14:18:28 +020048 return pci_s_read_config8(PCI_BDF(dev), reg);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020049}
50
51static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020052u16 pci_read_config16(const struct device *dev, u16 reg)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020053{
Kyösti Mälkki4663f452019-03-07 14:18:28 +020054 return pci_s_read_config16(PCI_BDF(dev), reg);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020055}
56
57static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020058u32 pci_read_config32(const struct device *dev, u16 reg)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020059{
Kyösti Mälkki4663f452019-03-07 14:18:28 +020060 return pci_s_read_config32(PCI_BDF(dev), reg);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020061}
62
63static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020064void pci_write_config8(const struct device *dev, u16 reg, u8 val)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020065{
Kyösti Mälkki4663f452019-03-07 14:18:28 +020066 pci_s_write_config8(PCI_BDF(dev), reg, val);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020067}
68
69static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020070void pci_write_config16(const struct device *dev, u16 reg, u16 val)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020071{
Kyösti Mälkki4663f452019-03-07 14:18:28 +020072 pci_s_write_config16(PCI_BDF(dev), reg, val);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020073}
74
75static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020076void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020077{
Kyösti Mälkki4663f452019-03-07 14:18:28 +020078 pci_s_write_config32(PCI_BDF(dev), reg, val);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020079}
80
Stefan Reinauer24d1d4b2013-03-21 11:51:41 -070081#endif
Stefan Reinauer43b29cf2009-03-06 19:11:52 +000082
Kyösti Mälkki9d5af5b2019-09-27 12:01:15 +030083#if ENV_PCI_SIMPLE_DEVICE
Aaron Durbin75a62e72018-09-13 02:10:45 -060084static __always_inline
Angel Ponsaf36b292020-06-07 18:01:56 +020085void pci_and_config8(pci_devfn_t dev, u16 reg, u8 andmask)
86#else
87static __always_inline
88void pci_and_config8(const struct device *dev, u16 reg, u8 andmask)
89#endif
90{
91 u8 value = pci_read_config8(dev, reg);
92 pci_write_config8(dev, reg, value & andmask);
93}
94
95#if ENV_PCI_SIMPLE_DEVICE
96static __always_inline
97void pci_and_config16(pci_devfn_t dev, u16 reg, u16 andmask)
98#else
99static __always_inline
100void pci_and_config16(const struct device *dev, u16 reg, u16 andmask)
101#endif
102{
103 u16 value = pci_read_config16(dev, reg);
104 pci_write_config16(dev, reg, value & andmask);
105}
106
107#if ENV_PCI_SIMPLE_DEVICE
108static __always_inline
109void pci_and_config32(pci_devfn_t dev, u16 reg, u32 andmask)
110#else
111static __always_inline
112void pci_and_config32(const struct device *dev, u16 reg, u32 andmask)
113#endif
114{
115 u32 value = pci_read_config32(dev, reg);
116 pci_write_config32(dev, reg, value & andmask);
117}
118
119#if ENV_PCI_SIMPLE_DEVICE
120static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200121void pci_or_config8(pci_devfn_t dev, u16 reg, u8 ormask)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100122#else
123static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200124void pci_or_config8(const struct device *dev, u16 reg, u8 ormask)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100125#endif
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200126{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200127 u8 value = pci_read_config8(dev, reg);
128 pci_write_config8(dev, reg, value | ormask);
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200129}
130
Kyösti Mälkki9d5af5b2019-09-27 12:01:15 +0300131#if ENV_PCI_SIMPLE_DEVICE
Aaron Durbin75a62e72018-09-13 02:10:45 -0600132static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200133void pci_or_config16(pci_devfn_t dev, u16 reg, u16 ormask)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100134#else
135static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200136void pci_or_config16(const struct device *dev, u16 reg, u16 ormask)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100137#endif
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200138{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200139 u16 value = pci_read_config16(dev, reg);
140 pci_write_config16(dev, reg, value | ormask);
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200141}
142
Kyösti Mälkki9d5af5b2019-09-27 12:01:15 +0300143#if ENV_PCI_SIMPLE_DEVICE
Aaron Durbin75a62e72018-09-13 02:10:45 -0600144static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200145void pci_or_config32(pci_devfn_t dev, u16 reg, u32 ormask)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100146#else
147static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200148void pci_or_config32(const struct device *dev, u16 reg, u32 ormask)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100149#endif
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200150{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200151 u32 value = pci_read_config32(dev, reg);
152 pci_write_config32(dev, reg, value | ormask);
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200153}
154
Kyösti Mälkki9d5af5b2019-09-27 12:01:15 +0300155#if ENV_PCI_SIMPLE_DEVICE
Aaron Durbin75a62e72018-09-13 02:10:45 -0600156static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200157void pci_update_config8(pci_devfn_t dev, u16 reg, u8 mask, u8 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100158#else
159static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200160void pci_update_config8(const struct device *dev, u16 reg, u8 mask, u8 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100161#endif
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200162{
163 u8 reg8;
164
165 reg8 = pci_read_config8(dev, reg);
166 reg8 &= mask;
167 reg8 |= or;
168 pci_write_config8(dev, reg, reg8);
169}
170
Kyösti Mälkki9d5af5b2019-09-27 12:01:15 +0300171#if ENV_PCI_SIMPLE_DEVICE
Aaron Durbin75a62e72018-09-13 02:10:45 -0600172static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200173void pci_update_config16(pci_devfn_t dev, u16 reg, u16 mask, u16 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100174#else
175static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200176void pci_update_config16(const struct device *dev, u16 reg, u16 mask, u16 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100177#endif
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200178{
179 u16 reg16;
180
181 reg16 = pci_read_config16(dev, reg);
182 reg16 &= mask;
183 reg16 |= or;
184 pci_write_config16(dev, reg, reg16);
185}
186
Kyösti Mälkki9d5af5b2019-09-27 12:01:15 +0300187#if ENV_PCI_SIMPLE_DEVICE
Aaron Durbin75a62e72018-09-13 02:10:45 -0600188static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200189void pci_update_config32(pci_devfn_t dev, u16 reg, u32 mask, u32 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100190#else
191static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200192void pci_update_config32(const struct device *dev, u16 reg, u32 mask, u32 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100193#endif
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200194{
195 u32 reg32;
196
197 reg32 = pci_read_config32(dev, reg);
198 reg32 &= mask;
199 reg32 |= or;
200 pci_write_config32(dev, reg, reg32);
201}
202
Kyösti Mälkki9c0e14e2019-01-23 16:46:35 +0200203u16 pci_s_find_next_capability(pci_devfn_t dev, u16 cap, u16 last);
204u16 pci_s_find_capability(pci_devfn_t dev, u16 cap);
205
Kyösti Mälkki9c0e14e2019-01-23 16:46:35 +0200206static __always_inline
207u16 pci_find_next_capability(const struct device *dev, u16 cap, u16 last)
208{
209 return pci_s_find_next_capability(PCI_BDF(dev), cap, last);
210}
211
212static __always_inline
213u16 pci_find_capability(const struct device *dev, u16 cap)
214{
215 return pci_s_find_capability(PCI_BDF(dev), cap);
216}
Kyösti Mälkki9c0e14e2019-01-23 16:46:35 +0200217
Eric Biederman5899fd82003-04-24 06:25:08 +0000218#endif /* PCI_OPS_H */