pci: Add helper for implementing memory-mapped config space accesses

This sort of pattern for implementing memory-mapped PCI config space
accesses appears in U-Boot twice already, and a third user is coming up.
So add helper functions to avoid code duplication, similar to how Linux
has pci_generic_config_write and pci_generic_config_read.

Signed-off-by: Tuomas Tynkkynen <tuomas.tynkkynen@iki.fi>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 86df141..5a24eb6 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -518,6 +518,64 @@
 	return sub_bus;
 }
 
+int pci_generic_mmap_write_config(
+	struct udevice *bus,
+	int (*addr_f)(struct udevice *bus, pci_dev_t bdf, uint offset, void **addrp),
+	pci_dev_t bdf,
+	uint offset,
+	ulong value,
+	enum pci_size_t size)
+{
+	void *address;
+
+	if (addr_f(bus, bdf, offset, &address) < 0)
+		return 0;
+
+	switch (size) {
+	case PCI_SIZE_8:
+		writeb(value, address);
+		return 0;
+	case PCI_SIZE_16:
+		writew(value, address);
+		return 0;
+	case PCI_SIZE_32:
+		writel(value, address);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
+int pci_generic_mmap_read_config(
+	struct udevice *bus,
+	int (*addr_f)(struct udevice *bus, pci_dev_t bdf, uint offset, void **addrp),
+	pci_dev_t bdf,
+	uint offset,
+	ulong *valuep,
+	enum pci_size_t size)
+{
+	void *address;
+
+	if (addr_f(bus, bdf, offset, &address) < 0) {
+		*valuep = pci_get_ff(size);
+		return 0;
+	}
+
+	switch (size) {
+	case PCI_SIZE_8:
+		*valuep = readb(address);
+		return 0;
+	case PCI_SIZE_16:
+		*valuep = readw(address);
+		return 0;
+	case PCI_SIZE_32:
+		*valuep = readl(address);
+		return 0;
+	default:
+		return -EINVAL;
+	}
+}
+
 int dm_pci_hose_probe_bus(struct udevice *bus)
 {
 	int sub_bus;