blob: bb77754cb615346e012150e52a0100871103298d [file] [log] [blame]
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2004 Linux Networx
5 * (Written by Eric Biederman <ebiederman@lnxi.com> for Linux Networx)
6 * Copyright (C) 2009 coresystems GmbH
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
Eric Biederman5899fd82003-04-24 06:25:08 +000018#ifndef PCI_OPS_H
19#define PCI_OPS_H
20
21#include <stdint.h>
Eric Biederman7a5416a2003-06-12 19:23:51 +000022#include <device/device.h>
Kyösti Mälkki3e6913b2019-03-02 16:26:10 +020023#include <device/pci_type.h>
Eric Biederman018d8dd2004-11-04 11:04:33 +000024#include <arch/pci_ops.h>
Eric Biederman5899fd82003-04-24 06:25:08 +000025
Kyösti Mälkki92b52962019-03-01 08:08:28 +020026#ifdef __SIMPLE_DEVICE__
27
28/* Avoid name collisions as different stages have different signature
29 * for these functions. The _s_ stands for simple, fundamental IO or
30 * MMIO variant.
31 */
32#define pci_read_config8 pci_s_read_config8
33#define pci_read_config16 pci_s_read_config16
34#define pci_read_config32 pci_s_read_config32
35#define pci_write_config8 pci_s_write_config8
36#define pci_write_config16 pci_s_write_config16
37#define pci_write_config32 pci_s_write_config32
38#else
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020039
40#include <device/pci.h>
41
Kyösti Mälkki78d14322019-01-23 15:57:49 +020042const struct pci_bus_operations *pci_bus_default_ops(void);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020043
44static __always_inline const struct pci_bus_operations *pci_bus_ops(void)
45{
46 return pci_bus_default_ops();
47}
48
49void __noreturn pcidev_die(void);
50
Kyösti Mälkki34cf5612019-03-11 20:34:26 +020051static __always_inline pci_devfn_t pcidev_bdf(const struct device *dev)
52{
53 return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20);
54}
55
56static __always_inline pci_devfn_t pcidev_assert(const struct device *dev)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020057{
58 if (!dev)
59 pcidev_die();
Kyösti Mälkki34cf5612019-03-11 20:34:26 +020060 return pcidev_bdf(dev);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020061}
62
63static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020064u8 pci_read_config8(const struct device *dev, u16 reg)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020065{
Kyösti Mälkki34cf5612019-03-11 20:34:26 +020066 pci_devfn_t bdf = PCI_BDF(dev);
67 return pci_bus_ops()->read8(bdf, reg);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020068}
69
70static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020071u16 pci_read_config16(const struct device *dev, u16 reg)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020072{
Kyösti Mälkki34cf5612019-03-11 20:34:26 +020073 pci_devfn_t bdf = PCI_BDF(dev);
74 return pci_bus_ops()->read16(bdf, reg);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020075}
76
77static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020078u32 pci_read_config32(const struct device *dev, u16 reg)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020079{
Kyösti Mälkki34cf5612019-03-11 20:34:26 +020080 pci_devfn_t bdf = PCI_BDF(dev);
81 return pci_bus_ops()->read32(bdf, reg);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020082}
83
84static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020085void pci_write_config8(const struct device *dev, u16 reg, u8 val)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020086{
Kyösti Mälkki34cf5612019-03-11 20:34:26 +020087 pci_devfn_t bdf = PCI_BDF(dev);
88 pci_bus_ops()->write8(bdf, reg, val);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020089}
90
91static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020092void pci_write_config16(const struct device *dev, u16 reg, u16 val)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020093{
Kyösti Mälkki34cf5612019-03-11 20:34:26 +020094 pci_devfn_t bdf = PCI_BDF(dev);
95 pci_bus_ops()->write16(bdf, reg, val);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +020096}
97
98static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +020099void pci_write_config32(const struct device *dev, u16 reg, u32 val)
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +0200100{
Kyösti Mälkki34cf5612019-03-11 20:34:26 +0200101 pci_devfn_t bdf = PCI_BDF(dev);
102 pci_bus_ops()->write32(bdf, reg, val);
Kyösti Mälkkie079e5c2019-01-23 16:15:48 +0200103}
104
Stefan Reinauer24d1d4b2013-03-21 11:51:41 -0700105#endif
Stefan Reinauer43b29cf2009-03-06 19:11:52 +0000106
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100107#ifdef __SIMPLE_DEVICE__
Aaron Durbin75a62e72018-09-13 02:10:45 -0600108static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200109void pci_or_config8(pci_devfn_t dev, u16 reg, u8 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_config8(const struct device *dev, u16 reg, u8 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 u8 value = pci_read_config8(dev, reg);
116 pci_write_config8(dev, reg, value | ormask);
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200117}
118
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100119#ifdef __SIMPLE_DEVICE__
Aaron Durbin75a62e72018-09-13 02:10:45 -0600120static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200121void pci_or_config16(pci_devfn_t dev, u16 reg, u16 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_config16(const struct device *dev, u16 reg, u16 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 u16 value = pci_read_config16(dev, reg);
128 pci_write_config16(dev, reg, value | ormask);
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200129}
130
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100131#ifdef __SIMPLE_DEVICE__
Aaron Durbin75a62e72018-09-13 02:10:45 -0600132static __always_inline
Kyösti Mälkkib603fdc2019-03-11 20:33:01 +0200133void pci_or_config32(pci_devfn_t dev, u16 reg, u32 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_config32(const struct device *dev, u16 reg, u32 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 u32 value = pci_read_config32(dev, reg);
140 pci_write_config32(dev, reg, value | ormask);
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200141}
142
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100143#ifdef __SIMPLE_DEVICE__
Aaron Durbin75a62e72018-09-13 02:10:45 -0600144static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200145void pci_update_config8(pci_devfn_t dev, u16 reg, u8 mask, u8 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100146#else
147static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200148void pci_update_config8(const struct device *dev, u16 reg, u8 mask, u8 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100149#endif
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200150{
151 u8 reg8;
152
153 reg8 = pci_read_config8(dev, reg);
154 reg8 &= mask;
155 reg8 |= or;
156 pci_write_config8(dev, reg, reg8);
157}
158
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100159#ifdef __SIMPLE_DEVICE__
Aaron Durbin75a62e72018-09-13 02:10:45 -0600160static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200161void pci_update_config16(pci_devfn_t dev, u16 reg, u16 mask, u16 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100162#else
163static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200164void pci_update_config16(const struct device *dev, u16 reg, u16 mask, u16 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100165#endif
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200166{
167 u16 reg16;
168
169 reg16 = pci_read_config16(dev, reg);
170 reg16 &= mask;
171 reg16 |= or;
172 pci_write_config16(dev, reg, reg16);
173}
174
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100175#ifdef __SIMPLE_DEVICE__
Aaron Durbin75a62e72018-09-13 02:10:45 -0600176static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200177void pci_update_config32(pci_devfn_t dev, u16 reg, u32 mask, u32 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100178#else
179static __always_inline
Kyösti Mälkki55172462019-03-07 11:13:29 +0200180void pci_update_config32(const struct device *dev, u16 reg, u32 mask, u32 or)
Elyes HAOUASf9e47cc2018-12-05 11:03:36 +0100181#endif
Patrick Rudolphe56189c2018-04-18 10:11:59 +0200182{
183 u32 reg32;
184
185 reg32 = pci_read_config32(dev, reg);
186 reg32 &= mask;
187 reg32 |= or;
188 pci_write_config32(dev, reg, reg32);
189}
190
Eric Biederman5899fd82003-04-24 06:25:08 +0000191#endif /* PCI_OPS_H */