* [PATCH v2 0/3] PCI: Add PTM sysfs support
@ 2025-03-24 10:04 Manivannan Sadhasivam via B4 Relay
2025-03-24 10:04 ` [PATCH v2 1/3] PCI: Add sysfs support for exposing PTM context Manivannan Sadhasivam via B4 Relay
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Manivannan Sadhasivam via B4 Relay @ 2025-03-24 10:04 UTC (permalink / raw)
To: Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring,
Bjorn Helgaas, Jingoo Han
Cc: linux-pci, linux-kernel, linux-arm-msm, Manivannan Sadhasivam
Hi,
This series adds sysfs support to expose the PTM context available in the
capable PCIe controllers. Support for enabling PTM in the requester/responder is
already available in drivers/pci/pcie/ptm.c and this series expands that file to
add sysfs support for the PTM context info.
The controller drivers are expected to call pcie_ptm_create_sysfs() with
'pcie_ptm_ops' callbacks populated to create the sysfs entries and call
pcie_ptm_destroy_sysfs() to destroy them.
Patch 1 adds the necessary code in the drivers/pci/pcie/ptm.c to expose PTM
context over sysfs and patch 2 adds PTM support in the DWC drivers (host and
endpoint). Finally, patch 3 masks the PTM_UPDATING interrupt in the pcie-qcom-ep
driver to avoid processing the interrupt for each PTM context update.
Testing
=======
This series is tested on Qcom SA8775p Ride Mx platform where one SA8775p acts as
RC and another as EP with following instructions:
RC
--
$ echo 1 > /sys/devices/platform/1c10000.pcie/ptm/context_valid
EP
--
$ echo auto > /sys/devices/platform/1c10000.pcie-ep/ptm/context_update
$ cat /sys/devices/platform/1c10000.pcie-ep/ptm/local_clock
159612570424
$ cat /sys/devices/platform/1c10000.pcie-ep/ptm/master_clock
159609466232
$ cat /sys/devices/platform/1c10000.pcie-ep/ptm/t1
159609466112
$ cat /sys/devices/platform/1c10000.pcie-ep/ptm/t4
159609466518
NOTE: To make use of the PTM feature, the host PCIe client driver has to call
'pci_enable_ptm()' API during probe. This series was tested with enabling PTM in
the MHI host driver with a local change (which will be upstreamed later).
Technically, PTM could also be enabled in the pci_endpoint_test driver, but I
didn't add the change as I'm not sure we'd want to add random PCIe features in
the test driver without corresponding code in pci-epf-test driver.
Changes in v2:
* Dropped the VSEC changes that got merged
* Moved the PTM sysfs code from drivers/pci/controller/dwc to
drivers/pci/pcie/ptm to make it generic so that other controller drivers could
also benefit from it.
* Rebased on top of pci/controller/dwc
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
Manivannan Sadhasivam (3):
PCI: Add sysfs support for exposing PTM context
PCI: dwc: Add sysfs support for PTM context
PCI: qcom-ep: Mask PTM_UPDATING interrupt
Documentation/ABI/testing/sysfs-platform-pcie-ptm | 70 ++++++
MAINTAINERS | 1 +
drivers/pci/controller/dwc/Makefile | 2 +-
drivers/pci/controller/dwc/pcie-designware-ep.c | 3 +
drivers/pci/controller/dwc/pcie-designware-host.c | 3 +
drivers/pci/controller/dwc/pcie-designware-sysfs.c | 254 +++++++++++++++++++
drivers/pci/controller/dwc/pcie-designware.c | 6 +
drivers/pci/controller/dwc/pcie-designware.h | 21 ++
drivers/pci/controller/dwc/pcie-qcom-ep.c | 8 +
drivers/pci/pcie/ptm.c | 268 +++++++++++++++++++++
include/linux/pci.h | 35 +++
include/linux/pcie-dwc.h | 8 +
12 files changed, 678 insertions(+), 1 deletion(-)
---
base-commit: 1f5a69f1b3132054d8d82b8d7546d0af6a2ed4f6
change-id: 20250324-pcie-ptm-e75b9b2ffcfb
Best regards,
--
Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
^ permalink raw reply [flat|nested] 12+ messages in thread* [PATCH v2 1/3] PCI: Add sysfs support for exposing PTM context 2025-03-24 10:04 [PATCH v2 0/3] PCI: Add PTM sysfs support Manivannan Sadhasivam via B4 Relay @ 2025-03-24 10:04 ` Manivannan Sadhasivam via B4 Relay 2025-03-24 13:01 ` Ilpo Järvinen ` (2 more replies) 2025-03-24 10:04 ` [PATCH v2 2/3] PCI: dwc: Add sysfs support for " Manivannan Sadhasivam via B4 Relay 2025-03-24 10:04 ` [PATCH v2 3/3] PCI: qcom-ep: Mask PTM_UPDATING interrupt Manivannan Sadhasivam via B4 Relay 2 siblings, 3 replies; 12+ messages in thread From: Manivannan Sadhasivam via B4 Relay @ 2025-03-24 10:04 UTC (permalink / raw) To: Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Jingoo Han Cc: linux-pci, linux-kernel, linux-arm-msm, Manivannan Sadhasivam From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Precision Time Management (PTM) mechanism defined in PCIe spec r6.0, sec 6.22 allows precise coordination of timing information across multiple components in a PCIe hierarchy with independent local time clocks. PCI core already supports enabling PTM in the root port and endpoint devices through PTM Extended Capability registers. But the PTM context supported by the PTM capable components such as Root Complex (RC) and Endpoint (EP) controllers were not exposed as of now. Hence, add the sysfs support to expose the PTM context to userspace from both PCIe RC and EP controllers. Controller drivers are expected to call pcie_ptm_create_sysfs() to create the sysfs attributes for the PTM context and call pcie_ptm_destroy_sysfs() to destroy them. The drivers should also populate the relevant callbacks in the 'struct pcie_ptm_ops' structure based on the controller implementation. Below PTM context are exposed through sysfs: PCIe RC ======= 1. PTM Local clock 2. PTM T2 timestamp 3. PTM T3 timestamp 4. PTM Context valid PCIe EP ======= 1. PTM Local clock 2. PTM T1 timestamp 3. PTM T4 timestamp 4. PTM Master clock 5. PTM Context update Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> --- Documentation/ABI/testing/sysfs-platform-pcie-ptm | 70 ++++++ MAINTAINERS | 1 + drivers/pci/pcie/ptm.c | 268 ++++++++++++++++++++++ include/linux/pci.h | 35 +++ 4 files changed, 374 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-platform-pcie-ptm b/Documentation/ABI/testing/sysfs-platform-pcie-ptm new file mode 100644 index 0000000000000000000000000000000000000000..010c3e32e2b8eaf352a8e1aad7420d8a3e948dae --- /dev/null +++ b/Documentation/ABI/testing/sysfs-platform-pcie-ptm @@ -0,0 +1,70 @@ +What: /sys/devices/platform/*/ptm/local_clock +Date: February 2025 +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Description: + (RO) PTM local clock in nanoseconds. Applicable for both Root + Complex and Endpoint controllers. + +What: /sys/devices/platform/*/ptm/master_clock +Date: February 2025 +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Description: + (RO) PTM master clock in nanoseconds. Applicable only for + Endpoint controllers. + +What: /sys/devices/platform/*/ptm/t1 +Date: February 2025 +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Description: + (RO) PTM T1 timestamp in nanoseconds. Applicable only for + Endpoint controllers. + +What: /sys/devices/platform/*/ptm/t2 +Date: February 2025 +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Description: + (RO) PTM T2 timestamp in nanoseconds. Applicable only for + Root Complex controllers. + +What: /sys/devices/platform/*/ptm/t3 +Date: February 2025 +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Description: + (RO) PTM T3 timestamp in nanoseconds. Applicable only for + Root Complex controllers. + +What: /sys/devices/platform/*/ptm/t4 +Date: February 2025 +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Description: + (RO) PTM T4 timestamp in nanoseconds. Applicable only for + Endpoint controllers. + +What: /sys/devices/platform/*/ptm/context_update +Date: February 2025 +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Description: + (RW) Control the PTM context update mode. Applicable only for + Endpoint controllers. + + Following values are supported: + + * auto = PTM context auto update trigger for every 10ms + + * manual = PTM context manual update. Writing 'manual' to this + file triggers PTM context update (default) + +What: /sys/devices/platform/*/ptm/context_valid +Date: February 2025 +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> +Description: + (RW) Control the PTM context validity (local clock timing). + Applicable only for Root Complex controllers. PTM context is + invalidated by hardware if the Root Complex enters low power + mode or changes link frequency. + + Following values are supported: + + * 0 = PTM context invalid (default) + + * 1 = PTM context valid diff --git a/MAINTAINERS b/MAINTAINERS index b4d09d52a750b320f689c1365791cdfa6e719fde..f1bac092877df739328347481bd14f6701a7df19 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -18213,6 +18213,7 @@ Q: https://patchwork.kernel.org/project/linux-pci/list/ B: https://bugzilla.kernel.org C: irc://irc.oftc.net/linux-pci T: git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git +F: Documentation/ABI/testing/sysfs-platform-pcie-ptm F: Documentation/devicetree/bindings/pci/ F: drivers/pci/controller/ F: drivers/pci/pci-bridge-emul.c diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c index 7cfb6c0d5dcb6de2a759b56d6877c95102b3d10f..bfa632b76a87ad304e966a8edfb5dba14d58a23c 100644 --- a/drivers/pci/pcie/ptm.c +++ b/drivers/pci/pcie/ptm.c @@ -10,6 +10,8 @@ #include <linux/pci.h> #include "../pci.h" +struct device *ptm_device; + /* * If the next upstream device supports PTM, return it; otherwise return * NULL. PTM Messages are local, so both link partners must support it. @@ -252,3 +254,269 @@ bool pcie_ptm_enabled(struct pci_dev *dev) return dev->ptm_enabled; } EXPORT_SYMBOL(pcie_ptm_enabled); + +static ssize_t context_update_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct pcie_ptm *ptm = dev_get_drvdata(dev); + int ret; + + if (!ptm->ops->context_update_store) + return -EOPNOTSUPP; + + ret = ptm->ops->context_update_store(ptm->pdata, buf); + if (ret) + return ret; + + return count; +} + +static ssize_t context_update_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pcie_ptm *ptm = dev_get_drvdata(dev); + + if (!ptm->ops->context_update_show) + return -EOPNOTSUPP; + + return ptm->ops->context_update_show(ptm->pdata, buf); +} + +static ssize_t context_valid_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct pcie_ptm *ptm = dev_get_drvdata(dev); + unsigned long arg; + int ret; + + if (kstrtoul(buf, 0, &arg) < 0) + return -EINVAL; + + if (!ptm->ops->context_valid_store) + return -EOPNOTSUPP; + + ret = ptm->ops->context_valid_store(ptm->pdata, !!arg); + if (ret) + return ret; + + return count; +} + +static ssize_t context_valid_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pcie_ptm *ptm = dev_get_drvdata(dev); + + if (!ptm->ops->context_valid_show) + return -EOPNOTSUPP; + + return ptm->ops->context_valid_show(ptm->pdata, buf); +} + +static ssize_t local_clock_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pcie_ptm *ptm = dev_get_drvdata(dev); + + if (!ptm->ops->local_clock_show) + return -EOPNOTSUPP; + + return ptm->ops->local_clock_show(ptm->pdata, buf); +} + +static ssize_t master_clock_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pcie_ptm *ptm = dev_get_drvdata(dev); + + if (!ptm->ops->master_clock_show) + return -EOPNOTSUPP; + + return ptm->ops->master_clock_show(ptm->pdata, buf); +} + +static ssize_t t1_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pcie_ptm *ptm = dev_get_drvdata(dev); + + if (!ptm->ops->t1_show) + return -EOPNOTSUPP; + + return ptm->ops->t1_show(ptm->pdata, buf); +} + +static ssize_t t2_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pcie_ptm *ptm = dev_get_drvdata(dev); + + if (!ptm->ops->t2_show) + return -EOPNOTSUPP; + + return ptm->ops->t2_show(ptm->pdata, buf); +} + +static ssize_t t3_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pcie_ptm *ptm = dev_get_drvdata(dev); + + if (!ptm->ops->t3_show) + return -EOPNOTSUPP; + + return ptm->ops->t3_show(ptm->pdata, buf); +} + +static ssize_t t4_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct pcie_ptm *ptm = dev_get_drvdata(dev); + + if (!ptm->ops->t4_show) + return -EOPNOTSUPP; + + return ptm->ops->t4_show(ptm->pdata, buf); +} + +static DEVICE_ATTR_RW(context_update); +static DEVICE_ATTR_RW(context_valid); +static DEVICE_ATTR_RO(local_clock); +static DEVICE_ATTR_RO(master_clock); +static DEVICE_ATTR_RO(t1); +static DEVICE_ATTR_RO(t2); +static DEVICE_ATTR_RO(t3); +static DEVICE_ATTR_RO(t4); + +static struct attribute *pcie_ptm_attrs[] = { + &dev_attr_context_update.attr, + &dev_attr_context_valid.attr, + &dev_attr_local_clock.attr, + &dev_attr_master_clock.attr, + &dev_attr_t1.attr, + &dev_attr_t2.attr, + &dev_attr_t3.attr, + &dev_attr_t4.attr, + NULL +}; + +static umode_t pcie_ptm_attr_visible(struct kobject *kobj, struct attribute *attr, + int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct pcie_ptm *ptm = dev_get_drvdata(dev); + + if ((attr == &dev_attr_t1.attr && ptm->ops->t1_visible && + ptm->ops->t1_visible(ptm->pdata)) || + (attr == &dev_attr_t2.attr && ptm->ops->t2_visible && + ptm->ops->t2_visible(ptm->pdata)) || + (attr == &dev_attr_t3.attr && ptm->ops->t3_visible && + ptm->ops->t3_visible(ptm->pdata)) || + (attr == &dev_attr_t4.attr && ptm->ops->t4_visible && + ptm->ops->t4_visible(ptm->pdata)) || + (attr == &dev_attr_local_clock.attr && + ptm->ops->local_clock_visible && + ptm->ops->local_clock_visible(ptm->pdata)) || + (attr == &dev_attr_master_clock.attr && + ptm->ops->master_clock_visible && + ptm->ops->master_clock_visible(ptm->pdata)) || + (attr == &dev_attr_context_update.attr && + ptm->ops->context_update_visible && + ptm->ops->context_update_visible(ptm->pdata)) || + (attr == &dev_attr_context_valid.attr && + ptm->ops->context_valid_visible && + ptm->ops->context_valid_visible(ptm->pdata))) + return attr->mode; + + return 0; +} + +static const struct attribute_group pcie_ptm_attr_group = { + .attrs = pcie_ptm_attrs, + .is_visible = pcie_ptm_attr_visible, +}; + +static const struct attribute_group *pcie_ptm_attr_groups[] = { + &pcie_ptm_attr_group, + NULL, +}; + +static void pcie_ptm_release(struct device *dev) +{ + struct pcie_ptm *ptm = container_of(dev, struct pcie_ptm, dev); + + kfree(ptm); +} + +/* + * pcie_ptm_create_sysfs() - Create sysfs entries for the PTM context + * @dev: PTM capable component device + * @pdata: Private data of the PTM capable component device + * @ops: PTM callback structure + * + * Create sysfs entries for exposing the PTM context of the PTM capable + * components such as Root Complex and Endpoint controllers. + */ +int pcie_ptm_create_sysfs(struct device *dev, void *pdata, + struct pcie_ptm_ops *ops) +{ + struct pcie_ptm *ptm; + int ret; + + /* Caller must provide check_capability() callback */ + if (!ops->check_capability) + return -EINVAL; + + /* Check for PTM capability before creating sysfs attrbutes */ + ret = ops->check_capability(pdata); + if (!ret) { + dev_dbg(dev, "PTM capability not present\n"); + return -ENODATA; + } + + ptm = kzalloc(sizeof(*ptm), GFP_KERNEL); + if (!ptm) + return -ENOMEM; + + ptm->pdata = pdata; + ptm->ops = ops; + + device_initialize(&ptm->dev); + ptm->dev.groups = pcie_ptm_attr_groups; + ptm->dev.release = pcie_ptm_release; + ptm->dev.parent = dev; + dev_set_drvdata(&ptm->dev, ptm); + device_set_pm_not_required(&ptm->dev); + + ret = dev_set_name(&ptm->dev, "ptm"); + if (ret) + goto err_put_device; + + ret = device_add(&ptm->dev); + if (ret) + goto err_put_device; + + ptm_device = &ptm->dev; + + return 0; + +err_put_device: + put_device(&ptm->dev); + + return ret; +} +EXPORT_SYMBOL(pci_ptm_init); + +/* + * pcie_ptm_destroy_sysfs() - Destroy sysfs entries for the PTM context + */ +void pcie_ptm_destroy_sysfs(void) +{ + if (ptm_device) { + device_unregister(ptm_device); + ptm_device = NULL; + } +} +EXPORT_SYMBOL(pcie_ptm_destroy_sysfs); diff --git a/include/linux/pci.h b/include/linux/pci.h index 47b31ad724fa5bf7abd7c3dc572947551b0f2148..42bb3cf0212e96fd65a1f01410ef70c82491c9eb 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1857,16 +1857,51 @@ static inline bool pci_aer_available(void) { return false; } bool pci_ats_disabled(void); +struct pcie_ptm_ops { + int (*check_capability)(void *drvdata); + int (*context_update_store)(void *drvdata, const char *buf); + ssize_t (*context_update_show)(void *drvdata, char *buf); + int (*context_valid_store)(void *drvdata, bool valid); + ssize_t (*context_valid_show)(void *drvdata, char *buf); + ssize_t (*local_clock_show)(void *drvdata, char *buf); + ssize_t (*master_clock_show)(void *drvdata, char *buf); + ssize_t (*t1_show)(void *drvdata, char *buf); + ssize_t (*t2_show)(void *drvdata, char *buf); + ssize_t (*t3_show)(void *drvdata, char *buf); + ssize_t (*t4_show)(void *drvdata, char *buf); + + bool (*context_update_visible)(void *drvdata); + bool (*context_valid_visible)(void *drvdata); + bool (*local_clock_visible)(void *drvdata); + bool (*master_clock_visible)(void *drvdata); + bool (*t1_visible)(void *drvdata); + bool (*t2_visible)(void *drvdata); + bool (*t3_visible)(void *drvdata); + bool (*t4_visible)(void *drvdata); +}; + +struct pcie_ptm { + struct device dev; + struct pcie_ptm_ops *ops; + void *pdata; +}; + #ifdef CONFIG_PCIE_PTM int pci_enable_ptm(struct pci_dev *dev, u8 *granularity); void pci_disable_ptm(struct pci_dev *dev); bool pcie_ptm_enabled(struct pci_dev *dev); +int pcie_ptm_create_sysfs(struct device *dev, void *pdata, struct pcie_ptm_ops *ops); +void pcie_ptm_destroy_sysfs(void); #else static inline int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) { return -EINVAL; } static inline void pci_disable_ptm(struct pci_dev *dev) { } static inline bool pcie_ptm_enabled(struct pci_dev *dev) { return false; } +static inline int pcie_ptm_create_sysfs(struct device *dev, void *pdata, + struct pcie_ptm_ops *ops) +{ return 0; } +static inline void pcie_ptm_destroy_sysfs(void) { } #endif void pci_cfg_access_lock(struct pci_dev *dev); -- 2.43.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] PCI: Add sysfs support for exposing PTM context 2025-03-24 10:04 ` [PATCH v2 1/3] PCI: Add sysfs support for exposing PTM context Manivannan Sadhasivam via B4 Relay @ 2025-03-24 13:01 ` Ilpo Järvinen 2025-04-07 7:36 ` Manivannan Sadhasivam 2025-03-24 16:28 ` Bjorn Helgaas 2025-03-26 21:18 ` kernel test robot 2 siblings, 1 reply; 12+ messages in thread From: Ilpo Järvinen @ 2025-03-24 13:01 UTC (permalink / raw) To: Manivannan Sadhasivam Cc: Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Jingoo Han, linux-pci, linux-kernel, linux-arm-msm On Mon, 24 Mar 2025, Manivannan Sadhasivam via B4 Relay wrote: > From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > > Precision Time Management (PTM) mechanism defined in PCIe spec r6.0, > sec 6.22 allows precise coordination of timing information across multiple > components in a PCIe hierarchy with independent local time clocks. Hi Mani, PCIe r6.0.1 sec 6.22 is about Readiness Notification (RN) and PTM is 6.21, did you perhaps mistype the section number? > PCI core already supports enabling PTM in the root port and endpoint > devices through PTM Extended Capability registers. But the PTM context > supported by the PTM capable components such as Root Complex (RC) and > Endpoint (EP) controllers were not exposed as of now. > > Hence, add the sysfs support to expose the PTM context to userspace from > both PCIe RC and EP controllers. Controller drivers are expected to call > pcie_ptm_create_sysfs() to create the sysfs attributes for the PTM context > and call pcie_ptm_destroy_sysfs() to destroy them. The drivers should also > populate the relevant callbacks in the 'struct pcie_ptm_ops' structure > based on the controller implementation. > > Below PTM context are exposed through sysfs: > > PCIe RC > ======= > > 1. PTM Local clock > 2. PTM T2 timestamp > 3. PTM T3 timestamp > 4. PTM Context valid > > PCIe EP > ======= > > 1. PTM Local clock > 2. PTM T1 timestamp > 3. PTM T4 timestamp > 4. PTM Master clock > 5. PTM Context update > > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > --- > Documentation/ABI/testing/sysfs-platform-pcie-ptm | 70 ++++++ > MAINTAINERS | 1 + > drivers/pci/pcie/ptm.c | 268 ++++++++++++++++++++++ > include/linux/pci.h | 35 +++ > 4 files changed, 374 insertions(+) > > diff --git a/Documentation/ABI/testing/sysfs-platform-pcie-ptm b/Documentation/ABI/testing/sysfs-platform-pcie-ptm > new file mode 100644 > index 0000000000000000000000000000000000000000..010c3e32e2b8eaf352a8e1aad7420d8a3e948dae > --- /dev/null > +++ b/Documentation/ABI/testing/sysfs-platform-pcie-ptm > @@ -0,0 +1,70 @@ > +What: /sys/devices/platform/*/ptm/local_clock > +Date: February 2025 > +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > +Description: > + (RO) PTM local clock in nanoseconds. Applicable for both Root > + Complex and Endpoint controllers. > + > +What: /sys/devices/platform/*/ptm/master_clock > +Date: February 2025 > +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > +Description: > + (RO) PTM master clock in nanoseconds. Applicable only for > + Endpoint controllers. > + > +What: /sys/devices/platform/*/ptm/t1 > +Date: February 2025 > +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > +Description: > + (RO) PTM T1 timestamp in nanoseconds. Applicable only for > + Endpoint controllers. > + > +What: /sys/devices/platform/*/ptm/t2 > +Date: February 2025 > +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > +Description: > + (RO) PTM T2 timestamp in nanoseconds. Applicable only for > + Root Complex controllers. > + > +What: /sys/devices/platform/*/ptm/t3 > +Date: February 2025 > +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > +Description: > + (RO) PTM T3 timestamp in nanoseconds. Applicable only for > + Root Complex controllers. > + > +What: /sys/devices/platform/*/ptm/t4 > +Date: February 2025 > +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > +Description: > + (RO) PTM T4 timestamp in nanoseconds. Applicable only for > + Endpoint controllers. > + > +What: /sys/devices/platform/*/ptm/context_update > +Date: February 2025 > +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > +Description: > + (RW) Control the PTM context update mode. Applicable only for > + Endpoint controllers. > + > + Following values are supported: > + > + * auto = PTM context auto update trigger for every 10ms > + > + * manual = PTM context manual update. Writing 'manual' to this > + file triggers PTM context update (default) > + > +What: /sys/devices/platform/*/ptm/context_valid > +Date: February 2025 > +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > +Description: > + (RW) Control the PTM context validity (local clock timing). > + Applicable only for Root Complex controllers. PTM context is > + invalidated by hardware if the Root Complex enters low power > + mode or changes link frequency. > + > + Following values are supported: > + > + * 0 = PTM context invalid (default) > + > + * 1 = PTM context valid > diff --git a/MAINTAINERS b/MAINTAINERS > index b4d09d52a750b320f689c1365791cdfa6e719fde..f1bac092877df739328347481bd14f6701a7df19 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -18213,6 +18213,7 @@ Q: https://patchwork.kernel.org/project/linux-pci/list/ > B: https://bugzilla.kernel.org > C: irc://irc.oftc.net/linux-pci > T: git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git > +F: Documentation/ABI/testing/sysfs-platform-pcie-ptm > F: Documentation/devicetree/bindings/pci/ > F: drivers/pci/controller/ > F: drivers/pci/pci-bridge-emul.c > diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c > index 7cfb6c0d5dcb6de2a759b56d6877c95102b3d10f..bfa632b76a87ad304e966a8edfb5dba14d58a23c 100644 > --- a/drivers/pci/pcie/ptm.c > +++ b/drivers/pci/pcie/ptm.c > @@ -10,6 +10,8 @@ > #include <linux/pci.h> > #include "../pci.h" > > +struct device *ptm_device; > + > /* > * If the next upstream device supports PTM, return it; otherwise return > * NULL. PTM Messages are local, so both link partners must support it. > @@ -252,3 +254,269 @@ bool pcie_ptm_enabled(struct pci_dev *dev) > return dev->ptm_enabled; > } > EXPORT_SYMBOL(pcie_ptm_enabled); > + > +static ssize_t context_update_store(struct device *dev, > + struct device_attribute *attr, > + const char *buf, size_t count) > +{ > + struct pcie_ptm *ptm = dev_get_drvdata(dev); > + int ret; > + > + if (!ptm->ops->context_update_store) > + return -EOPNOTSUPP; > + > + ret = ptm->ops->context_update_store(ptm->pdata, buf); Do these store funcs need some locking? Who is responsible about it? Why isn't buf parsed here and converted to some define/enum values, what is the advantage of passing it on as char *? -- i. > + if (ret) > + return ret; > + > + return count; > +} > + > +static ssize_t context_update_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct pcie_ptm *ptm = dev_get_drvdata(dev); > + > + if (!ptm->ops->context_update_show) > + return -EOPNOTSUPP; > + > + return ptm->ops->context_update_show(ptm->pdata, buf); > +} > + > +static ssize_t context_valid_store(struct device *dev, > + struct device_attribute *attr, > + const char *buf, size_t count) > +{ > + struct pcie_ptm *ptm = dev_get_drvdata(dev); > + unsigned long arg; > + int ret; > + > + if (kstrtoul(buf, 0, &arg) < 0) > + return -EINVAL; > + > + if (!ptm->ops->context_valid_store) > + return -EOPNOTSUPP; > + > + ret = ptm->ops->context_valid_store(ptm->pdata, !!arg); > + if (ret) > + return ret; > + > + return count; > +} > + > +static ssize_t context_valid_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct pcie_ptm *ptm = dev_get_drvdata(dev); > + > + if (!ptm->ops->context_valid_show) > + return -EOPNOTSUPP; > + > + return ptm->ops->context_valid_show(ptm->pdata, buf); > +} > + > +static ssize_t local_clock_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct pcie_ptm *ptm = dev_get_drvdata(dev); > + > + if (!ptm->ops->local_clock_show) > + return -EOPNOTSUPP; > + > + return ptm->ops->local_clock_show(ptm->pdata, buf); > +} > + > +static ssize_t master_clock_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct pcie_ptm *ptm = dev_get_drvdata(dev); > + > + if (!ptm->ops->master_clock_show) > + return -EOPNOTSUPP; > + > + return ptm->ops->master_clock_show(ptm->pdata, buf); > +} > + > +static ssize_t t1_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct pcie_ptm *ptm = dev_get_drvdata(dev); > + > + if (!ptm->ops->t1_show) > + return -EOPNOTSUPP; > + > + return ptm->ops->t1_show(ptm->pdata, buf); > +} > + > +static ssize_t t2_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct pcie_ptm *ptm = dev_get_drvdata(dev); > + > + if (!ptm->ops->t2_show) > + return -EOPNOTSUPP; > + > + return ptm->ops->t2_show(ptm->pdata, buf); > +} > + > +static ssize_t t3_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct pcie_ptm *ptm = dev_get_drvdata(dev); > + > + if (!ptm->ops->t3_show) > + return -EOPNOTSUPP; > + > + return ptm->ops->t3_show(ptm->pdata, buf); > +} > + > +static ssize_t t4_show(struct device *dev, > + struct device_attribute *attr, char *buf) > +{ > + struct pcie_ptm *ptm = dev_get_drvdata(dev); > + > + if (!ptm->ops->t4_show) > + return -EOPNOTSUPP; > + > + return ptm->ops->t4_show(ptm->pdata, buf); > +} > + > +static DEVICE_ATTR_RW(context_update); > +static DEVICE_ATTR_RW(context_valid); > +static DEVICE_ATTR_RO(local_clock); > +static DEVICE_ATTR_RO(master_clock); > +static DEVICE_ATTR_RO(t1); > +static DEVICE_ATTR_RO(t2); > +static DEVICE_ATTR_RO(t3); > +static DEVICE_ATTR_RO(t4); > + > +static struct attribute *pcie_ptm_attrs[] = { > + &dev_attr_context_update.attr, > + &dev_attr_context_valid.attr, > + &dev_attr_local_clock.attr, > + &dev_attr_master_clock.attr, > + &dev_attr_t1.attr, > + &dev_attr_t2.attr, > + &dev_attr_t3.attr, > + &dev_attr_t4.attr, > + NULL > +}; > + > +static umode_t pcie_ptm_attr_visible(struct kobject *kobj, struct attribute *attr, > + int n) > +{ > + struct device *dev = container_of(kobj, struct device, kobj); > + struct pcie_ptm *ptm = dev_get_drvdata(dev); > + > + if ((attr == &dev_attr_t1.attr && ptm->ops->t1_visible && > + ptm->ops->t1_visible(ptm->pdata)) || > + (attr == &dev_attr_t2.attr && ptm->ops->t2_visible && > + ptm->ops->t2_visible(ptm->pdata)) || > + (attr == &dev_attr_t3.attr && ptm->ops->t3_visible && > + ptm->ops->t3_visible(ptm->pdata)) || > + (attr == &dev_attr_t4.attr && ptm->ops->t4_visible && > + ptm->ops->t4_visible(ptm->pdata)) || > + (attr == &dev_attr_local_clock.attr && > + ptm->ops->local_clock_visible && > + ptm->ops->local_clock_visible(ptm->pdata)) || > + (attr == &dev_attr_master_clock.attr && > + ptm->ops->master_clock_visible && > + ptm->ops->master_clock_visible(ptm->pdata)) || > + (attr == &dev_attr_context_update.attr && > + ptm->ops->context_update_visible && > + ptm->ops->context_update_visible(ptm->pdata)) || > + (attr == &dev_attr_context_valid.attr && > + ptm->ops->context_valid_visible && > + ptm->ops->context_valid_visible(ptm->pdata))) > + return attr->mode; > + > + return 0; > +} > + > +static const struct attribute_group pcie_ptm_attr_group = { > + .attrs = pcie_ptm_attrs, > + .is_visible = pcie_ptm_attr_visible, > +}; > + > +static const struct attribute_group *pcie_ptm_attr_groups[] = { > + &pcie_ptm_attr_group, > + NULL, > +}; > + > +static void pcie_ptm_release(struct device *dev) > +{ > + struct pcie_ptm *ptm = container_of(dev, struct pcie_ptm, dev); > + > + kfree(ptm); > +} > + > +/* > + * pcie_ptm_create_sysfs() - Create sysfs entries for the PTM context > + * @dev: PTM capable component device > + * @pdata: Private data of the PTM capable component device > + * @ops: PTM callback structure > + * > + * Create sysfs entries for exposing the PTM context of the PTM capable > + * components such as Root Complex and Endpoint controllers. > + */ > +int pcie_ptm_create_sysfs(struct device *dev, void *pdata, > + struct pcie_ptm_ops *ops) > +{ > + struct pcie_ptm *ptm; > + int ret; > + > + /* Caller must provide check_capability() callback */ > + if (!ops->check_capability) > + return -EINVAL; > + > + /* Check for PTM capability before creating sysfs attrbutes */ > + ret = ops->check_capability(pdata); > + if (!ret) { > + dev_dbg(dev, "PTM capability not present\n"); > + return -ENODATA; > + } > + > + ptm = kzalloc(sizeof(*ptm), GFP_KERNEL); > + if (!ptm) > + return -ENOMEM; > + > + ptm->pdata = pdata; > + ptm->ops = ops; > + > + device_initialize(&ptm->dev); > + ptm->dev.groups = pcie_ptm_attr_groups; > + ptm->dev.release = pcie_ptm_release; > + ptm->dev.parent = dev; > + dev_set_drvdata(&ptm->dev, ptm); > + device_set_pm_not_required(&ptm->dev); > + > + ret = dev_set_name(&ptm->dev, "ptm"); > + if (ret) > + goto err_put_device; > + > + ret = device_add(&ptm->dev); > + if (ret) > + goto err_put_device; > + > + ptm_device = &ptm->dev; > + > + return 0; > + > +err_put_device: > + put_device(&ptm->dev); > + > + return ret; > +} > +EXPORT_SYMBOL(pci_ptm_init); > + > +/* > + * pcie_ptm_destroy_sysfs() - Destroy sysfs entries for the PTM context > + */ > +void pcie_ptm_destroy_sysfs(void) > +{ > + if (ptm_device) { > + device_unregister(ptm_device); > + ptm_device = NULL; > + } > +} > +EXPORT_SYMBOL(pcie_ptm_destroy_sysfs); > diff --git a/include/linux/pci.h b/include/linux/pci.h > index 47b31ad724fa5bf7abd7c3dc572947551b0f2148..42bb3cf0212e96fd65a1f01410ef70c82491c9eb 100644 > --- a/include/linux/pci.h > +++ b/include/linux/pci.h > @@ -1857,16 +1857,51 @@ static inline bool pci_aer_available(void) { return false; } > > bool pci_ats_disabled(void); > > +struct pcie_ptm_ops { > + int (*check_capability)(void *drvdata); > + int (*context_update_store)(void *drvdata, const char *buf); > + ssize_t (*context_update_show)(void *drvdata, char *buf); > + int (*context_valid_store)(void *drvdata, bool valid); > + ssize_t (*context_valid_show)(void *drvdata, char *buf); > + ssize_t (*local_clock_show)(void *drvdata, char *buf); > + ssize_t (*master_clock_show)(void *drvdata, char *buf); > + ssize_t (*t1_show)(void *drvdata, char *buf); > + ssize_t (*t2_show)(void *drvdata, char *buf); > + ssize_t (*t3_show)(void *drvdata, char *buf); > + ssize_t (*t4_show)(void *drvdata, char *buf); > + > + bool (*context_update_visible)(void *drvdata); > + bool (*context_valid_visible)(void *drvdata); > + bool (*local_clock_visible)(void *drvdata); > + bool (*master_clock_visible)(void *drvdata); > + bool (*t1_visible)(void *drvdata); > + bool (*t2_visible)(void *drvdata); > + bool (*t3_visible)(void *drvdata); > + bool (*t4_visible)(void *drvdata); > +}; > + > +struct pcie_ptm { > + struct device dev; > + struct pcie_ptm_ops *ops; > + void *pdata; > +}; > + > #ifdef CONFIG_PCIE_PTM > int pci_enable_ptm(struct pci_dev *dev, u8 *granularity); > void pci_disable_ptm(struct pci_dev *dev); > bool pcie_ptm_enabled(struct pci_dev *dev); > +int pcie_ptm_create_sysfs(struct device *dev, void *pdata, struct pcie_ptm_ops *ops); > +void pcie_ptm_destroy_sysfs(void); > #else > static inline int pci_enable_ptm(struct pci_dev *dev, u8 *granularity) > { return -EINVAL; } > static inline void pci_disable_ptm(struct pci_dev *dev) { } > static inline bool pcie_ptm_enabled(struct pci_dev *dev) > { return false; } > +static inline int pcie_ptm_create_sysfs(struct device *dev, void *pdata, > + struct pcie_ptm_ops *ops) > +{ return 0; } > +static inline void pcie_ptm_destroy_sysfs(void) { } > #endif > > void pci_cfg_access_lock(struct pci_dev *dev); > > ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] PCI: Add sysfs support for exposing PTM context 2025-03-24 13:01 ` Ilpo Järvinen @ 2025-04-07 7:36 ` Manivannan Sadhasivam 0 siblings, 0 replies; 12+ messages in thread From: Manivannan Sadhasivam @ 2025-04-07 7:36 UTC (permalink / raw) To: Ilpo Järvinen Cc: Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Jingoo Han, linux-pci, linux-kernel, linux-arm-msm On Mon, Mar 24, 2025 at 03:01:49PM +0200, Ilpo Järvinen wrote: > On Mon, 24 Mar 2025, Manivannan Sadhasivam via B4 Relay wrote: > > > From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > > > > Precision Time Management (PTM) mechanism defined in PCIe spec r6.0, > > sec 6.22 allows precise coordination of timing information across multiple > > components in a PCIe hierarchy with independent local time clocks. > > Hi Mani, > > PCIe r6.0.1 sec 6.22 is about Readiness Notification (RN) and PTM is 6.21, > did you perhaps mistype the section number? > Oops, yeah. I referred the PCIe 5.0 spec, but mistakenly quoted 6.0. Will fix it. > > PCI core already supports enabling PTM in the root port and endpoint > > devices through PTM Extended Capability registers. But the PTM context > > supported by the PTM capable components such as Root Complex (RC) and > > Endpoint (EP) controllers were not exposed as of now. > > > > Hence, add the sysfs support to expose the PTM context to userspace from > > both PCIe RC and EP controllers. Controller drivers are expected to call > > pcie_ptm_create_sysfs() to create the sysfs attributes for the PTM context > > and call pcie_ptm_destroy_sysfs() to destroy them. The drivers should also > > populate the relevant callbacks in the 'struct pcie_ptm_ops' structure > > based on the controller implementation. > > > > Below PTM context are exposed through sysfs: > > > > PCIe RC > > ======= > > > > 1. PTM Local clock > > 2. PTM T2 timestamp > > 3. PTM T3 timestamp > > 4. PTM Context valid > > > > PCIe EP > > ======= > > > > 1. PTM Local clock > > 2. PTM T1 timestamp > > 3. PTM T4 timestamp > > 4. PTM Master clock > > 5. PTM Context update > > > > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > > --- > > Documentation/ABI/testing/sysfs-platform-pcie-ptm | 70 ++++++ > > MAINTAINERS | 1 + > > drivers/pci/pcie/ptm.c | 268 ++++++++++++++++++++++ > > include/linux/pci.h | 35 +++ > > 4 files changed, 374 insertions(+) > > > > diff --git a/Documentation/ABI/testing/sysfs-platform-pcie-ptm b/Documentation/ABI/testing/sysfs-platform-pcie-ptm > > new file mode 100644 > > index 0000000000000000000000000000000000000000..010c3e32e2b8eaf352a8e1aad7420d8a3e948dae > > --- /dev/null > > +++ b/Documentation/ABI/testing/sysfs-platform-pcie-ptm > > @@ -0,0 +1,70 @@ > > +What: /sys/devices/platform/*/ptm/local_clock > > +Date: February 2025 > > +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > > +Description: > > + (RO) PTM local clock in nanoseconds. Applicable for both Root > > + Complex and Endpoint controllers. > > + > > +What: /sys/devices/platform/*/ptm/master_clock > > +Date: February 2025 > > +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > > +Description: > > + (RO) PTM master clock in nanoseconds. Applicable only for > > + Endpoint controllers. > > + > > +What: /sys/devices/platform/*/ptm/t1 > > +Date: February 2025 > > +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > > +Description: > > + (RO) PTM T1 timestamp in nanoseconds. Applicable only for > > + Endpoint controllers. > > + > > +What: /sys/devices/platform/*/ptm/t2 > > +Date: February 2025 > > +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > > +Description: > > + (RO) PTM T2 timestamp in nanoseconds. Applicable only for > > + Root Complex controllers. > > + > > +What: /sys/devices/platform/*/ptm/t3 > > +Date: February 2025 > > +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > > +Description: > > + (RO) PTM T3 timestamp in nanoseconds. Applicable only for > > + Root Complex controllers. > > + > > +What: /sys/devices/platform/*/ptm/t4 > > +Date: February 2025 > > +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > > +Description: > > + (RO) PTM T4 timestamp in nanoseconds. Applicable only for > > + Endpoint controllers. > > + > > +What: /sys/devices/platform/*/ptm/context_update > > +Date: February 2025 > > +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > > +Description: > > + (RW) Control the PTM context update mode. Applicable only for > > + Endpoint controllers. > > + > > + Following values are supported: > > + > > + * auto = PTM context auto update trigger for every 10ms > > + > > + * manual = PTM context manual update. Writing 'manual' to this > > + file triggers PTM context update (default) > > + > > +What: /sys/devices/platform/*/ptm/context_valid > > +Date: February 2025 > > +Contact: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > > +Description: > > + (RW) Control the PTM context validity (local clock timing). > > + Applicable only for Root Complex controllers. PTM context is > > + invalidated by hardware if the Root Complex enters low power > > + mode or changes link frequency. > > + > > + Following values are supported: > > + > > + * 0 = PTM context invalid (default) > > + > > + * 1 = PTM context valid > > diff --git a/MAINTAINERS b/MAINTAINERS > > index b4d09d52a750b320f689c1365791cdfa6e719fde..f1bac092877df739328347481bd14f6701a7df19 100644 > > --- a/MAINTAINERS > > +++ b/MAINTAINERS > > @@ -18213,6 +18213,7 @@ Q: https://patchwork.kernel.org/project/linux-pci/list/ > > B: https://bugzilla.kernel.org > > C: irc://irc.oftc.net/linux-pci > > T: git git://git.kernel.org/pub/scm/linux/kernel/git/pci/pci.git > > +F: Documentation/ABI/testing/sysfs-platform-pcie-ptm > > F: Documentation/devicetree/bindings/pci/ > > F: drivers/pci/controller/ > > F: drivers/pci/pci-bridge-emul.c > > diff --git a/drivers/pci/pcie/ptm.c b/drivers/pci/pcie/ptm.c > > index 7cfb6c0d5dcb6de2a759b56d6877c95102b3d10f..bfa632b76a87ad304e966a8edfb5dba14d58a23c 100644 > > --- a/drivers/pci/pcie/ptm.c > > +++ b/drivers/pci/pcie/ptm.c > > @@ -10,6 +10,8 @@ > > #include <linux/pci.h> > > #include "../pci.h" > > > > +struct device *ptm_device; > > + > > /* > > * If the next upstream device supports PTM, return it; otherwise return > > * NULL. PTM Messages are local, so both link partners must support it. > > @@ -252,3 +254,269 @@ bool pcie_ptm_enabled(struct pci_dev *dev) > > return dev->ptm_enabled; > > } > > EXPORT_SYMBOL(pcie_ptm_enabled); > > + > > +static ssize_t context_update_store(struct device *dev, > > + struct device_attribute *attr, > > + const char *buf, size_t count) > > +{ > > + struct pcie_ptm *ptm = dev_get_drvdata(dev); > > + int ret; > > + > > + if (!ptm->ops->context_update_store) > > + return -EOPNOTSUPP; > > + > > + ret = ptm->ops->context_update_store(ptm->pdata, buf); > > Do these store funcs need some locking? Who is responsible about it? > Good catch! I obviously missed the locking here. > Why isn't buf parsed here and converted to some define/enum values, what > is the advantage of passing it on as char *? > Only because I was not sure if the values are going to be the same across all implementations. But since I document 'auto' and 'manual' in ABI documentation, I think it makes sense to pass the values directly. - Mani -- மணிவண்ணன் சதாசிவம் ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] PCI: Add sysfs support for exposing PTM context 2025-03-24 10:04 ` [PATCH v2 1/3] PCI: Add sysfs support for exposing PTM context Manivannan Sadhasivam via B4 Relay 2025-03-24 13:01 ` Ilpo Järvinen @ 2025-03-24 16:28 ` Bjorn Helgaas 2025-04-07 7:44 ` Manivannan Sadhasivam 2025-03-26 21:18 ` kernel test robot 2 siblings, 1 reply; 12+ messages in thread From: Bjorn Helgaas @ 2025-03-24 16:28 UTC (permalink / raw) To: manivannan.sadhasivam Cc: Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Jingoo Han, linux-pci, linux-kernel, linux-arm-msm On Mon, Mar 24, 2025 at 03:34:35PM +0530, Manivannan Sadhasivam via B4 Relay wrote: > From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > > Precision Time Management (PTM) mechanism defined in PCIe spec r6.0, > sec 6.22 allows precise coordination of timing information across multiple > components in a PCIe hierarchy with independent local time clocks. > > PCI core already supports enabling PTM in the root port and endpoint > devices through PTM Extended Capability registers. But the PTM context > supported by the PTM capable components such as Root Complex (RC) and > Endpoint (EP) controllers were not exposed as of now. > > Hence, add the sysfs support to expose the PTM context to userspace from > both PCIe RC and EP controllers. Controller drivers are expected to call > pcie_ptm_create_sysfs() to create the sysfs attributes for the PTM context > and call pcie_ptm_destroy_sysfs() to destroy them. The drivers should also > populate the relevant callbacks in the 'struct pcie_ptm_ops' structure > based on the controller implementation. Can we include some motivation here, e.g., what is the value of exposing this information? Is this for debugging or bringup purposes? Can users or administrators use this for something? Obviously they can read and update some internal PTM state, but it would be nice to know what that's good for. It looks like this requires device-specific support, i.e., the context itself, context update modes, access to the clock values, etc., is not specified by the generic PCIe spec. Consequently this probably can't be done by generic drivers like ACPI, and maybe this is a candidate for debugfs instead of sysfs. The merge window is open now, so this will be v6.16 material, so no hurry about updating before v6.15-rc1. Bjorn ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] PCI: Add sysfs support for exposing PTM context 2025-03-24 16:28 ` Bjorn Helgaas @ 2025-04-07 7:44 ` Manivannan Sadhasivam 2025-04-07 16:53 ` Bjorn Helgaas 0 siblings, 1 reply; 12+ messages in thread From: Manivannan Sadhasivam @ 2025-04-07 7:44 UTC (permalink / raw) To: Bjorn Helgaas Cc: Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Jingoo Han, linux-pci, linux-kernel, linux-arm-msm On Mon, Mar 24, 2025 at 11:28:54AM -0500, Bjorn Helgaas wrote: > On Mon, Mar 24, 2025 at 03:34:35PM +0530, Manivannan Sadhasivam via B4 Relay wrote: > > From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > > > > Precision Time Management (PTM) mechanism defined in PCIe spec r6.0, > > sec 6.22 allows precise coordination of timing information across multiple > > components in a PCIe hierarchy with independent local time clocks. > > > > PCI core already supports enabling PTM in the root port and endpoint > > devices through PTM Extended Capability registers. But the PTM context > > supported by the PTM capable components such as Root Complex (RC) and > > Endpoint (EP) controllers were not exposed as of now. > > > > Hence, add the sysfs support to expose the PTM context to userspace from > > both PCIe RC and EP controllers. Controller drivers are expected to call > > pcie_ptm_create_sysfs() to create the sysfs attributes for the PTM context > > and call pcie_ptm_destroy_sysfs() to destroy them. The drivers should also > > populate the relevant callbacks in the 'struct pcie_ptm_ops' structure > > based on the controller implementation. > > Can we include some motivation here, e.g., what is the value of > exposing this information? Is this for debugging or bringup purposes? > Can users or administrators use this for something? Obviously they > can read and update some internal PTM state, but it would be nice to > know what that's good for. > This was a request from one of the Qualcomm customers, but they didn't share how they are using these context. They just said that they want to collect the PTM timestamps for comparing with PTP timestamps from a different PCIe switch. That was not a worth of information to be mentioned in the cover letter, so I skipped it intentionally. Also, the spec itself didn't mention any specific usecases unfortunately. > It looks like this requires device-specific support, i.e., the context > itself, context update modes, access to the clock values, etc., is not > specified by the generic PCIe spec. Right. > Consequently this probably can't > be done by generic drivers like ACPI, and maybe this is a candidate > for debugfs instead of sysfs. > Well, we can still create syfs ABI for vendor specific features. Problem with debugfs is that the customers cannot use debugfs in a production environment. Moreover, I cannot strictly classify PTM context as a debugging information. - Mani -- மணிவண்ணன் சதாசிவம் ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] PCI: Add sysfs support for exposing PTM context 2025-04-07 7:44 ` Manivannan Sadhasivam @ 2025-04-07 16:53 ` Bjorn Helgaas 0 siblings, 0 replies; 12+ messages in thread From: Bjorn Helgaas @ 2025-04-07 16:53 UTC (permalink / raw) To: Manivannan Sadhasivam Cc: Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Jingoo Han, linux-pci, linux-kernel, linux-arm-msm On Mon, Apr 07, 2025 at 01:14:56PM +0530, Manivannan Sadhasivam wrote: > On Mon, Mar 24, 2025 at 11:28:54AM -0500, Bjorn Helgaas wrote: > > On Mon, Mar 24, 2025 at 03:34:35PM +0530, Manivannan Sadhasivam via B4 Relay wrote: > > > From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> > > > > > > Precision Time Management (PTM) mechanism defined in PCIe spec > > > r6.0, sec 6.22 allows precise coordination of timing information > > > across multiple components in a PCIe hierarchy with independent > > > local time clocks. > > > > > > PCI core already supports enabling PTM in the root port and > > > endpoint devices through PTM Extended Capability registers. But > > > the PTM context supported by the PTM capable components such as > > > Root Complex (RC) and Endpoint (EP) controllers were not exposed > > > as of now. > > > > > > Hence, add the sysfs support to expose the PTM context to > > > userspace from both PCIe RC and EP controllers. Controller > > > drivers are expected to call pcie_ptm_create_sysfs() to create > > > the sysfs attributes for the PTM context and call > > > pcie_ptm_destroy_sysfs() to destroy them. The drivers should > > > also populate the relevant callbacks in the 'struct > > > pcie_ptm_ops' structure based on the controller implementation. > > > > Can we include some motivation here, e.g., what is the value of > > exposing this information? Is this for debugging or bringup > > purposes? Can users or administrators use this for something? > > Obviously they can read and update some internal PTM state, but it > > would be nice to know what that's good for. > > This was a request from one of the Qualcomm customers, but they > didn't share how they are using these context. They just said that > they want to collect the PTM timestamps for comparing with PTP > timestamps from a different PCIe switch. That was not a worth of > information to be mentioned in the cover letter, so I skipped it > intentionally. I think it is important to include a reason for merging a change. The mere fact that information exists is not enough reason to expose it as a sysfs ABI. > > Consequently this probably can't be done by generic drivers like > > ACPI, and maybe this is a candidate for debugfs instead of sysfs. > > Well, we can still create sysfs ABI for vendor specific features. > Problem with debugfs is that the customers cannot use debugfs in a > production environment. Moreover, I cannot strictly classify PTM > context as a debugging information. I'm not convinced about making sysfs ABI for vendor-specific features. I see that we do have a few existing things like this: Documentation/ABI/testing/sysfs-bus-pci-drivers-janz-cmodio Documentation/ABI/testing/sysfs-bus-pci-devices-cciss Documentation/ABI/testing/sysfs-bus-pci-devices-avs but I'm a bit hesitant to extend this model. Bjorn ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 1/3] PCI: Add sysfs support for exposing PTM context 2025-03-24 10:04 ` [PATCH v2 1/3] PCI: Add sysfs support for exposing PTM context Manivannan Sadhasivam via B4 Relay 2025-03-24 13:01 ` Ilpo Järvinen 2025-03-24 16:28 ` Bjorn Helgaas @ 2025-03-26 21:18 ` kernel test robot 2 siblings, 0 replies; 12+ messages in thread From: kernel test robot @ 2025-03-26 21:18 UTC (permalink / raw) To: Manivannan Sadhasivam via B4 Relay, Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Jingoo Han Cc: oe-kbuild-all, linux-pci, linux-kernel, linux-arm-msm, Manivannan Sadhasivam Hi Manivannan, kernel test robot noticed the following build warnings: [auto build test WARNING on 1f5a69f1b3132054d8d82b8d7546d0af6a2ed4f6] url: https://github.com/intel-lab-lkp/linux/commits/Manivannan-Sadhasivam-via-B4-Relay/PCI-Add-sysfs-support-for-exposing-PTM-context/20250324-181039 base: 1f5a69f1b3132054d8d82b8d7546d0af6a2ed4f6 patch link: https://lore.kernel.org/r/20250324-pcie-ptm-v2-1-c7d8c3644b4a%40linaro.org patch subject: [PATCH v2 1/3] PCI: Add sysfs support for exposing PTM context config: i386-randconfig-061-20250326 (https://download.01.org/0day-ci/archive/20250327/202503270447.SYoXEBQd-lkp@intel.com/config) compiler: gcc-11 (Debian 11.3.0-12) 11.3.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250327/202503270447.SYoXEBQd-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202503270447.SYoXEBQd-lkp@intel.com/ sparse warnings: (new ones prefixed by >>) >> drivers/pci/pcie/ptm.c:13:15: sparse: sparse: symbol 'ptm_device' was not declared. Should it be static? vim +/ptm_device +13 drivers/pci/pcie/ptm.c 12 > 13 struct device *ptm_device; 14 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 2/3] PCI: dwc: Add sysfs support for PTM context 2025-03-24 10:04 [PATCH v2 0/3] PCI: Add PTM sysfs support Manivannan Sadhasivam via B4 Relay 2025-03-24 10:04 ` [PATCH v2 1/3] PCI: Add sysfs support for exposing PTM context Manivannan Sadhasivam via B4 Relay @ 2025-03-24 10:04 ` Manivannan Sadhasivam via B4 Relay 2025-03-24 14:06 ` kernel test robot 2025-03-26 21:42 ` kernel test robot 2025-03-24 10:04 ` [PATCH v2 3/3] PCI: qcom-ep: Mask PTM_UPDATING interrupt Manivannan Sadhasivam via B4 Relay 2 siblings, 2 replies; 12+ messages in thread From: Manivannan Sadhasivam via B4 Relay @ 2025-03-24 10:04 UTC (permalink / raw) To: Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Jingoo Han Cc: linux-pci, linux-kernel, linux-arm-msm, Manivannan Sadhasivam From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> Synopsys Designware PCIe IPs support PTM capability as defined in the PCIe spec r6.0, sec 6.22. The PTM context information is exposed through Vendor Specific Extended Capability (VSEC) registers on supported controller implementation. Hence, add support for exposing these context information to userspace through the sysfs interface for the DWC controllers (both RC and EP). Currently, only Qcom controllers are supported. For adding support for DWC vendor controllers, dwc_pcie_ptm_vsec_ids[] needs to be extended. Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> --- drivers/pci/controller/dwc/Makefile | 2 +- drivers/pci/controller/dwc/pcie-designware-ep.c | 3 + drivers/pci/controller/dwc/pcie-designware-host.c | 3 + drivers/pci/controller/dwc/pcie-designware-sysfs.c | 254 +++++++++++++++++++++ drivers/pci/controller/dwc/pcie-designware.c | 6 + drivers/pci/controller/dwc/pcie-designware.h | 21 ++ include/linux/pcie-dwc.h | 8 + 7 files changed, 296 insertions(+), 1 deletion(-) diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile index 54565eedc52cc36bc393e257d093c4671aff7b39..ca7c1ff7a6807bf0aec24778dc10c02c7e8680c7 100644 --- a/drivers/pci/controller/dwc/Makefile +++ b/drivers/pci/controller/dwc/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_PCIE_DW) += pcie-designware.o +obj-$(CONFIG_PCIE_DW) += pcie-designware.o pcie-designware-sysfs.o obj-$(CONFIG_PCIE_DW_DEBUGFS) += pcie-designware-debugfs.o obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c b/drivers/pci/controller/dwc/pcie-designware-ep.c index 5a6174e107c20c897cfa142687e219c5ecafb8c6..d1a07cebc4c21f1a81048730bcf40fa8e1dba0b1 100644 --- a/drivers/pci/controller/dwc/pcie-designware-ep.c +++ b/drivers/pci/controller/dwc/pcie-designware-ep.c @@ -705,6 +705,7 @@ void dw_pcie_ep_cleanup(struct dw_pcie_ep *ep) { struct dw_pcie *pci = to_dw_pcie_from_ep(ep); + pcie_designware_sysfs_exit(pci); dwc_pcie_debugfs_deinit(pci); dw_pcie_edma_remove(pci); } @@ -880,6 +881,8 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep) dwc_pcie_debugfs_init(pci); + pcie_designware_sysfs_init(pci, DW_PCIE_EP_TYPE); + return 0; err_remove_edma: diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c index 6501fb062c70e56eb301ca71fcd642f7be33a252..faaabc5446ebde5adcdf5ab03e0cf3569636b79b 100644 --- a/drivers/pci/controller/dwc/pcie-designware-host.c +++ b/drivers/pci/controller/dwc/pcie-designware-host.c @@ -550,6 +550,8 @@ int dw_pcie_host_init(struct dw_pcie_rp *pp) dwc_pcie_debugfs_init(pci); + pcie_designware_sysfs_init(pci, DW_PCIE_RC_TYPE); + return 0; err_stop_link: @@ -574,6 +576,7 @@ void dw_pcie_host_deinit(struct dw_pcie_rp *pp) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + pcie_designware_sysfs_exit(pci); dwc_pcie_debugfs_deinit(pci); pci_stop_root_bus(pp->bridge->bus); diff --git a/drivers/pci/controller/dwc/pcie-designware-sysfs.c b/drivers/pci/controller/dwc/pcie-designware-sysfs.c new file mode 100644 index 0000000000000000000000000000000000000000..1723444e408c90dee0c8d0b526c6887969451d6c --- /dev/null +++ b/drivers/pci/controller/dwc/pcie-designware-sysfs.c @@ -0,0 +1,254 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2025 Linaro Ltd. + * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> + */ + +#include <linux/device.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/slab.h> + +#include "pcie-designware.h" + +static int dw_pcie_ptm_check_capability(void *drvdata) +{ + struct dw_pcie *pci = drvdata; + + pci->ptm_vsec_offset = dw_pcie_find_ptm_capability(pci); + + return pci->ptm_vsec_offset; +} + +static int dw_pcie_ptm_context_update_store(void *drvdata, const char *buf) +{ + struct dw_pcie *pci = drvdata; + u32 val; + + if (sysfs_streq(buf, "auto")) { + val = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL); + val |= PTM_REQ_AUTO_UPDATE_ENABLED; + dw_pcie_writel_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL, val); + } else if (sysfs_streq(buf, "manual")) { + val = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL); + val &= ~PTM_REQ_AUTO_UPDATE_ENABLED; + val |= PTM_REQ_START_UPDATE; + dw_pcie_writel_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL, val); + } else { + return -EINVAL; + } + + return 0; +} + +static ssize_t dw_pcie_ptm_context_update_show(void *drvdata, char *buf) +{ + struct dw_pcie *pci = drvdata; + u32 val; + + val = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL); + if (FIELD_GET(PTM_REQ_AUTO_UPDATE_ENABLED, val)) + return sysfs_emit(buf, "auto\n"); + + /* + * PTM_REQ_START_UPDATE is a self clearing register bit. So if + * PTM_REQ_AUTO_UPDATE_ENABLED is not set, then it implies that + * manual update is used. + */ + return sysfs_emit(buf, "manual\n"); +} + +static int dw_pcie_ptm_context_valid_store(void *drvdata, bool valid) +{ + struct dw_pcie *pci = drvdata; + u32 val; + + if (valid) { + val = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL); + val |= PTM_RES_CCONTEXT_VALID; + dw_pcie_writel_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL, val); + } else { + val = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL); + val &= ~PTM_RES_CCONTEXT_VALID; + dw_pcie_writel_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL, val); + } + + return 0; +} + +static ssize_t dw_pcie_ptm_context_valid_show(void *drvdata, char *buf) +{ + struct dw_pcie *pci = drvdata; + u32 val; + + val = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_RES_REQ_CTRL); + + return sysfs_emit(buf, "%u\n", !!FIELD_GET(PTM_RES_CCONTEXT_VALID, val)); +} + +static ssize_t dw_pcie_ptm_local_clock_show(void *drvdata, char *buf) +{ + struct dw_pcie *pci = drvdata; + u32 msb, lsb; + + do { + msb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_LOCAL_MSB); + lsb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_LOCAL_LSB); + } while (msb != dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_LOCAL_MSB)); + + return sysfs_emit(buf, "%llu\n", ((u64) msb) << 32 | lsb); +} + +static ssize_t dw_pcie_ptm_master_clock_show(void *drvdata, char *buf) +{ + struct dw_pcie *pci = drvdata; + u32 msb, lsb; + + do { + msb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_MASTER_MSB); + lsb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_MASTER_LSB); + } while (msb != dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_MASTER_MSB)); + + return sysfs_emit(buf, "%llu\n", ((u64) msb) << 32 | lsb); +} + +static ssize_t dw_pcie_ptm_t1_show(void *drvdata, char *buf) +{ + struct dw_pcie *pci = drvdata; + u32 msb, lsb; + + do { + msb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T1_T2_MSB); + lsb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T1_T2_LSB); + } while (msb != dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T1_T2_MSB)); + + return sysfs_emit(buf, "%llu\n", ((u64) msb) << 32 | lsb); +} + +static ssize_t dw_pcie_ptm_t2_show(void *drvdata, char *buf) +{ + struct dw_pcie *pci = drvdata; + u32 msb, lsb; + + do { + msb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T1_T2_MSB); + lsb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T1_T2_LSB); + } while (msb != dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T1_T2_MSB)); + + return sysfs_emit(buf, "%llu\n", ((u64) msb) << 32 | lsb); +} + +static ssize_t dw_pcie_ptm_t3_show(void *drvdata, char *buf) +{ + struct dw_pcie *pci = drvdata; + u32 msb, lsb; + + do { + msb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T3_T4_MSB); + lsb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T3_T4_LSB); + } while (msb != dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T3_T4_MSB)); + + return sysfs_emit(buf, "%llu\n", ((u64) msb) << 32 | lsb); +} + +static ssize_t dw_pcie_ptm_t4_show(void *drvdata, char *buf) +{ + struct dw_pcie *pci = drvdata; + u32 msb, lsb; + + do { + msb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T3_T4_MSB); + lsb = dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T3_T4_LSB); + } while (msb != dw_pcie_readl_dbi(pci, pci->ptm_vsec_offset + PTM_T3_T4_MSB)); + + return sysfs_emit(buf, "%llu\n", ((u64) msb) << 32 | lsb); +} + +static bool dw_pcie_ptm_context_update_visible(void *drvdata) +{ + struct dw_pcie *pci = drvdata; + + return (pci->mode == DW_PCIE_EP_TYPE) ? true : false; +} + +static bool dw_pcie_ptm_context_valid_visible(void *drvdata) +{ + struct dw_pcie *pci = drvdata; + + return (pci->mode == DW_PCIE_RC_TYPE) ? true : false; +} + +static bool dw_pcie_ptm_local_clock_visible(void *drvdata) +{ + /* PTM local clock is always visible */ + return true; +} + +static bool dw_pcie_ptm_master_clock_visible(void *drvdata) +{ + struct dw_pcie *pci = drvdata; + + return (pci->mode == DW_PCIE_EP_TYPE) ? true : false; +} + +static bool dw_pcie_ptm_t1_visible(void *drvdata) +{ + struct dw_pcie *pci = drvdata; + + return (pci->mode == DW_PCIE_EP_TYPE) ? true : false; +} + +static bool dw_pcie_ptm_t2_visible(void *drvdata) +{ + struct dw_pcie *pci = drvdata; + + return (pci->mode == DW_PCIE_RC_TYPE) ? true : false; +} + +static bool dw_pcie_ptm_t3_visible(void *drvdata) +{ + struct dw_pcie *pci = drvdata; + + return (pci->mode == DW_PCIE_RC_TYPE) ? true : false; +} + +static bool dw_pcie_ptm_t4_visible(void *drvdata) +{ + struct dw_pcie *pci = drvdata; + + return (pci->mode == DW_PCIE_EP_TYPE) ? true : false; +} + +struct pcie_ptm_ops dw_pcie_ptm_ops = { + .check_capability = dw_pcie_ptm_check_capability, + .context_update_store = dw_pcie_ptm_context_update_store, + .context_update_show = dw_pcie_ptm_context_update_show, + .context_valid_store = dw_pcie_ptm_context_valid_store, + .context_valid_show = dw_pcie_ptm_context_valid_show, + .local_clock_show = dw_pcie_ptm_local_clock_show, + .master_clock_show = dw_pcie_ptm_master_clock_show, + .t1_show = dw_pcie_ptm_t1_show, + .t2_show = dw_pcie_ptm_t2_show, + .t3_show = dw_pcie_ptm_t3_show, + .t4_show = dw_pcie_ptm_t4_show, + .context_update_visible = dw_pcie_ptm_context_update_visible, + .context_valid_visible = dw_pcie_ptm_context_valid_visible, + .local_clock_visible = dw_pcie_ptm_local_clock_visible, + .master_clock_visible = dw_pcie_ptm_master_clock_visible, + .t1_visible = dw_pcie_ptm_t1_visible, + .t2_visible = dw_pcie_ptm_t2_visible, + .t3_visible = dw_pcie_ptm_t3_visible, + .t4_visible = dw_pcie_ptm_t4_visible, +}; + +void pcie_designware_sysfs_init(struct dw_pcie *pci, + enum dw_pcie_device_mode mode) +{ + pci->mode = mode; + pcie_ptm_create_sysfs(pci->dev, pci, &dw_pcie_ptm_ops); +} + +void pcie_designware_sysfs_exit(struct dw_pcie *pci) +{ + pcie_ptm_destroy_sysfs(); +} diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c index 3d1d95d9e38057dd1389e2d57d701ce4f4fa6f7f..1e858c15991f0f87e0711b9a9eec9c44d43fef4b 100644 --- a/drivers/pci/controller/dwc/pcie-designware.c +++ b/drivers/pci/controller/dwc/pcie-designware.c @@ -329,6 +329,12 @@ u16 dw_pcie_find_rasdes_capability(struct dw_pcie *pci) } EXPORT_SYMBOL_GPL(dw_pcie_find_rasdes_capability); +u16 dw_pcie_find_ptm_capability(struct dw_pcie *pci) +{ + return dw_pcie_find_vsec_capability(pci, dwc_pcie_ptm_vsec_ids); +} +EXPORT_SYMBOL_GPL(dw_pcie_find_ptm_capability); + int dw_pcie_read(void __iomem *addr, int size, u32 *val) { if (!IS_ALIGNED((uintptr_t)addr, size)) { diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h index 2d1de81d47b67fc0df941484b1d92d986b2b4dbd..27a729b9c13f17dd635bc2976a0b5d4c7aeff5f9 100644 --- a/drivers/pci/controller/dwc/pcie-designware.h +++ b/drivers/pci/controller/dwc/pcie-designware.h @@ -260,6 +260,21 @@ #define PCIE_RAS_DES_EVENT_COUNTER_DATA 0xc +/* PTM register definitions */ +#define PTM_RES_REQ_CTRL 0x8 +#define PTM_RES_CCONTEXT_VALID BIT(0) +#define PTM_REQ_AUTO_UPDATE_ENABLED BIT(0) +#define PTM_REQ_START_UPDATE BIT(1) + +#define PTM_LOCAL_LSB 0x10 +#define PTM_LOCAL_MSB 0x14 +#define PTM_T1_T2_LSB 0x18 +#define PTM_T1_T2_MSB 0x1c +#define PTM_T3_T4_LSB 0x28 +#define PTM_T3_T4_MSB 0x2c +#define PTM_MASTER_LSB 0x38 +#define PTM_MASTER_MSB 0x3c + /* * The default address offset between dbi_base and atu_base. Root controller * drivers are not required to initialize atu_base if the offset matches this @@ -500,6 +515,8 @@ struct dw_pcie { struct reset_control_bulk_data app_rsts[DW_PCIE_NUM_APP_RSTS]; struct reset_control_bulk_data core_rsts[DW_PCIE_NUM_CORE_RSTS]; struct gpio_desc *pe_rst; + u16 ptm_vsec_offset; + enum dw_pcie_device_mode mode; bool suspended; struct debugfs_info *debugfs; }; @@ -516,6 +533,7 @@ void dw_pcie_version_detect(struct dw_pcie *pci); u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap); u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap); u16 dw_pcie_find_rasdes_capability(struct dw_pcie *pci); +u16 dw_pcie_find_ptm_capability(struct dw_pcie *pci); int dw_pcie_read(void __iomem *addr, int size, u32 *val); int dw_pcie_write(void __iomem *addr, int size, u32 val); @@ -537,6 +555,9 @@ void dw_pcie_setup(struct dw_pcie *pci); void dw_pcie_iatu_detect(struct dw_pcie *pci); int dw_pcie_edma_detect(struct dw_pcie *pci); void dw_pcie_edma_remove(struct dw_pcie *pci); +void pcie_designware_sysfs_init(struct dw_pcie *pci, + enum dw_pcie_device_mode mode); +void pcie_designware_sysfs_exit(struct dw_pcie *pci); static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val) { diff --git a/include/linux/pcie-dwc.h b/include/linux/pcie-dwc.h index 8ff778e7aec0ef60462ea69245c76a91c81b76b9..b15057fa6c0ef1794b72c9279b49787fe56302c4 100644 --- a/include/linux/pcie-dwc.h +++ b/include/linux/pcie-dwc.h @@ -35,4 +35,12 @@ static const struct dwc_pcie_vsec_id dwc_pcie_rasdes_vsec_ids[] = { {} }; +static const struct dwc_pcie_vsec_id dwc_pcie_ptm_vsec_ids[] = { + { .vendor_id = PCI_VENDOR_ID_QCOM, /* EP */ + .vsec_id = 0x03, .vsec_rev = 0x1 }, + { .vendor_id = PCI_VENDOR_ID_QCOM, /* RC */ + .vsec_id = 0x04, .vsec_rev = 0x1 }, + { } +}; + #endif /* LINUX_PCIE_DWC_H */ -- 2.43.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/3] PCI: dwc: Add sysfs support for PTM context 2025-03-24 10:04 ` [PATCH v2 2/3] PCI: dwc: Add sysfs support for " Manivannan Sadhasivam via B4 Relay @ 2025-03-24 14:06 ` kernel test robot 2025-03-26 21:42 ` kernel test robot 1 sibling, 0 replies; 12+ messages in thread From: kernel test robot @ 2025-03-24 14:06 UTC (permalink / raw) To: Manivannan Sadhasivam via B4 Relay, Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Jingoo Han Cc: oe-kbuild-all, linux-pci, linux-kernel, linux-arm-msm, Manivannan Sadhasivam Hi Manivannan, kernel test robot noticed the following build warnings: [auto build test WARNING on 1f5a69f1b3132054d8d82b8d7546d0af6a2ed4f6] url: https://github.com/intel-lab-lkp/linux/commits/Manivannan-Sadhasivam-via-B4-Relay/PCI-Add-sysfs-support-for-exposing-PTM-context/20250324-181039 base: 1f5a69f1b3132054d8d82b8d7546d0af6a2ed4f6 patch link: https://lore.kernel.org/r/20250324-pcie-ptm-v2-2-c7d8c3644b4a%40linaro.org patch subject: [PATCH v2 2/3] PCI: dwc: Add sysfs support for PTM context config: csky-randconfig-001-20250324 (https://download.01.org/0day-ci/archive/20250324/202503242112.lOewj3sy-lkp@intel.com/config) compiler: csky-linux-gcc (GCC) 14.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250324/202503242112.lOewj3sy-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202503242112.lOewj3sy-lkp@intel.com/ All warnings (new ones prefixed by >>): In file included from drivers/perf/dwc_pcie_pmu.c:16: >> include/linux/pcie-dwc.h:38:38: warning: 'dwc_pcie_ptm_vsec_ids' defined but not used [-Wunused-const-variable=] 38 | static const struct dwc_pcie_vsec_id dwc_pcie_ptm_vsec_ids[] = { | ^~~~~~~~~~~~~~~~~~~~~ vim +/dwc_pcie_ptm_vsec_ids +38 include/linux/pcie-dwc.h 37 > 38 static const struct dwc_pcie_vsec_id dwc_pcie_ptm_vsec_ids[] = { 39 { .vendor_id = PCI_VENDOR_ID_QCOM, /* EP */ 40 .vsec_id = 0x03, .vsec_rev = 0x1 }, 41 { .vendor_id = PCI_VENDOR_ID_QCOM, /* RC */ 42 .vsec_id = 0x04, .vsec_rev = 0x1 }, 43 { } 44 }; 45 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH v2 2/3] PCI: dwc: Add sysfs support for PTM context 2025-03-24 10:04 ` [PATCH v2 2/3] PCI: dwc: Add sysfs support for " Manivannan Sadhasivam via B4 Relay 2025-03-24 14:06 ` kernel test robot @ 2025-03-26 21:42 ` kernel test robot 1 sibling, 0 replies; 12+ messages in thread From: kernel test robot @ 2025-03-26 21:42 UTC (permalink / raw) To: Manivannan Sadhasivam via B4 Relay, Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Jingoo Han Cc: oe-kbuild-all, linux-pci, linux-kernel, linux-arm-msm, Manivannan Sadhasivam Hi Manivannan, kernel test robot noticed the following build warnings: [auto build test WARNING on 1f5a69f1b3132054d8d82b8d7546d0af6a2ed4f6] url: https://github.com/intel-lab-lkp/linux/commits/Manivannan-Sadhasivam-via-B4-Relay/PCI-Add-sysfs-support-for-exposing-PTM-context/20250324-181039 base: 1f5a69f1b3132054d8d82b8d7546d0af6a2ed4f6 patch link: https://lore.kernel.org/r/20250324-pcie-ptm-v2-2-c7d8c3644b4a%40linaro.org patch subject: [PATCH v2 2/3] PCI: dwc: Add sysfs support for PTM context config: i386-randconfig-062-20250326 (https://download.01.org/0day-ci/archive/20250327/202503270545.z7lzaIQz-lkp@intel.com/config) compiler: clang version 20.1.1 (https://github.com/llvm/llvm-project 424c2d9b7e4de40d0804dd374721e6411c27d1d1) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250327/202503270545.z7lzaIQz-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202503270545.z7lzaIQz-lkp@intel.com/ sparse warnings: (new ones prefixed by >>) >> drivers/pci/controller/dwc/pcie-designware-sysfs.c:222:21: sparse: sparse: symbol 'dw_pcie_ptm_ops' was not declared. Should it be static? vim +/dw_pcie_ptm_ops +222 drivers/pci/controller/dwc/pcie-designware-sysfs.c 221 > 222 struct pcie_ptm_ops dw_pcie_ptm_ops = { 223 .check_capability = dw_pcie_ptm_check_capability, 224 .context_update_store = dw_pcie_ptm_context_update_store, 225 .context_update_show = dw_pcie_ptm_context_update_show, 226 .context_valid_store = dw_pcie_ptm_context_valid_store, 227 .context_valid_show = dw_pcie_ptm_context_valid_show, 228 .local_clock_show = dw_pcie_ptm_local_clock_show, 229 .master_clock_show = dw_pcie_ptm_master_clock_show, 230 .t1_show = dw_pcie_ptm_t1_show, 231 .t2_show = dw_pcie_ptm_t2_show, 232 .t3_show = dw_pcie_ptm_t3_show, 233 .t4_show = dw_pcie_ptm_t4_show, 234 .context_update_visible = dw_pcie_ptm_context_update_visible, 235 .context_valid_visible = dw_pcie_ptm_context_valid_visible, 236 .local_clock_visible = dw_pcie_ptm_local_clock_visible, 237 .master_clock_visible = dw_pcie_ptm_master_clock_visible, 238 .t1_visible = dw_pcie_ptm_t1_visible, 239 .t2_visible = dw_pcie_ptm_t2_visible, 240 .t3_visible = dw_pcie_ptm_t3_visible, 241 .t4_visible = dw_pcie_ptm_t4_visible, 242 }; 243 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 3/3] PCI: qcom-ep: Mask PTM_UPDATING interrupt 2025-03-24 10:04 [PATCH v2 0/3] PCI: Add PTM sysfs support Manivannan Sadhasivam via B4 Relay 2025-03-24 10:04 ` [PATCH v2 1/3] PCI: Add sysfs support for exposing PTM context Manivannan Sadhasivam via B4 Relay 2025-03-24 10:04 ` [PATCH v2 2/3] PCI: dwc: Add sysfs support for " Manivannan Sadhasivam via B4 Relay @ 2025-03-24 10:04 ` Manivannan Sadhasivam via B4 Relay 2 siblings, 0 replies; 12+ messages in thread From: Manivannan Sadhasivam via B4 Relay @ 2025-03-24 10:04 UTC (permalink / raw) To: Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring, Bjorn Helgaas, Jingoo Han Cc: linux-pci, linux-kernel, linux-arm-msm, Manivannan Sadhasivam From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> When PTM is enabled, PTM_UPDATING interrupt will be fired for each PTM context update, which will be once every 10ms in the case of auto context update. Since the interrupt is not strictly needed for making use of PTM, mask it to avoid the overhead of processing it. Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> --- drivers/pci/controller/dwc/pcie-qcom-ep.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/pci/controller/dwc/pcie-qcom-ep.c b/drivers/pci/controller/dwc/pcie-qcom-ep.c index c08f64d7a825fa5da22976c8020f96ee5faa5462..940edb7be1b920840556246613f186769aca4159 100644 --- a/drivers/pci/controller/dwc/pcie-qcom-ep.c +++ b/drivers/pci/controller/dwc/pcie-qcom-ep.c @@ -60,6 +60,7 @@ #define PARF_DEVICE_TYPE 0x1000 #define PARF_BDF_TO_SID_CFG 0x2c00 #define PARF_INT_ALL_5_MASK 0x2dcc +#define PARF_INT_ALL_3_MASK 0x2e18 /* PARF_INT_ALL_{STATUS/CLEAR/MASK} register fields */ #define PARF_INT_ALL_LINK_DOWN BIT(1) @@ -132,6 +133,9 @@ /* PARF_INT_ALL_5_MASK fields */ #define PARF_INT_ALL_5_MHI_RAM_DATA_PARITY_ERR BIT(0) +/* PARF_INT_ALL_3_MASK fields */ +#define PARF_INT_ALL_3_PTM_UPDATING BIT(4) + /* ELBI registers */ #define ELBI_SYS_STTS 0x08 #define ELBI_CS2_ENABLE 0xa4 @@ -497,6 +501,10 @@ static int qcom_pcie_perst_deassert(struct dw_pcie *pci) writel_relaxed(val, pcie_ep->parf + PARF_INT_ALL_5_MASK); } + val = readl_relaxed(pcie_ep->parf + PARF_INT_ALL_3_MASK); + val &= ~PARF_INT_ALL_3_PTM_UPDATING; + writel_relaxed(val, pcie_ep->parf + PARF_INT_ALL_3_MASK); + ret = dw_pcie_ep_init_registers(&pcie_ep->pci.ep); if (ret) { dev_err(dev, "Failed to complete initialization: %d\n", ret); -- 2.43.0 ^ permalink raw reply related [flat|nested] 12+ messages in thread
end of thread, other threads:[~2025-04-07 16:53 UTC | newest] Thread overview: 12+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-03-24 10:04 [PATCH v2 0/3] PCI: Add PTM sysfs support Manivannan Sadhasivam via B4 Relay 2025-03-24 10:04 ` [PATCH v2 1/3] PCI: Add sysfs support for exposing PTM context Manivannan Sadhasivam via B4 Relay 2025-03-24 13:01 ` Ilpo Järvinen 2025-04-07 7:36 ` Manivannan Sadhasivam 2025-03-24 16:28 ` Bjorn Helgaas 2025-04-07 7:44 ` Manivannan Sadhasivam 2025-04-07 16:53 ` Bjorn Helgaas 2025-03-26 21:18 ` kernel test robot 2025-03-24 10:04 ` [PATCH v2 2/3] PCI: dwc: Add sysfs support for " Manivannan Sadhasivam via B4 Relay 2025-03-24 14:06 ` kernel test robot 2025-03-26 21:42 ` kernel test robot 2025-03-24 10:04 ` [PATCH v2 3/3] PCI: qcom-ep: Mask PTM_UPDATING interrupt Manivannan Sadhasivam via B4 Relay
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox