Linux PCI subsystem development
 help / color / mirror / Atom feed
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


  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