From: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
To: linux-pci@vger.kernel.org, "Bjorn Helgaas" <bhelgaas@google.com>,
"Lorenzo Pieralisi" <lorenzo.pieralisi@arm.com>,
"Rob Herring" <robh@kernel.org>,
"Krzysztof Wilczyński" <kw@linux.com>,
linux-kernel@vger.kernel.org
Cc: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
Subject: [PATCH 02/10] PCI: Add helpers to calculate PCI Conf Type 0/1 addresses
Date: Mon, 29 Apr 2024 13:46:25 +0300 [thread overview]
Message-ID: <20240429104633.11060-3-ilpo.jarvinen@linux.intel.com> (raw)
In-Reply-To: <20240429104633.11060-1-ilpo.jarvinen@linux.intel.com>
Many places in arch and PCI controller code need to calculate PCI
Configuration Space Addresses for Type 0/1 accesses. There are small
variations between archs when it comes to bits outside of [10:2] (Type
0) and [24:2] (Type 1) but the basic calculation can still be
generalized.
drivers/pci/pci.h has PCI_CONF1{,_EXT}_ADDRESS() but due to their
location the use is limited to PCI subsys and the also always enable
PCI_CONF1_ENABLE which is not what all the callers want.
Add generic pci_conf{0,1}_addr() and pci_conf1_ext_addr() helpers into
include/linux/pci.h which can be reused by various parts of the kernel
that have to calculate PCI Conf Type 0/1 addresses.
The PCI_CONF* defines are needed by the new helpers so move also them
to include/linux/pci.h. The new helpers use true bitmasks and
FIELD_PREP() instead of open coded masking and shifting so adjust
PCI_CONF* definitions to match that.
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
---
drivers/pci/pci.h | 43 ++---------------------
include/linux/pci.h | 85 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 88 insertions(+), 40 deletions(-)
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 17fed1846847..cf0530a60105 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -833,49 +833,12 @@ struct pci_devres {
struct pci_devres *find_pci_dr(struct pci_dev *pdev);
-/*
- * Config Address for PCI Configuration Mechanism #1
- *
- * See PCI Local Bus Specification, Revision 3.0,
- * Section 3.2.2.3.2, Figure 3-2, p. 50.
- */
-
-#define PCI_CONF1_BUS_SHIFT 16 /* Bus number */
-#define PCI_CONF1_DEV_SHIFT 11 /* Device number */
-#define PCI_CONF1_FUNC_SHIFT 8 /* Function number */
-
-#define PCI_CONF1_BUS_MASK 0xff
-#define PCI_CONF1_DEV_MASK 0x1f
-#define PCI_CONF1_FUNC_MASK 0x7
-#define PCI_CONF1_REG_MASK 0xfc /* Limit aligned offset to a maximum of 256B */
-
-#define PCI_CONF1_ENABLE BIT(31)
-#define PCI_CONF1_BUS(x) (((x) & PCI_CONF1_BUS_MASK) << PCI_CONF1_BUS_SHIFT)
-#define PCI_CONF1_DEV(x) (((x) & PCI_CONF1_DEV_MASK) << PCI_CONF1_DEV_SHIFT)
-#define PCI_CONF1_FUNC(x) (((x) & PCI_CONF1_FUNC_MASK) << PCI_CONF1_FUNC_SHIFT)
-#define PCI_CONF1_REG(x) ((x) & PCI_CONF1_REG_MASK)
-
#define PCI_CONF1_ADDRESS(bus, dev, func, reg) \
(PCI_CONF1_ENABLE | \
- PCI_CONF1_BUS(bus) | \
- PCI_CONF1_DEV(dev) | \
- PCI_CONF1_FUNC(func) | \
- PCI_CONF1_REG(reg))
-
-/*
- * Extension of PCI Config Address for accessing extended PCIe registers
- *
- * No standardized specification, but used on lot of non-ECAM-compliant ARM SoCs
- * or on AMD Barcelona and new CPUs. Reserved bits [27:24] of PCI Config Address
- * are used for specifying additional 4 high bits of PCI Express register.
- */
-
-#define PCI_CONF1_EXT_REG_SHIFT 16
-#define PCI_CONF1_EXT_REG_MASK 0xf00
-#define PCI_CONF1_EXT_REG(x) (((x) & PCI_CONF1_EXT_REG_MASK) << PCI_CONF1_EXT_REG_SHIFT)
+ pci_conf1_addr(bus, PCI_DEVFN(dev, func), reg & ~0x3U))
#define PCI_CONF1_EXT_ADDRESS(bus, dev, func, reg) \
- (PCI_CONF1_ADDRESS(bus, dev, func, reg) | \
- PCI_CONF1_EXT_REG(reg))
+ (PCI_CONF1_ENABLE | \
+ pci_conf1_ext_addr(bus, PCI_DEVFN(dev, func), reg & ~0x3U))
#endif /* DRIVERS_PCI_H */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 16493426a04f..4c4e3bb52a0a 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -26,6 +26,8 @@
#include <linux/args.h>
#include <linux/mod_devicetable.h>
+#include <linux/bits.h>
+#include <linux/bitfield.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/ioport.h>
@@ -1183,6 +1185,89 @@ void pci_sort_breadthfirst(void);
#define dev_is_pci(d) ((d)->bus == &pci_bus_type)
#define dev_is_pf(d) ((dev_is_pci(d) ? to_pci_dev(d)->is_physfn : false))
+/*
+ * Config Address for PCI Configuration Mechanism #0/1
+ *
+ * See PCI Local Bus Specification, Revision 3.0,
+ * Section 3.2.2.3.2, Figure 3-1 and 3-2, p. 48-50.
+ */
+#define PCI_CONF_REG 0x000000ffU /* common for Type 0/1 */
+#define PCI_CONF_FUNC 0x00000700U /* common for Type 0/1 */
+#define PCI_CONF1_DEV 0x0000f800U
+#define PCI_CONF1_BUS 0x00ff0000U
+#define PCI_CONF1_ENABLE BIT(31)
+
+/**
+ * pci_conf0_addr - PCI Base Configuration Space address for Type 0 access
+ * @devfn: Device and function numbers (device number will be ignored)
+ * @reg: Base configuration space offset
+ *
+ * Calculates the PCI Configuration Space address for Type 0 accesses.
+ *
+ * Note: the caller is responsible for adding the bits outside of [10:0].
+ *
+ * Return: Base Configuration Space address.
+ */
+static inline u32 pci_conf0_addr(u8 devfn, u8 reg)
+{
+ return FIELD_PREP(PCI_CONF_FUNC, PCI_FUNC(devfn)) |
+ FIELD_PREP(PCI_CONF_REG, reg & ~3);
+}
+
+/**
+ * pci_conf1_addr - PCI Base Configuration Space address for Type 1 access
+ * @bus: Bus number of the device
+ * @devfn: Device and function numbers
+ * @reg: Base configuration space offset
+ * @enable: Assert enable bit (bit 31)
+ *
+ * Calculates the PCI Base Configuration Space (first 256 bytes) address for
+ * Type 1 accesses.
+ *
+ * Note: the caller is responsible for adding the bits outside of [24:2]
+ * and enable bit.
+ *
+ * Return: PCI Base Configuration Space address.
+ */
+static inline u32 pci_conf1_addr(u8 bus, u8 devfn, u8 reg, bool enable)
+{
+ return (enable ? PCI_CONF1_ENABLE : 0) |
+ FIELD_PREP(PCI_CONF1_BUS, bus) |
+ FIELD_PREP(PCI_CONF1_DEV | PCI_CONF_FUNC, devfn) |
+ FIELD_PREP(PCI_CONF_REG, reg & ~3);
+}
+
+/*
+ * Extension of PCI Config Address for accessing extended PCIe registers
+ *
+ * No standardized specification, but used on lot of non-ECAM-compliant ARM SoCs
+ * or on AMD Barcelona and new CPUs. Reserved bits [27:24] of PCI Config Address
+ * are used for specifying additional 4 high bits of PCI Express register.
+ */
+#define PCI_CONF1_EXT_REG 0x0f000000UL
+
+/**
+ * pci_conf1_ext_addr - PCI Configuration Space address for Type 1 access
+ * @bus: Bus number of the device
+ * @devfn: Device and function numbers
+ * @reg: Base or Extended Configuration space offset
+ * @enable: Assert enable bit (bit 31)
+ *
+ * Calculates the PCI Base and Extended (4096 bytes per PCI function)
+ * Configuration Space address for Type 1 accesses. This function assumes
+ * the Extended Conguration Space is using the reserved bits [27:24].
+ *
+ * Note: the caller is responsible for adding the bits outside of [27:2] and
+ * enable bit.
+ *
+ * Return: PCI Configuration Space address.
+ */
+static inline u32 pci_conf1_ext_addr(u8 bus, u8 devfn, u16 reg, bool enable)
+{
+ return FIELD_PREP(PCI_CONF1_EXT_REG, (reg & 0xf00) >> 8) |
+ pci_conf1_addr(bus, devfn, reg & 0xff, enable);
+}
+
/* Generic PCI functions exported to card drivers */
u8 pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap);
--
2.39.2
next prev parent reply other threads:[~2024-04-29 10:47 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-29 10:46 [PATCH 00/10] PCI: Add generic Conf Type 0/1 helpers Ilpo Järvinen
2024-04-29 10:46 ` [PATCH 01/10] ARM: orion5x: Rename PCI_CONF_{REG,FUNC}() out of the way Ilpo Järvinen
2024-04-29 14:08 ` Andrew Lunn
2024-04-29 14:38 ` Andrew Lunn
2024-04-29 14:51 ` Ilpo Järvinen
2024-05-05 16:38 ` Gregory CLEMENT
2024-04-29 10:46 ` Ilpo Järvinen [this message]
2024-04-29 19:24 ` [PATCH 02/10] PCI: Add helpers to calculate PCI Conf Type 0/1 addresses Pali Rohár
2024-04-30 10:21 ` Ilpo Järvinen
2024-04-30 18:43 ` Pali Rohár
2024-04-29 10:46 ` [PATCH 03/10] ARM: orion5x: Pass devfn to orion5x_pci_hw_{rd,wr}_conf() Ilpo Järvinen
2024-04-29 14:11 ` Andrew Lunn
2024-05-05 16:38 ` Gregory CLEMENT
2024-04-29 10:46 ` [PATCH 04/10] ARM: orion5x: Use generic PCI Conf Type 1 helper Ilpo Järvinen
2024-05-05 16:39 ` Gregory CLEMENT
2024-04-29 10:46 ` [PATCH 05/10] PCI: ixp4xx: Use generic PCI Conf Type 0 helper Ilpo Järvinen
2024-05-03 8:42 ` Linus Walleij
2024-04-29 10:46 ` [PATCH 06/10] PCI: ixp4xx: Replace 1 with PCI_CONF1_TRANSACTION Ilpo Järvinen
2024-05-03 8:43 ` Linus Walleij
2024-04-29 10:46 ` [PATCH 07/10] PCI: Replace PCI_CONF1{,_EXT}_ADDRESS() with the new helpers Ilpo Järvinen
2024-05-03 8:43 ` Linus Walleij
2024-05-03 9:42 ` Sergio Paracuellos
2024-04-29 10:46 ` [PATCH 08/10] PCI: tegra: Use generic PCI Conf Type 1 helper Ilpo Järvinen
2024-04-29 10:46 ` [PATCH 09/10] PCI: mvebu: " Ilpo Järvinen
2024-04-29 19:31 ` Pali Rohár
2024-04-29 19:45 ` Andrew Lunn
2024-04-29 10:46 ` [PATCH 10/10] PCI: v3: Use generic PCI Conf Type 0/1 helpers Ilpo Järvinen
2024-05-03 8:44 ` Linus Walleij
2024-04-29 18:23 ` [PATCH 00/10] PCI: Add generic " Pali Rohár
2024-04-30 11:18 ` Ilpo Järvinen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240429104633.11060-3-ilpo.jarvinen@linux.intel.com \
--to=ilpo.jarvinen@linux.intel.com \
--cc=bhelgaas@google.com \
--cc=kw@linux.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lorenzo.pieralisi@arm.com \
--cc=robh@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox