From: Remi Pommarel <repk@triplefau.lt>
To: Andrew Murray <andrew.murray@arm.com>
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
Bjorn Helgaas <helgaas@kernel.org>,
Ellie Reeves <ellierevves@gmail.com>,
linux-pci@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH v3] PCI: aardvark: Use LTSSM state to build link training flag
Date: Mon, 30 Sep 2019 18:52:30 +0200 [thread overview]
Message-ID: <20190930165230.GA12568@voidbox> (raw)
In-Reply-To: <20190930154017.GF42880@e119886-lin.cambridge.arm.com>
On Mon, Sep 30, 2019 at 04:40:18PM +0100, Andrew Murray wrote:
> On Wed, May 22, 2019 at 11:33:51PM +0200, Remi Pommarel wrote:
> > Aardvark's PCI_EXP_LNKSTA_LT flag in its link status register is not
> > implemented and does not reflect the actual link training state (the
> > flag is always set to 0). In order to support link re-training feature
> > this flag has to be emulated. The Link Training and Status State
> > Machine (LTSSM) flag in Aardvark LMI config register could be used as
> > a link training indicator. Indeed if the LTSSM is in L0 or upper state
> > then link training has completed (see [1]).
> >
> > Unfortunately because after asking a link retraining it takes a while
> > for the LTSSM state to become less than 0x10 (due to L0s to recovery
> > state transition delays), LTSSM can still be in L0 while link training
> > has not finished yet. So this waits for link to be in recovery or lesser
> > state before returning after asking for a link retrain.
> >
> > [1] "PCI Express Base Specification", REV. 4.0
> > PCI Express, February 19 2014, Table 4-14
> >
> > Signed-off-by: Remi Pommarel <repk@triplefau.lt>
> > ---
> > Changes since v1:
> > - Rename retraining flag field
> > - Fix DEVCTL register writing
> >
> > Changes since v2:
> > - Rewrite patch logic so it is more legible
> >
> > Please note that I will unlikely be able to answer any comments from May
> > 24th to June 10th.
> > ---
> > drivers/pci/controller/pci-aardvark.c | 29 ++++++++++++++++++++++++++-
> > 1 file changed, 28 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
> > index 134e0306ff00..8803083b2174 100644
> > --- a/drivers/pci/controller/pci-aardvark.c
> > +++ b/drivers/pci/controller/pci-aardvark.c
> > @@ -180,6 +180,8 @@
> > #define LINK_WAIT_MAX_RETRIES 10
> > #define LINK_WAIT_USLEEP_MIN 90000
> > #define LINK_WAIT_USLEEP_MAX 100000
> > +#define RETRAIN_WAIT_MAX_RETRIES 10
> > +#define RETRAIN_WAIT_USLEEP_US 2000
> >
> > #define MSI_IRQ_NUM 32
> >
> > @@ -239,6 +241,17 @@ static int advk_pcie_wait_for_link(struct advk_pcie *pcie)
> > return -ETIMEDOUT;
> > }
> >
> > +static void advk_pcie_wait_for_retrain(struct advk_pcie *pcie)
> > +{
> > + size_t retries;
> > +
> > + for (retries = 0; retries < RETRAIN_WAIT_MAX_RETRIES; ++retries) {
> > + if (!advk_pcie_link_up(pcie))
> > + break;
> > + udelay(RETRAIN_WAIT_USLEEP_US);
> > + }
> > +}
> > +
> > static void advk_pcie_setup_hw(struct advk_pcie *pcie)
> > {
> > u32 reg;
> > @@ -426,11 +439,20 @@ advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
> > return PCI_BRIDGE_EMUL_HANDLED;
> > }
> >
> > + case PCI_EXP_LNKCTL: {
> > + /* u32 contains both PCI_EXP_LNKCTL and PCI_EXP_LNKSTA */
> > + u32 val = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg) &
> > + ~(PCI_EXP_LNKSTA_LT << 16);
>
> The commit message says "the flag is always set to 0" - therefore I guess
> you don't *need* to mask out the LT bit here? I assume this is just
> belt-and-braces but thought I'd check incase I've misunderstood or if your
> commit message is inaccurate.
>
> In any case masking out the bit (or adding a comment) makes this code more
> readable as the reader doesn't need to know what the hardware does with this
> bit.
Actually vendor eventually responded that the bit was reserved, but
during my tests it remains to 0.
So yes I am masking this out mainly for belt-and-braces and legibility.
> > + if (!advk_pcie_link_up(pcie))
> > + val |= (PCI_EXP_LNKSTA_LT << 16);
> > + *value = val;
> > + return PCI_BRIDGE_EMUL_HANDLED;
> > + }
> > +
> > case PCI_CAP_LIST_ID:
> > case PCI_EXP_DEVCAP:
> > case PCI_EXP_DEVCTL:
> > case PCI_EXP_LNKCAP:
> > - case PCI_EXP_LNKCTL:
> > *value = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg);
> > return PCI_BRIDGE_EMUL_HANDLED;
> > default:
> > @@ -447,8 +469,13 @@ advk_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
> >
> > switch (reg) {
> > case PCI_EXP_DEVCTL:
> > + advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg);
> > + break;
>
> Why is this here?
>
Before PCI_EXP_DEVCTL and PCI_EXP_LNKCTL were doing the same thing, but
as now PCI_EXP_LNKCTL does extra things (i.e. wait for link to
successfully retrain), they do have different behaviours.
So this is here so PCI_EXP_DEVCTL keeps its old behaviour and do not
wait for link retrain in case an unrelated (PCI_EXP_LNKCTL_RL) bit is
set.
--
Remi
> > +
> > case PCI_EXP_LNKCTL:
> > advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg);
> > + if (new & PCI_EXP_LNKCTL_RL)
> > + advk_pcie_wait_for_retrain(pcie);
> > break;
> >
> > case PCI_EXP_RTCTL:
> > --
> > 2.20.1
> >
WARNING: multiple messages have this Message-ID (diff)
From: Remi Pommarel <repk@triplefau.lt>
To: Andrew Murray <andrew.murray@arm.com>
Cc: Ellie Reeves <ellierevves@gmail.com>,
Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org,
Bjorn Helgaas <helgaas@kernel.org>,
Thomas Petazzoni <thomas.petazzoni@bootlin.com>,
linux-arm-kernel@lists.infradead.org
Subject: Re: [PATCH v3] PCI: aardvark: Use LTSSM state to build link training flag
Date: Mon, 30 Sep 2019 18:52:30 +0200 [thread overview]
Message-ID: <20190930165230.GA12568@voidbox> (raw)
In-Reply-To: <20190930154017.GF42880@e119886-lin.cambridge.arm.com>
On Mon, Sep 30, 2019 at 04:40:18PM +0100, Andrew Murray wrote:
> On Wed, May 22, 2019 at 11:33:51PM +0200, Remi Pommarel wrote:
> > Aardvark's PCI_EXP_LNKSTA_LT flag in its link status register is not
> > implemented and does not reflect the actual link training state (the
> > flag is always set to 0). In order to support link re-training feature
> > this flag has to be emulated. The Link Training and Status State
> > Machine (LTSSM) flag in Aardvark LMI config register could be used as
> > a link training indicator. Indeed if the LTSSM is in L0 or upper state
> > then link training has completed (see [1]).
> >
> > Unfortunately because after asking a link retraining it takes a while
> > for the LTSSM state to become less than 0x10 (due to L0s to recovery
> > state transition delays), LTSSM can still be in L0 while link training
> > has not finished yet. So this waits for link to be in recovery or lesser
> > state before returning after asking for a link retrain.
> >
> > [1] "PCI Express Base Specification", REV. 4.0
> > PCI Express, February 19 2014, Table 4-14
> >
> > Signed-off-by: Remi Pommarel <repk@triplefau.lt>
> > ---
> > Changes since v1:
> > - Rename retraining flag field
> > - Fix DEVCTL register writing
> >
> > Changes since v2:
> > - Rewrite patch logic so it is more legible
> >
> > Please note that I will unlikely be able to answer any comments from May
> > 24th to June 10th.
> > ---
> > drivers/pci/controller/pci-aardvark.c | 29 ++++++++++++++++++++++++++-
> > 1 file changed, 28 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
> > index 134e0306ff00..8803083b2174 100644
> > --- a/drivers/pci/controller/pci-aardvark.c
> > +++ b/drivers/pci/controller/pci-aardvark.c
> > @@ -180,6 +180,8 @@
> > #define LINK_WAIT_MAX_RETRIES 10
> > #define LINK_WAIT_USLEEP_MIN 90000
> > #define LINK_WAIT_USLEEP_MAX 100000
> > +#define RETRAIN_WAIT_MAX_RETRIES 10
> > +#define RETRAIN_WAIT_USLEEP_US 2000
> >
> > #define MSI_IRQ_NUM 32
> >
> > @@ -239,6 +241,17 @@ static int advk_pcie_wait_for_link(struct advk_pcie *pcie)
> > return -ETIMEDOUT;
> > }
> >
> > +static void advk_pcie_wait_for_retrain(struct advk_pcie *pcie)
> > +{
> > + size_t retries;
> > +
> > + for (retries = 0; retries < RETRAIN_WAIT_MAX_RETRIES; ++retries) {
> > + if (!advk_pcie_link_up(pcie))
> > + break;
> > + udelay(RETRAIN_WAIT_USLEEP_US);
> > + }
> > +}
> > +
> > static void advk_pcie_setup_hw(struct advk_pcie *pcie)
> > {
> > u32 reg;
> > @@ -426,11 +439,20 @@ advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
> > return PCI_BRIDGE_EMUL_HANDLED;
> > }
> >
> > + case PCI_EXP_LNKCTL: {
> > + /* u32 contains both PCI_EXP_LNKCTL and PCI_EXP_LNKSTA */
> > + u32 val = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg) &
> > + ~(PCI_EXP_LNKSTA_LT << 16);
>
> The commit message says "the flag is always set to 0" - therefore I guess
> you don't *need* to mask out the LT bit here? I assume this is just
> belt-and-braces but thought I'd check incase I've misunderstood or if your
> commit message is inaccurate.
>
> In any case masking out the bit (or adding a comment) makes this code more
> readable as the reader doesn't need to know what the hardware does with this
> bit.
Actually vendor eventually responded that the bit was reserved, but
during my tests it remains to 0.
So yes I am masking this out mainly for belt-and-braces and legibility.
> > + if (!advk_pcie_link_up(pcie))
> > + val |= (PCI_EXP_LNKSTA_LT << 16);
> > + *value = val;
> > + return PCI_BRIDGE_EMUL_HANDLED;
> > + }
> > +
> > case PCI_CAP_LIST_ID:
> > case PCI_EXP_DEVCAP:
> > case PCI_EXP_DEVCTL:
> > case PCI_EXP_LNKCAP:
> > - case PCI_EXP_LNKCTL:
> > *value = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg);
> > return PCI_BRIDGE_EMUL_HANDLED;
> > default:
> > @@ -447,8 +469,13 @@ advk_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
> >
> > switch (reg) {
> > case PCI_EXP_DEVCTL:
> > + advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg);
> > + break;
>
> Why is this here?
>
Before PCI_EXP_DEVCTL and PCI_EXP_LNKCTL were doing the same thing, but
as now PCI_EXP_LNKCTL does extra things (i.e. wait for link to
successfully retrain), they do have different behaviours.
So this is here so PCI_EXP_DEVCTL keeps its old behaviour and do not
wait for link retrain in case an unrelated (PCI_EXP_LNKCTL_RL) bit is
set.
--
Remi
> > +
> > case PCI_EXP_LNKCTL:
> > advk_writel(pcie, new, PCIE_CORE_PCIEXP_CAP + reg);
> > + if (new & PCI_EXP_LNKCTL_RL)
> > + advk_pcie_wait_for_retrain(pcie);
> > break;
> >
> > case PCI_EXP_RTCTL:
> > --
> > 2.20.1
> >
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2019-09-30 16:43 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-22 21:33 [PATCH v3] PCI: aardvark: Use LTSSM state to build link training flag Remi Pommarel
2019-05-22 21:33 ` Remi Pommarel
2019-08-06 18:50 ` Remi Pommarel
2019-08-06 18:50 ` Remi Pommarel
2019-09-25 12:32 ` Thomas Petazzoni
2019-09-25 12:32 ` Thomas Petazzoni
2019-09-30 15:40 ` Andrew Murray
2019-09-30 15:40 ` Andrew Murray
2019-09-30 16:52 ` Remi Pommarel [this message]
2019-09-30 16:52 ` Remi Pommarel
2019-10-01 8:05 ` Andrew Murray
2019-10-01 8:05 ` Andrew Murray
2019-10-13 10:34 ` Marc Zyngier
2019-10-13 10:34 ` Marc Zyngier
2019-10-14 10:01 ` Lorenzo Pieralisi
2019-10-14 10:01 ` Lorenzo Pieralisi
2019-10-14 13:06 ` Remi Pommarel
2019-10-14 13:06 ` Remi Pommarel
2019-10-14 13:45 ` Marc Zyngier
2019-10-14 13:45 ` Marc Zyngier
2019-10-14 14:00 ` Remi Pommarel
2019-10-14 14:00 ` Remi Pommarel
2019-10-14 14:18 ` Marc Zyngier
2019-10-14 14:18 ` Marc Zyngier
2019-10-14 16:50 ` Lorenzo Pieralisi
2019-10-14 16:50 ` Lorenzo Pieralisi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190930165230.GA12568@voidbox \
--to=repk@triplefau.lt \
--cc=andrew.murray@arm.com \
--cc=ellierevves@gmail.com \
--cc=helgaas@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lorenzo.pieralisi@arm.com \
--cc=thomas.petazzoni@bootlin.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.