blob: 3757d3073b58538ee4be15addc78870d20b8fa24 [file] [log] [blame]
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +02001/*
2 * This file is part of the coreboot project.
3 *
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +02004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
Eric Biederman5899fd82003-04-24 06:25:08 +000015#ifndef PCI_OPS_H
16#define PCI_OPS_H
17
18#include <stdint.h>
Eric Biederman7a5416a2003-06-12 19:23:51 +000019#include <device/device.h>
Kyösti Mälkki3e6913b2019-03-02 16:26:10 +020020#include <device/pci_type.h>
Eric Biederman018d8dd2004-11-04 11:04:33 +000021#include <arch/pci_ops.h>
Eric Biederman5899fd82003-04-24 06:25:08 +000022
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020023void __noreturn pcidev_die(void);
24
Kyösti Mälkki34cf5612019-03-11 20:34:26 +020025static __always_inline pci_devfn_t pcidev_bdf(const struct device *dev)
26{
27 return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20);
28}
29
30static __always_inline pci_devfn_t pcidev_assert(const struct device *dev)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020031{
32 if (!dev)
33 pcidev_die();
Kyösti Mälkki34cf5612019-03-11 20:34:26 +020034 return pcidev_bdf(dev);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020035}
Kyösti Mälkki3f98d412019-07-29 16:38:14 +030036
Kyösti Mälkki9d5af5b2019-09-27 12:01:15 +030037#if defined(__SIMPLE_DEVICE__)
38#define ENV_PCI_SIMPLE_DEVICE 1
39#else
40#define ENV_PCI_SIMPLE_DEVICE 0
41#endif
42
43#if ENV_PCI_SIMPLE_DEVICE
Kyösti Mälkki3f98d412019-07-29 16:38:14 +030044
45/* Avoid name collisions as different stages have different signature
46 * for these functions. The _s_ stands for simple, fundamental IO or
47 * MMIO variant.
48 */
49#define pci_read_config8 pci_s_read_config8
50#define pci_read_config16 pci_s_read_config16
51#define pci_read_config32 pci_s_read_config32
52#define pci_write_config8 pci_s_write_config8
53#define pci_write_config16 pci_s_write_config16
54#define pci_write_config32 pci_s_write_config32
55#else
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020056
57static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020058u8 pci_read_config8(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_config8(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 +020064u16 pci_read_config16(const struct device *dev, u16 reg)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020065{
Kyösti Mälkki4663f452019-03-07 14:18:28 +020066 return pci_s_read_config16(PCI_BDF(dev), reg);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020067}
68
69static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020070u32 pci_read_config32(const struct device *dev, u16 reg)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020071{
Kyösti Mälkki4663f452019-03-07 14:18:28 +020072 return pci_s_read_config32(PCI_BDF(dev), reg);
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_config8(const struct device *dev, u16 reg, u8 val)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020077{
Kyösti Mälkki4663f452019-03-07 14:18:28 +020078 pci_s_write_config8(PCI_BDF(dev), reg, val);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020079}
80
81static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020082void pci_write_config16(const struct device *dev, u16 reg, u16 val)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020083{
Kyösti Mälkki4663f452019-03-07 14:18:28 +020084 pci_s_write_config16(PCI_BDF(dev), reg, val);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020085}
86
87static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020088void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020089{
Kyösti Mälkki4663f452019-03-07 14:18:28 +020090 pci_s_write_config32(PCI_BDF(dev), reg, val);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020091}
92
Stefan Reinauer24d1d4b2013-03-21 11:51:41 -070093#endif
Stefan Reinauer43b29cf2009-03-06 19:11:52 +000094
Kyösti Mälkki9d5af5b2019-09-27 12:01:15 +030095#if ENV_PCI_SIMPLE_DEVICE
Aaron Durbin75a62e72018-09-13 02:10:45 -060096static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020097void pci_or_config8(pci_devfn_t dev, u16 reg, u8 ormask)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +010098#else
99static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200100void pci_or_config8(const struct device *dev, u16 reg, u8 ormask)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100101#endif
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200102{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200103 u8 value = pci_read_config8(dev, reg);
104 pci_write_config8(dev, reg, value | ormask);
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200105}
106
Kyösti Mälkki9d5af5b2019-09-27 12:01:15 +0300107#if ENV_PCI_SIMPLE_DEVICE
Aaron Durbin75a62e72018-09-13 02:10:45 -0600108static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200109void pci_or_config16(pci_devfn_t dev, u16 reg, u16 ormask)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100110#else
111static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200112void pci_or_config16(const struct device *dev, u16 reg, u16 ormask)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100113#endif
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200114{
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200115 u16 value = pci_read_config16(dev, reg);
116 pci_write_config16(dev, reg, value | ormask);
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200117}
118
Kyösti Mälkki9d5af5b2019-09-27 12:01:15 +0300119#if ENV_PCI_SIMPLE_DEVICE
Aaron Durbin75a62e72018-09-13 02:10:45 -0600120static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200121void pci_or_config32(pci_devfn_t dev, u16 reg, u32 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_config32(const struct device *dev, u16 reg, u32 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 u32 value = pci_read_config32(dev, reg);
128 pci_write_config32(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älkki55172462019-03-07 11:13:29 +0200133void pci_update_config8(pci_devfn_t dev, u16 reg, u8 mask, u8 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100134#else
135static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200136void pci_update_config8(const struct device *dev, u16 reg, u8 mask, u8 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100137#endif
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200138{
139 u8 reg8;
140
141 reg8 = pci_read_config8(dev, reg);
142 reg8 &= mask;
143 reg8 |= or;
144 pci_write_config8(dev, reg, reg8);
145}
146
Kyösti Mälkki9d5af5b2019-09-27 12:01:15 +0300147#if ENV_PCI_SIMPLE_DEVICE
Aaron Durbin75a62e72018-09-13 02:10:45 -0600148static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200149void pci_update_config16(pci_devfn_t dev, u16 reg, u16 mask, u16 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100150#else
151static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200152void pci_update_config16(const struct device *dev, u16 reg, u16 mask, u16 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100153#endif
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200154{
155 u16 reg16;
156
157 reg16 = pci_read_config16(dev, reg);
158 reg16 &= mask;
159 reg16 |= or;
160 pci_write_config16(dev, reg, reg16);
161}
162
Kyösti Mälkki9d5af5b2019-09-27 12:01:15 +0300163#if ENV_PCI_SIMPLE_DEVICE
Aaron Durbin75a62e72018-09-13 02:10:45 -0600164static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200165void pci_update_config32(pci_devfn_t dev, u16 reg, u32 mask, u32 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100166#else
167static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200168void pci_update_config32(const struct device *dev, u16 reg, u32 mask, u32 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100169#endif
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200170{
171 u32 reg32;
172
173 reg32 = pci_read_config32(dev, reg);
174 reg32 &= mask;
175 reg32 |= or;
176 pci_write_config32(dev, reg, reg32);
177}
178
Kyösti Mälkki9c0e14e2019-01-23 16:46:35 +0200179u16 pci_s_find_next_capability(pci_devfn_t dev, u16 cap, u16 last);
180u16 pci_s_find_capability(pci_devfn_t dev, u16 cap);
181
Kyösti Mälkki9c0e14e2019-01-23 16:46:35 +0200182static __always_inline
183u16 pci_find_next_capability(const struct device *dev, u16 cap, u16 last)
184{
185 return pci_s_find_next_capability(PCI_BDF(dev), cap, last);
186}
187
188static __always_inline
189u16 pci_find_capability(const struct device *dev, u16 cap)
190{
191 return pci_s_find_capability(PCI_BDF(dev), cap);
192}
Kyösti Mälkki9c0e14e2019-01-23 16:46:35 +0200193
Eric Biederman5899fd82003-04-24 06:25:08 +0000194#endif /* PCI_OPS_H */