Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1376314 > unrolled thread
| Started by | Jayachandran C <jchandra@broadcom.com> |
|---|---|
| First post | 2016-04-12 00:50 +0200 |
| Last post | 2016-04-12 00:50 +0200 |
| Articles | 11 — 4 participants |
Back to article view | Back to linux.kernel
[PATCH v2 0/4] ACPI based PCI host driver with generic ECAM Jayachandran C <jchandra@broadcom.com> - 2016-04-12 00:50 +0200
[PATCH v2 2/4] PCI: Provide common functions for ECAM mapping Jayachandran C <jchandra@broadcom.com> - 2016-04-12 00:50 +0200
Re: [PATCH v2 2/4] PCI: Provide common functions for ECAM mapping Jon Masters <jcm@jonmasters.org> - 2016-04-12 06:30 +0200
Re: [PATCH v2 2/4] PCI: Provide common functions for ECAM mapping Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-04-12 18:50 +0200
Re: [PATCH v2 2/4] PCI: Provide common functions for ECAM mapping Jon Masters <jcm@jonmasters.org> - 2016-04-14 08:30 +0200
Re: [PATCH v2 2/4] PCI: Provide common functions for ECAM mapping Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> - 2016-04-14 12:10 +0200
Re: [PATCH v2 2/4] PCI: Provide common functions for ECAM mapping Jayachandran C <jchandra@broadcom.com> - 2016-04-14 17:50 +0200
[PATCH v2 4/4] ACPI: PCI: Add generic PCI host controller Jayachandran C <jchandra@broadcom.com> - 2016-04-12 00:50 +0200
Re: [PATCH v2 4/4] ACPI: PCI: Add generic PCI host controller Sinan Kaya <okaya@codeaurora.org> - 2016-04-14 18:00 +0200
Re: [PATCH v2 4/4] ACPI: PCI: Add generic PCI host controller Sinan Kaya <okaya@codeaurora.org> - 2016-04-14 18:00 +0200
[PATCH v2 1/4] arm64: Prepare to use generic ACPI PCI implementation Jayachandran C <jchandra@broadcom.com> - 2016-04-12 00:50 +0200
| From | Jayachandran C <jchandra@broadcom.com> |
|---|---|
| Date | 2016-04-12 00:50 +0200 |
| Subject | [PATCH v2 0/4] ACPI based PCI host driver with generic ECAM |
| Message-ID | <rmSOC-4W8-3@gated-at.bofh.it> |
Here is v2 of the patchset for the ACPI PCI controller driver based on the earlier discussion[1]. This patchset unifies the pci-host-generic ECAM code and the ACPI PCI ECAM code much further so that both the implementations can use the same structure (struct pci_config_window) as ->sysdata. The patchset should also make it easier to share platform quirks between DT and ACPI PCI controller drivers using struct pci_generic_ecam_ops. Short description of the patches in the patchset: - fixup arm64 PCI code so that it can use the generic ACPI PCI driver. - implement pci/drivers/ecam.[ch] which will replace drivers/pci/host/pci-host-common.h API for ECAM access and will be shared by ACPI and DT. - Update users of the pci-host-common API to the ecam API - implement a simple PCI ACPI host. I have not used the pci_mmcfg_list or the region definitions from x86, but have used a much simpler approach here. This should apply cleanly on top of the current 4.6 tree or the pci next tree, and can be reviewed as a patchset. The full set of changes for arm64 includes other fixes, that series is available at https://github.com/jchandra-brcm/linux branch arm64-acpi-pci-v2 This has been tested on qemu with OVMF for the ACPI part and with device tree for pci-host-generic code. Further testing and reviews are welcome. Thanks, JC. [1] https://lkml.org/lkml/2016/3/3/921 Jayachandran C (4): arm64: Prepare to use generic ACPI PCI implementation PCI: Provide common functions for ECAM mapping PCI: generic, thunder: update to use generic ECAM API ACPI: PCI: Add generic PCI host controller arch/arm64/Kconfig | 3 + arch/arm64/kernel/pci.c | 7 +- drivers/acpi/Kconfig | 9 ++ drivers/acpi/Makefile | 1 + drivers/acpi/pci_gen_host.c | 258 ++++++++++++++++++++++++++++++++++++ drivers/pci/Kconfig | 3 + drivers/pci/Makefile | 2 + drivers/pci/ecam.c | 130 ++++++++++++++++++ drivers/pci/ecam.h | 63 +++++++++ drivers/pci/host/Kconfig | 1 + drivers/pci/host/pci-host-common.c | 121 ++++++++--------- drivers/pci/host/pci-host-common.h | 47 ------- drivers/pci/host/pci-host-generic.c | 50 ++----- drivers/pci/host/pci-thunder-ecam.c | 37 +----- drivers/pci/host/pci-thunder-pem.c | 53 +++----- 15 files changed, 560 insertions(+), 225 deletions(-) create mode 100644 drivers/acpi/pci_gen_host.c create mode 100644 drivers/pci/ecam.c create mode 100644 drivers/pci/ecam.h delete mode 100644 drivers/pci/host/pci-host-common.h -- 1.9.1
[toc] | [next] | [standalone]
| From | Jayachandran C <jchandra@broadcom.com> |
|---|---|
| Date | 2016-04-12 00:50 +0200 |
| Subject | [PATCH v2 2/4] PCI: Provide common functions for ECAM mapping |
| Message-ID | <rmSOC-4W8-9@gated-at.bofh.it> |
| In reply to | #1376314 |
Add config option PCI_GENERIC_ECAM and file drivers/pci/ecam.c to
provide generic functions for accessing memory mapped PCI config space.
The API is defined in drivers/pci/ecam.h and is written to replace the
API in drivers/pci/host/pci-host-common.h. The file defines a new
'struct pci_config_window' to hold the information related to a PCI
config area and its mapping. This structure is expected to be used as
sysdata for controllers that have ECAM based mapping.
Helper functions are provided to setup the mapping, free the mapping
and to implement the map_bus method in 'struct pci_ops'
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
drivers/pci/Kconfig | 3 ++
drivers/pci/Makefile | 2 +
drivers/pci/ecam.c | 130 +++++++++++++++++++++++++++++++++++++++++++++++++++
drivers/pci/ecam.h | 58 +++++++++++++++++++++++
4 files changed, 193 insertions(+)
create mode 100644 drivers/pci/ecam.c
create mode 100644 drivers/pci/ecam.h
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 209292e..e930d62 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -83,6 +83,9 @@ config HT_IRQ
config PCI_ATS
bool
+config PCI_GENERIC_ECAM
+ bool
+
config PCI_IOV
bool "PCI IOV support"
depends on PCI
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 2154092..810aec8 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -55,6 +55,8 @@ obj-$(CONFIG_PCI_SYSCALL) += syscall.o
obj-$(CONFIG_PCI_STUB) += pci-stub.o
+obj-$(CONFIG_PCI_GENERIC_ECAM) += ecam.o
+
obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o
obj-$(CONFIG_OF) += of.o
diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c
new file mode 100644
index 00000000..798f0b7
--- /dev/null
+++ b/drivers/pci/ecam.c
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2016 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation (the "GPL").
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License version 2 (GPLv2) for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 (GPLv2) along with this source code.
+ */
+
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+
+#include "ecam.h"
+
+/*
+ * On 64 bit systems, we do a single ioremap for the whole config space
+ * since we have enough virtual address range available. On 32 bit, do an
+ * ioremap per bus.
+ */
+static const bool per_bus_mapping = !config_enabled(CONFIG_64BIT);
+
+/*
+ * Create a PCI config space window
+ * - reserve mem region
+ * - alloc struct pci_config_window with space for all mappings
+ * - ioremap the config space
+ */
+struct pci_config_window *pci_generic_ecam_create(struct device *dev,
+ phys_addr_t addr, u8 bus_start, u8 bus_end,
+ struct pci_generic_ecam_ops *ops)
+{
+ struct pci_config_window *cfg;
+ unsigned int bus_shift, bus_range, bsz, mapsz;
+ int i, nidx;
+
+ if (bus_end < bus_start)
+ return ERR_PTR(-EINVAL);
+
+ bus_shift = ops->bus_shift;
+ bus_range = bus_end - bus_start + 1;
+ bsz = 1 << bus_shift;
+ nidx = per_bus_mapping ? bus_range : 1;
+ mapsz = per_bus_mapping ? bsz : bus_range * bsz;
+ cfg = kzalloc(sizeof(*cfg) + nidx * sizeof(cfg->win[0]), GFP_KERNEL);
+ if (!cfg)
+ return ERR_PTR(-ENOMEM);
+
+ cfg->bus_start = bus_start;
+ cfg->bus_end = bus_end;
+ cfg->ops = ops;
+
+ if (!request_mem_region(addr, bus_range * bsz, "Configuration Space"))
+ goto err_exit;
+
+ /* cfgaddr has to be set after request_mem_region */
+ cfg->cfgaddr = addr;
+
+ for (i = 0; i < nidx; i++) {
+ cfg->win[i] = ioremap(addr + i * mapsz, mapsz);
+ if (!cfg->win[i])
+ goto err_exit;
+ }
+ return cfg;
+
+err_exit:
+ pci_generic_ecam_free(cfg);
+ return ERR_PTR(-ENOMEM);
+}
+
+/*
+ * Free a config space mapping
+ */
+void pci_generic_ecam_free(struct pci_config_window *cfg)
+{
+ unsigned int bus_range;
+ int i, nidx;
+
+ bus_range = cfg->bus_end - cfg->bus_start + 1;
+ nidx = per_bus_mapping ? bus_range : 1;
+ for (i = 0; i < nidx; i++)
+ if (cfg->win[i])
+ iounmap(cfg->win[i]);
+ if (cfg->cfgaddr)
+ release_mem_region(cfg->cfgaddr,
+ bus_range << cfg->ops->bus_shift);
+ kfree(cfg);
+}
+
+/*
+ * Function to implement the pci_ops ->map_bus method
+ */
+void __iomem *pci_generic_ecam_map_bus(struct pci_bus *bus, unsigned int devfn,
+ int where)
+{
+ struct pci_config_window *cfg = bus->sysdata;
+ unsigned int devfn_shift = cfg->ops->bus_shift - 8;
+ unsigned int busn = bus->number;
+ void __iomem *base;
+
+ if (busn < cfg->bus_start || busn > cfg->bus_end)
+ return NULL;
+
+ busn -= cfg->bus_start;
+ if (per_bus_mapping)
+ base = cfg->win[busn];
+ else
+ base = cfg->win[0] + (busn << cfg->ops->bus_shift);
+ return base + (devfn << devfn_shift) + where;
+}
+
+/* default ECAM ops */
+struct pci_generic_ecam_ops pci_generic_ecam_default_ops = {
+ .bus_shift = 20,
+ .ops = {
+ .map_bus = pci_generic_ecam_map_bus,
+ .read = pci_generic_config_read,
+ .write = pci_generic_config_write,
+ }
+};
diff --git a/drivers/pci/ecam.h b/drivers/pci/ecam.h
new file mode 100644
index 00000000..dda8c50
--- /dev/null
+++ b/drivers/pci/ecam.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2016 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation (the "GPL").
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License version 2 (GPLv2) for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 (GPLv2) along with this source code.
+ */
+#ifndef DRIVERS_PCI_ECAM_H
+#define DRIVERS_PCI_ECAM_H
+
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+
+/*
+ * struct to hold pci ops and bus shift of the config window
+ * for a PCI controller.
+ */
+struct pci_generic_ecam_ops {
+ unsigned int bus_shift;
+ struct pci_ops ops;
+};
+
+/*
+ * struct to hold the mappings of a config space window. This
+ * will be allocated with enough entries in win[] to hold all
+ * the mappings for the bus range.
+ */
+struct pci_config_window {
+ phys_addr_t cfgaddr;
+ u16 domain;
+ u8 bus_start;
+ u8 bus_end;
+ void *priv;
+ struct pci_generic_ecam_ops *ops;
+ void __iomem *win[0];
+};
+
+/* create and free for pci_config_window */
+struct pci_config_window *pci_generic_ecam_create(struct device *dev,
+ phys_addr_t addr, u8 bus_start, u8 bus_end,
+ struct pci_generic_ecam_ops *ops);
+void pci_generic_ecam_free(struct pci_config_window *cfg);
+
+/* map_bus when ->sysdata is an instance of pci_config_window */
+void __iomem *pci_generic_ecam_map_bus(struct pci_bus *bus, unsigned int devfn,
+ int where);
+/* default ECAM ops, bus shift 20, generic read and write */
+extern struct pci_generic_ecam_ops pci_generic_ecam_default_ops;
+
+#endif
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Jon Masters <jcm@jonmasters.org> |
|---|---|
| Date | 2016-04-12 06:30 +0200 |
| Subject | Re: [PATCH v2 2/4] PCI: Provide common functions for ECAM mapping |
| Message-ID | <rmY7E-ZZ-5@gated-at.bofh.it> |
| In reply to | #1376316 |
Hi David, JC, On 04/11/2016 08:24 PM, David Daney wrote: > Tested-by: David Daney <david.daney@cavium.com> On ThunderX (please let me know the silicon pass specifics off-list)? I'm planning to give this series a test run also on some other ARMv8 hardware and will prod a few of the other vendors to do so. >> drivers/pci/ecam.c | 130 >> drivers/pci/ecam.h | 58 +++++++++++++++++++++++ > > I wonder if these files should go in drivers/pci/host ... I understand > that you still have to use them from drivers/pci/acpi though. > > I will let others opine on this, but could you put the contents of > ecam.h into include/linux/pci.h along with the pci_generic_config_*() > declarations? > > If you did that, the contents of ecam.c could go into > drivers/pci/access.c... Quoting Bjorn's original reply to the previous series: > Some of the code that moved to drivers/acpi/pci_mcfg.c is not > really ACPI-specific, and could potentially be used for non-ACPI > bridges that support ECAM. I'd like to see that sort of code > moved to a new file like drivers/pci/ecam.c. So my guess is that this is the reasoning behind JC's file layout. I'm curious what Lorenzo's take on things is currently. I assume this series is now to be the official coordinated version of this effort for upstream, following the advice of Bjorn previously, but I would like to know if everyone is behind this plan. I've (previously) requested a Linaro LEG meeting this week (part of our bootarch working group) to specifically discuss the status of PCI upstreaming in order to get the different vendors together to ensure every single one of them is tracking the correct latest effort and doing what is needed to test/aid, hence my ask. If this is now plan A, I'll make sure everyone is aligned behind it and start pinging people individually for testing. Jon. -- Computer Architect
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-04-12 18:50 +0200 |
| Subject | Re: [PATCH v2 2/4] PCI: Provide common functions for ECAM mapping |
| Message-ID | <rn9FM-22N-35@gated-at.bofh.it> |
| In reply to | #1376439 |
On Tue, Apr 12, 2016 at 12:26:25AM -0400, Jon Masters wrote: [...] > Quoting Bjorn's original reply to the previous series: > > > Some of the code that moved to drivers/acpi/pci_mcfg.c is not > > really ACPI-specific, and could potentially be used for non-ACPI > > bridges that support ECAM. I'd like to see that sort of code > > moved to a new file like drivers/pci/ecam.c. > > So my guess is that this is the reasoning behind JC's file layout. > > I'm curious what Lorenzo's take on things is currently. I assume this > series is now to be the official coordinated version of this effort for > upstream, following the advice of Bjorn previously, but I would like to > know if everyone is behind this plan. I've (previously) requested a > Linaro LEG meeting this week (part of our bootarch working group) to > specifically discuss the status of PCI upstreaming in order to get the > different vendors together to ensure every single one of them is > tracking the correct latest effort and doing what is needed to test/aid, > hence my ask. If this is now plan A, I'll make sure everyone is aligned > behind it and start pinging people individually for testing. My take is that JC's aim is to get this four patch series reviewed and merged (which is *not* sufficient to get ACPI PCI to work fully on ARM64 - see cover letter - the remaining patches in his branch are not fixes, it is code that is required to get things to work, these 4 patches stand alone are not sufficient but I understand he wants to get them reviewed following feedback on the lists) so that we can make progress on ACPI PCI on ARM64. I will comment on the patches as soon as I have time to review them, I certainly would like to understand what we have to do with the rest of the code though (provided this series is good to go) see above. Lorenzo
[toc] | [prev] | [next] | [standalone]
| From | Jon Masters <jcm@jonmasters.org> |
|---|---|
| Date | 2016-04-14 08:30 +0200 |
| Subject | Re: [PATCH v2 2/4] PCI: Provide common functions for ECAM mapping |
| Message-ID | <rnIWS-5Pm-15@gated-at.bofh.it> |
| In reply to | #1377015 |
On 04/12/2016 12:44 PM, Lorenzo Pieralisi wrote: > On Tue, Apr 12, 2016 at 12:26:25AM -0400, Jon Masters wrote: > > [...] > >> Quoting Bjorn's original reply to the previous series: >> >>> Some of the code that moved to drivers/acpi/pci_mcfg.c is not >>> really ACPI-specific, and could potentially be used for non-ACPI >>> bridges that support ECAM. I'd like to see that sort of code >>> moved to a new file like drivers/pci/ecam.c. >> >> So my guess is that this is the reasoning behind JC's file layout. >> >> I'm curious what Lorenzo's take on things is currently. I assume this >> series is now to be the official coordinated version of this effort for >> upstream, following the advice of Bjorn previously, but I would like to >> know if everyone is behind this plan. I've (previously) requested a >> Linaro LEG meeting this week (part of our bootarch working group) to >> specifically discuss the status of PCI upstreaming in order to get the >> different vendors together to ensure every single one of them is >> tracking the correct latest effort and doing what is needed to test/aid, >> hence my ask. If this is now plan A, I'll make sure everyone is aligned >> behind it and start pinging people individually for testing. > > My take is that JC's aim is to get this four patch series reviewed and > merged Indeed, I see that's probably the goal, and why not :) > (which is *not* sufficient to get ACPI PCI to work fully on ARM64 > - see cover letter - the remaining patches in his branch are not > fixes, it is code that is required to get things to work, these 4 > patches stand alone are not sufficient but I understand he wants to get > them reviewed following feedback on the lists) so that we can make > progress on ACPI PCI on ARM64. Agreed. I went through the branch and the 11 patches there, reacquainted myself with what's what. So what we have now is 4 patches here plus a few others that in total replace v5 of your previous mmconfig patches in functionality. The question is what happens with the rest (of JC's branch let's say) - do they get sent out now too? > I will comment on the patches as soon as I have time to review > them, I certainly would like to understand what we have to do with the > rest of the code though (provided this series is good to go) see above. Right. That's my reason for asking. I'd like to know who is driving (I believe that to be Lorenzo) and what the path forward is, and whether we need to get additional support from anyone else. There's a multi-vendor meeting in the morning where I'm going to summarize the current state of these patches and I would like to know (soon) what the plan is so that we can get everyone on deck to help out at least with testing (most have tested the previous set, but we need public acks happening). Jon.
[toc] | [prev] | [next] | [standalone]
| From | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> |
|---|---|
| Date | 2016-04-14 12:10 +0200 |
| Subject | Re: [PATCH v2 2/4] PCI: Provide common functions for ECAM mapping |
| Message-ID | <rnMnM-4X-9@gated-at.bofh.it> |
| In reply to | #1378513 |
On Thu, Apr 14, 2016 at 01:55:32AM -0400, Jon Masters wrote: [...] > > I will comment on the patches as soon as I have time to review > > them, I certainly would like to understand what we have to do with the > > rest of the code though (provided this series is good to go) see above. > > Right. That's my reason for asking. I'd like to know who is driving (I > believe that to be Lorenzo) and what the path forward is, and whether we > need to get additional support from anyone else. There's a multi-vendor > meeting in the morning where I'm going to summarize the current state of > these patches and I would like to know (soon) what the plan is so that > we can get everyone on deck to help out at least with testing (most have > tested the previous set, but we need public acks happening). Testing always helps, this code needs reviewing from PCI and ACPI standpoints, what we can do is review this series and repost the whole thing when we agree the ECAM refactoring this series is implementing is the right way to go and it is a step in that direction, with no generic MCFG support in the kernel ACPI PCI on ARM64 can't be implemented so I would start from that. Lorenzo
[toc] | [prev] | [next] | [standalone]
| From | Jayachandran C <jchandra@broadcom.com> |
|---|---|
| Date | 2016-04-14 17:50 +0200 |
| Subject | Re: [PATCH v2 2/4] PCI: Provide common functions for ECAM mapping |
| Message-ID | <rnRGO-44y-25@gated-at.bofh.it> |
| In reply to | #1376316 |
On Tue, Apr 12, 2016 at 5:54 AM, David Daney <ddaney@caviumnetworks.com> wrote: > On 04/11/2016 03:45 PM, Jayachandran C wrote: >> >> Add config option PCI_GENERIC_ECAM and file drivers/pci/ecam.c to >> provide generic functions for accessing memory mapped PCI config space. >> >> The API is defined in drivers/pci/ecam.h and is written to replace the >> API in drivers/pci/host/pci-host-common.h. The file defines a new >> 'struct pci_config_window' to hold the information related to a PCI >> config area and its mapping. This structure is expected to be used as >> sysdata for controllers that have ECAM based mapping. >> >> Helper functions are provided to setup the mapping, free the mapping >> and to implement the map_bus method in 'struct pci_ops' >> >> Signed-off-by: Jayachandran C <jchandra@broadcom.com> > > Tested-by: David Daney <david.daney@cavium.com> I have updated the git tree (https://github.com/jchandra-brcm/linux/) with a branch arm64-acpi-pci-v3 . The branch has a new patch to use thunder ECAM ops in case of Cavium ThunderX platform when doing generic ACPI PCI initialization. I am hoping that the controllers that have "ECAM with quirks" can use this mechanism for sharing the quirks between OF and ACPI. If you have some time to review the patch and see it works for you, then I can post it with the v3 of this patchset. >> --- >> drivers/pci/Kconfig | 3 ++ >> drivers/pci/Makefile | 2 + >> drivers/pci/ecam.c | 130 >> +++++++++++++++++++++++++++++++++++++++++++++++++++ >> drivers/pci/ecam.h | 58 +++++++++++++++++++++++ > > > I wonder if these files should go in drivers/pci/host ... I understand that > you still have to use them from drivers/pci/acpi though. > > I will let others opine on this, but could you put the contents of ecam.h > into include/linux/pci.h along with the pci_generic_config_*() > declarations? > > If you did that, the contents of ecam.c could go into > drivers/pci/access.c... Earlier discussion seems to indicated that separate ecam.c/h was preferred. But I agree that it may be small enough to be merged. Thanks, JC.
[toc] | [prev] | [next] | [standalone]
| From | Jayachandran C <jchandra@broadcom.com> |
|---|---|
| Date | 2016-04-12 00:50 +0200 |
| Subject | [PATCH v2 4/4] ACPI: PCI: Add generic PCI host controller |
| Message-ID | <rmSOC-4W8-11@gated-at.bofh.it> |
| In reply to | #1376314 |
Add a generic ACPI based PCI host controller, and provide a config
option ACPI_PCI_HOST_GENERIC to enable it.
The implementation selects PCI_GENERIC_ECAM and uses functions from
drivers/pci/ecam.h to create and access ECAM mappings. It also selects
PCI_MMCONFIG and implements the pci_mmcfg_late_init() function to parse
and map entries in the MCFG table.
The implementation of pci_acpi_scan_root() looks up the saved mappings
and sets up a new mapping if needed. Generic PCI functions are used for
accessing config space.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
drivers/acpi/Kconfig | 9 ++
drivers/acpi/Makefile | 1 +
drivers/acpi/pci_gen_host.c | 258 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 268 insertions(+)
create mode 100644 drivers/acpi/pci_gen_host.c
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 82b96ee..f178f2e 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -343,6 +343,15 @@ config ACPI_PCI_SLOT
i.e., segment/bus/device/function tuples, with physical slots in
the system. If you are unsure, say N.
+config ACPI_PCI_HOST_GENERIC
+ bool "Generic ACPI based PCI controller"
+ depends on ARM64
+ select PCI_MMCONFIG
+ select PCI_GENERIC_ECAM
+ help
+ Say Y if you want the generic ACPI based PCI controller
+ implementation.
+
config X86_PM_TIMER
bool "Power Management Timer Support" if EXPERT
depends on X86
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index edeb2d1..eaf429c 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -66,6 +66,7 @@ obj-$(CONFIG_ACPI_BUTTON) += button.o
obj-$(CONFIG_ACPI_FAN) += fan.o
obj-$(CONFIG_ACPI_VIDEO) += video.o
obj-$(CONFIG_ACPI_PCI_SLOT) += pci_slot.o
+obj-$(CONFIG_ACPI_PCI_HOST_GENERIC) += pci_gen_host.o
obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
obj-$(CONFIG_ACPI) += container.o
obj-$(CONFIG_ACPI_THERMAL) += thermal.o
diff --git a/drivers/acpi/pci_gen_host.c b/drivers/acpi/pci_gen_host.c
new file mode 100644
index 00000000..bd31faa
--- /dev/null
+++ b/drivers/acpi/pci_gen_host.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright 2016 Broadcom
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, version 2, as
+ * published by the Free Software Foundation (the "GPL").
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License version 2 (GPLv2) for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 (GPLv2) along with this source code.
+ */
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/pci-acpi.h>
+#include <linux/sfi_acpi.h>
+#include <linux/slab.h>
+
+#include "../pci/ecam.h"
+
+#define PREFIX "ACPI: "
+
+/*
+ * Array of config windows from MCFG table, parsed and created by
+ * pci_mmcfg_late_init() at boot
+ */
+struct pci_config_window **cfgarr;
+
+/* ACPI info for generic ACPI PCI controller */
+struct acpi_pci_generic_root_info {
+ struct acpi_pci_root_info common;
+ struct pci_config_window *cfg; /* config space mapping */
+ bool mcfg_added;
+};
+
+/* find the entry in cfgarr which contains range bus_start..bus_end */
+static int mcfg_lookup(u16 seg, u8 bus_start, u8 bus_end)
+{
+ struct pci_config_window *cfg;
+ int i;
+
+ if (!cfgarr)
+ return -ENOENT;
+
+ for (i = 0; cfgarr[i]; i++) {
+ cfg = cfgarr[i];
+ if (seg != cfg->domain)
+ continue;
+ if (bus_start >= cfg->bus_start && bus_start <= cfg->bus_end)
+ return (bus_end <= cfg->bus_end) ? i : -EINVAL;
+ else if (bus_end >= cfg->bus_start && bus_end <= cfg->bus_end)
+ return -EINVAL;
+ }
+ return -ENOENT;
+}
+
+/*
+ * create a new mapping
+ */
+static struct pci_config_window *pci_acpi_ecam_create(struct device *dev,
+ phys_addr_t addr, u16 seg, u8 bus_start, u8 bus_end)
+{
+ struct pci_config_window *cfg;
+ int ret;
+
+ cfg = pci_generic_ecam_create(dev, addr, bus_start, bus_end,
+ &pci_generic_ecam_default_ops);
+ if (IS_ERR(cfg)) {
+ ret = PTR_ERR(cfg);
+ pr_err("%04x:%02x-%02x error %d mapping CAM\n", seg,
+ bus_start, bus_end, ret);
+ return NULL;
+ }
+ cfg->domain = seg;
+ return cfg;
+}
+
+/*
+ * Lookup the bus range for the domain in MCFG, and set up config space
+ * mapping.
+ */
+static int pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root,
+ struct acpi_pci_generic_root_info *ri)
+{
+ struct pci_config_window *cfg;
+ u16 seg = root->segment;
+ u8 bus_start = root->secondary.start;
+ u8 bus_end = root->secondary.end;
+ phys_addr_t addr = root->mcfg_addr;
+ struct acpi_device *adev = root->device;
+ int ret;
+
+ ret = mcfg_lookup(seg, bus_start, bus_end);
+ if (ret == -ENOENT) {
+ if (addr == 0) {
+ pr_err("%04x:%02x-%02x mcfg lookup failed\n", seg,
+ bus_start, bus_end);
+ return ret;
+ }
+ cfg = pci_acpi_ecam_create(&adev->dev, addr, seg, bus_start,
+ bus_end);
+ if (!cfg)
+ return ret;
+ } else if (ret < 0) {
+ pr_err("%04x:%02x-%02x bus range error (%d)\n", seg, bus_start,
+ bus_end, ret);
+ return ret;
+ } else {
+ cfg = cfgarr[ret];
+ if (addr == 0)
+ addr = cfg->cfgaddr;
+ if (bus_start != cfg->bus_start) {
+ pr_err("%04x:%02x-%02x bus range mismatch %02x\n",
+ seg, bus_start, bus_end, cfg->bus_start);
+ return -EINVAL;
+ }
+ if (addr != cfg->cfgaddr) {
+ pr_warn("%04x:%02x-%02x addr mismatch, ignoring MCFG\n",
+ seg, bus_start, bus_end);
+ } else if (bus_end != cfg->bus_end) {
+ pr_warn("%04x:%02x-%02x bus end mismatch using %02x\n",
+ seg, bus_start, bus_end, cfg->bus_end);
+ bus_end = cfg->bus_end;
+ }
+ }
+ ri->cfg = cfg;
+ ri->mcfg_added = (ret >= 0);
+
+ return 0;
+}
+
+/* release_info: free resrouces allocated by init_info */
+static void pci_acpi_generic_release_info(struct acpi_pci_root_info *ci)
+{
+ struct acpi_pci_generic_root_info *ri;
+
+ ri = container_of(ci, struct acpi_pci_generic_root_info, common);
+ if (!ri->mcfg_added)
+ pci_generic_ecam_free(ri->cfg);
+ kfree(ri);
+}
+
+static struct acpi_pci_root_ops acpi_pci_root_ops = {
+ .release_info = pci_acpi_generic_release_info,
+};
+
+/* Interface called from ACPI code to setup PCI host controller */
+struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
+{
+ int node = acpi_get_node(root->device->handle);
+ struct acpi_pci_generic_root_info *ri;
+ struct pci_bus *bus, *child;
+ int err;
+
+ ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node);
+ if (!ri)
+ return NULL;
+
+ err = pci_acpi_setup_ecam_mapping(root, ri);
+ if (err)
+ return NULL;
+
+ acpi_pci_root_ops.pci_ops = &ri->cfg->ops->ops;
+ bus = acpi_pci_root_create(root, &acpi_pci_root_ops, &ri->common,
+ ri->cfg);
+ if (!bus)
+ return NULL;
+
+ pci_bus_size_bridges(bus);
+ pci_bus_assign_resources(bus);
+
+ list_for_each_entry(child, &bus->children, node)
+ pcie_bus_configure_settings(child);
+
+ return bus;
+}
+
+/* handle MCFG table entries */
+static __init int handle_mcfg(struct acpi_table_header *header)
+{
+ struct acpi_table_mcfg *mcfg;
+ struct acpi_mcfg_allocation *mptr;
+ struct pci_config_window *cfg;
+ int i, j, n;
+
+ if (!header)
+ return -EINVAL;
+
+ mcfg = (struct acpi_table_mcfg *)header;
+ mptr = (struct acpi_mcfg_allocation *) &mcfg[1];
+ n = (header->length - sizeof(*mcfg)) / sizeof(*mptr);
+ if (n <= 0 || n > 255) {
+ pr_err(PREFIX " MCFG has incorrect entries (%d).\n", n);
+ return -EINVAL;
+ }
+
+ cfgarr = kcalloc(n + 1, sizeof(*cfgarr), GFP_KERNEL);
+ if (!cfgarr)
+ return -ENOMEM;
+
+ for (i = 0, j = 0; i < n; i++) {
+ cfg = pci_acpi_ecam_create(NULL, mptr->address,
+ mptr->pci_segment, mptr->start_bus_number,
+ mptr->end_bus_number);
+ if (!cfg)
+ continue;
+ cfgarr[j++] = cfg;
+ }
+
+ if (j == 0) {
+ kfree(cfgarr);
+ cfgarr = NULL;
+ return -ENOENT;
+ }
+ cfgarr[j] = NULL;
+ return 0;
+}
+
+/* Interface called by ACPI - parse and save MCFG table */
+void __init pci_mmcfg_late_init(void)
+{
+ int i, err;
+
+ err = acpi_sfi_table_parse(ACPI_SIG_MCFG, handle_mcfg);
+ if (err) {
+ pr_err(PREFIX " Failed to parse MCFG (%d)\n", err);
+ } else if (cfgarr == NULL) {
+ pr_err(PREFIX " Failed to parse MCFG, no valid entries.\n");
+ } else {
+ for (i = 0; cfgarr[i]; i++)
+ ;
+ pr_info(PREFIX " MCFG table at loaded, %d entries\n", i);
+ }
+}
+
+/* Raw operations, works only for MCFG entries with an associated bus */
+int raw_pci_read(unsigned int domain, unsigned int busn, unsigned int devfn,
+ int reg, int len, u32 *val)
+{
+ struct pci_bus *bus = pci_find_bus(domain, busn);
+
+ if (!bus)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ return bus->ops->read(bus, devfn, reg, len, val);
+}
+
+int raw_pci_write(unsigned int domain, unsigned int busn, unsigned int devfn,
+ int reg, int len, u32 val)
+{
+ struct pci_bus *bus = pci_find_bus(domain, busn);
+
+ if (!bus)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ return bus->ops->write(bus, devfn, reg, len, val);
+}
--
1.9.1
[toc] | [prev] | [next] | [standalone]
| From | Sinan Kaya <okaya@codeaurora.org> |
|---|---|
| Date | 2016-04-14 18:00 +0200 |
| Subject | Re: [PATCH v2 4/4] ACPI: PCI: Add generic PCI host controller |
| Message-ID | <rnRQu-4b1-19@gated-at.bofh.it> |
| In reply to | #1376317 |
On 4/11/2016 6:45 PM, Jayachandran C wrote:
> +/* find the entry in cfgarr which contains range bus_start..bus_end */
> +static int mcfg_lookup(u16 seg, u8 bus_start, u8 bus_end)
> +{
> + struct pci_config_window *cfg;
> + int i;
> +
> + if (!cfgarr)
> + return -ENOENT;
> +
> + for (i = 0; cfgarr[i]; i++) {
> + cfg = cfgarr[i];
> +
I see that you are allocating an array of cfgarr to keep the MCFG table entries.
The above way of checking the number of entries is not correct.
You should keep track of the number of entries you found out globally instead of
relying an element being NULL or not.
If you exceed the array size, you may or may not be lucky to find another entry
in memory.
--
Sinan Kaya
Qualcomm Technologies, Inc. on behalf of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
[toc] | [prev] | [next] | [standalone]
| From | Sinan Kaya <okaya@codeaurora.org> |
|---|---|
| Date | 2016-04-14 18:00 +0200 |
| Subject | Re: [PATCH v2 4/4] ACPI: PCI: Add generic PCI host controller |
| Message-ID | <rnRQu-4b1-21@gated-at.bofh.it> |
| In reply to | #1379057 |
On 4/14/2016 11:53 AM, Sinan Kaya wrote:
> On 4/11/2016 6:45 PM, Jayachandran C wrote:
>> +/* find the entry in cfgarr which contains range bus_start..bus_end */
>> +static int mcfg_lookup(u16 seg, u8 bus_start, u8 bus_end)
>> +{
>> + struct pci_config_window *cfg;
>> + int i;
>> +
>> + if (!cfgarr)
>> + return -ENOENT;
>> +
>> + for (i = 0; cfgarr[i]; i++) {
>> + cfg = cfgarr[i];
>> +
>
> I see that you are allocating an array of cfgarr to keep the MCFG table entries.
> The above way of checking the number of entries is not correct.
>
> You should keep track of the number of entries you found out globally instead of
> relying an element being NULL or not.
>
> If you exceed the array size, you may or may not be lucky to find another entry
> in memory.
>
I see now that you are allocating an extra element in memory. Still, looping to find
out the number of elements didn't quite look good to me.
+ for (i = 0; cfgarr[i]; i++)
+ ;
+ pr_info(PREFIX " MCFG table at loaded, %d entries\n", i);
--
Sinan Kaya
Qualcomm Technologies, Inc. on behalf of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
[toc] | [prev] | [next] | [standalone]
| From | Jayachandran C <jchandra@broadcom.com> |
|---|---|
| Date | 2016-04-12 00:50 +0200 |
| Subject | [PATCH v2 1/4] arm64: Prepare to use generic ACPI PCI implementation |
| Message-ID | <rmSOC-4W8-13@gated-at.bofh.it> |
| In reply to | #1376314 |
Define PCI_MMCONFIG config option for arm64.
Weaken implementations of raw_pci_read/write and pci_acpi_scan_root,
the generic ACPI PCI driver will implement these.
Signed-off-by: Jayachandran C <jchandra@broadcom.com>
---
arch/arm64/Kconfig | 3 +++
arch/arm64/kernel/pci.c | 7 +++----
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 4f43622..6c6658a 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -236,6 +236,9 @@ config PCI_DOMAINS_GENERIC
config PCI_SYSCALL
def_bool PCI
+config PCI_MMCONFIG
+ bool
+
source "drivers/pci/Kconfig"
endmenu
diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
index 15109c11..098028c 100644
--- a/arch/arm64/kernel/pci.c
+++ b/arch/arm64/kernel/pci.c
@@ -67,13 +67,13 @@ int pcibios_alloc_irq(struct pci_dev *dev)
/*
* raw_pci_read/write - Platform-specific PCI config space access.
*/
-int raw_pci_read(unsigned int domain, unsigned int bus,
+int __weak raw_pci_read(unsigned int domain, unsigned int bus,
unsigned int devfn, int reg, int len, u32 *val)
{
return -ENXIO;
}
-int raw_pci_write(unsigned int domain, unsigned int bus,
+int __weak raw_pci_write(unsigned int domain, unsigned int bus,
unsigned int devfn, int reg, int len, u32 val)
{
return -ENXIO;
@@ -81,9 +81,8 @@ int raw_pci_write(unsigned int domain, unsigned int bus,
#ifdef CONFIG_ACPI
/* Root bridge scanning */
-struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
+struct pci_bus *__weak pci_acpi_scan_root(struct acpi_pci_root *root)
{
- /* TODO: Should be revisited when implementing PCI on ACPI */
return NULL;
}
#endif
--
1.9.1
[toc] | [prev] | [standalone]
Back to top | Article view | linux.kernel
csiph-web