From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Currently, dw_pcie::max_link_speed has a valid value only if the controller
driver restricts the maximum link speed in the driver or if the platform
does so in the devicetree using the 'max-link-speed' property.
But having the maximum supported link speed of the platform would be
helpful for the vendor drivers to configure any link specific settings.
So in the case of non-valid value in dw_pcie::max_link_speed, just cache
the hardware default value from Link Capability register.
While at it, let's also remove the 'max_link_speed' argument to the
dw_pcie_link_set_max_speed() function since the value can be retrieved
within the function.
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
---
drivers/pci/controller/dwc/pcie-designware.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 86c49ba097c6..0704853daa85 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -687,16 +687,27 @@ void dw_pcie_upconfig_setup(struct dw_pcie *pci)
}
EXPORT_SYMBOL_GPL(dw_pcie_upconfig_setup);
-static void dw_pcie_link_set_max_speed(struct dw_pcie *pci, u32 max_link_speed)
+static void dw_pcie_link_set_max_speed(struct dw_pcie *pci)
{
u32 cap, ctrl2, link_speed;
u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
cap = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
+
+ /*
+ * Even if the platform doesn't want to limit the maximum link speed,
+ * just cache the hardware default value so that the vendor drivers can
+ * use it to do any link specific configuration.
+ */
+ if (pci->max_link_speed < 0) {
+ pci->max_link_speed = FIELD_GET(PCI_EXP_LNKCAP_SLS, cap);
+ return;
+ }
+
ctrl2 = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCTL2);
ctrl2 &= ~PCI_EXP_LNKCTL2_TLS;
- switch (pcie_link_speed[max_link_speed]) {
+ switch (pcie_link_speed[pci->max_link_speed]) {
case PCIE_SPEED_2_5GT:
link_speed = PCI_EXP_LNKCTL2_TLS_2_5GT;
break;
@@ -1058,8 +1069,7 @@ void dw_pcie_setup(struct dw_pcie *pci)
{
u32 val;
- if (pci->max_link_speed > 0)
- dw_pcie_link_set_max_speed(pci, pci->max_link_speed);
+ dw_pcie_link_set_max_speed(pci);
/* Configure Gen1 N_FTS */
if (pci->n_fts[0]) {
--
2.25.1
On Wed, Sep 04, 2024 at 12:41:58PM +0530, Manivannan Sadhasivam wrote:
> Currently, dw_pcie::max_link_speed has a valid value only if the controller
> driver restricts the maximum link speed in the driver or if the platform
> does so in the devicetree using the 'max-link-speed' property.
>
> But having the maximum supported link speed of the platform would be
> helpful for the vendor drivers to configure any link specific settings.
> So in the case of non-valid value in dw_pcie::max_link_speed, just cache
> the hardware default value from Link Capability register.
>
> While at it, let's also remove the 'max_link_speed' argument to the
> dw_pcie_link_set_max_speed() function since the value can be retrieved
> within the function.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> ---
> drivers/pci/controller/dwc/pcie-designware.c | 18 ++++++++++++++----
> 1 file changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> index 86c49ba097c6..0704853daa85 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.c
> +++ b/drivers/pci/controller/dwc/pcie-designware.c
> @@ -687,16 +687,27 @@ void dw_pcie_upconfig_setup(struct dw_pcie *pci)
> }
> EXPORT_SYMBOL_GPL(dw_pcie_upconfig_setup);
>
> -static void dw_pcie_link_set_max_speed(struct dw_pcie *pci, u32 max_link_speed)
> +static void dw_pcie_link_set_max_speed(struct dw_pcie *pci)
> {
> u32 cap, ctrl2, link_speed;
> u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
>
> cap = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
> +
> + /*
> + * Even if the platform doesn't want to limit the maximum link speed,
> + * just cache the hardware default value so that the vendor drivers can
> + * use it to do any link specific configuration.
> + */
> + if (pci->max_link_speed < 0) {
> + pci->max_link_speed = FIELD_GET(PCI_EXP_LNKCAP_SLS, cap);
> + return;
> + }
> +
> ctrl2 = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCTL2);
> ctrl2 &= ~PCI_EXP_LNKCTL2_TLS;
>
> - switch (pcie_link_speed[max_link_speed]) {
> + switch (pcie_link_speed[pci->max_link_speed]) {
> case PCIE_SPEED_2_5GT:
> link_speed = PCI_EXP_LNKCTL2_TLS_2_5GT;
> break;
> @@ -1058,8 +1069,7 @@ void dw_pcie_setup(struct dw_pcie *pci)
> {
> u32 val;
>
> - if (pci->max_link_speed > 0)
> - dw_pcie_link_set_max_speed(pci, pci->max_link_speed);
> + dw_pcie_link_set_max_speed(pci);
>
> /* Configure Gen1 N_FTS */
> if (pci->n_fts[0]) {
>
> --
> 2.25.1
>
On Wed, Sep 04, 2024 at 12:41:58PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
>
> Currently, dw_pcie::max_link_speed has a valid value only if the controller
> driver restricts the maximum link speed in the driver or if the platform
> does so in the devicetree using the 'max-link-speed' property.
>
> But having the maximum supported link speed of the platform would be
> helpful for the vendor drivers to configure any link specific settings.
> So in the case of non-valid value in dw_pcie::max_link_speed, just cache
> the hardware default value from Link Capability register.
>
> While at it, let's also remove the 'max_link_speed' argument to the
> dw_pcie_link_set_max_speed() function since the value can be retrieved
> within the function.
>
> Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> ---
> drivers/pci/controller/dwc/pcie-designware.c | 18 ++++++++++++++----
> 1 file changed, 14 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> index 86c49ba097c6..0704853daa85 100644
> --- a/drivers/pci/controller/dwc/pcie-designware.c
> +++ b/drivers/pci/controller/dwc/pcie-designware.c
> @@ -687,16 +687,27 @@ void dw_pcie_upconfig_setup(struct dw_pcie *pci)
> }
> EXPORT_SYMBOL_GPL(dw_pcie_upconfig_setup);
>
> -static void dw_pcie_link_set_max_speed(struct dw_pcie *pci, u32 max_link_speed)
> +static void dw_pcie_link_set_max_speed(struct dw_pcie *pci)
> {
> u32 cap, ctrl2, link_speed;
> u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
>
> cap = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
> +
> + /*
> + * Even if the platform doesn't want to limit the maximum link speed,
> + * just cache the hardware default value so that the vendor drivers can
> + * use it to do any link specific configuration.
> + */
> + if (pci->max_link_speed < 0) {
This should be
if (pci->max_link_speed < 1) {
but the patch works as-is because of the default case in the switch
below which falls back to PCI_EXP_LNKCAP_SLS.
> + pci->max_link_speed = FIELD_GET(PCI_EXP_LNKCAP_SLS, cap);
> + return;
> + }
> +
> ctrl2 = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCTL2);
> ctrl2 &= ~PCI_EXP_LNKCTL2_TLS;
>
> - switch (pcie_link_speed[max_link_speed]) {
> + switch (pcie_link_speed[pci->max_link_speed]) {
> case PCIE_SPEED_2_5GT:
> link_speed = PCI_EXP_LNKCTL2_TLS_2_5GT;
> break;
> @@ -1058,8 +1069,7 @@ void dw_pcie_setup(struct dw_pcie *pci)
> {
> u32 val;
>
> - if (pci->max_link_speed > 0)
> - dw_pcie_link_set_max_speed(pci, pci->max_link_speed);
> + dw_pcie_link_set_max_speed(pci);
With the above fixed:
Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
On Wed, Sep 04, 2024 at 11:30:08AM +0200, Johan Hovold wrote:
> On Wed, Sep 04, 2024 at 12:41:58PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> > From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> >
> > Currently, dw_pcie::max_link_speed has a valid value only if the controller
> > driver restricts the maximum link speed in the driver or if the platform
> > does so in the devicetree using the 'max-link-speed' property.
> >
> > But having the maximum supported link speed of the platform would be
> > helpful for the vendor drivers to configure any link specific settings.
> > So in the case of non-valid value in dw_pcie::max_link_speed, just cache
> > the hardware default value from Link Capability register.
> >
> > While at it, let's also remove the 'max_link_speed' argument to the
> > dw_pcie_link_set_max_speed() function since the value can be retrieved
> > within the function.
> >
> > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> > ---
> > drivers/pci/controller/dwc/pcie-designware.c | 18 ++++++++++++++----
> > 1 file changed, 14 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
> > index 86c49ba097c6..0704853daa85 100644
> > --- a/drivers/pci/controller/dwc/pcie-designware.c
> > +++ b/drivers/pci/controller/dwc/pcie-designware.c
> > @@ -687,16 +687,27 @@ void dw_pcie_upconfig_setup(struct dw_pcie *pci)
> > }
> > EXPORT_SYMBOL_GPL(dw_pcie_upconfig_setup);
> >
> > -static void dw_pcie_link_set_max_speed(struct dw_pcie *pci, u32 max_link_speed)
> > +static void dw_pcie_link_set_max_speed(struct dw_pcie *pci)
> > {
> > u32 cap, ctrl2, link_speed;
> > u8 offset = dw_pcie_find_capability(pci, PCI_CAP_ID_EXP);
> >
> > cap = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCAP);
> > +
> > + /*
> > + * Even if the platform doesn't want to limit the maximum link speed,
> > + * just cache the hardware default value so that the vendor drivers can
> > + * use it to do any link specific configuration.
> > + */
> > + if (pci->max_link_speed < 0) {
>
> This should be
>
> if (pci->max_link_speed < 1) {
>
Well I was trying to catch the error value here because if neither driver nor
platform limits the max link speed, this would have -EINVAL (returned by
of_pci_get_max_link_speed()).
But logically it makes sense to use 'pci->max_link_speed < 1' since anything
below value 1 is an invalid value.
Will change it.
- Mani
> but the patch works as-is because of the default case in the switch
> below which falls back to PCI_EXP_LNKCAP_SLS.
>
> > + pci->max_link_speed = FIELD_GET(PCI_EXP_LNKCAP_SLS, cap);
> > + return;
> > + }
> > +
> > ctrl2 = dw_pcie_readl_dbi(pci, offset + PCI_EXP_LNKCTL2);
> > ctrl2 &= ~PCI_EXP_LNKCTL2_TLS;
> >
> > - switch (pcie_link_speed[max_link_speed]) {
> > + switch (pcie_link_speed[pci->max_link_speed]) {
> > case PCIE_SPEED_2_5GT:
> > link_speed = PCI_EXP_LNKCTL2_TLS_2_5GT;
> > break;
>
> > @@ -1058,8 +1069,7 @@ void dw_pcie_setup(struct dw_pcie *pci)
> > {
> > u32 val;
> >
> > - if (pci->max_link_speed > 0)
> > - dw_pcie_link_set_max_speed(pci, pci->max_link_speed);
> > + dw_pcie_link_set_max_speed(pci);
>
> With the above fixed:
>
> Reviewed-by: Johan Hovold <johan+linaro@kernel.org>
--
மணிவண்ணன் சதாசிவம்
On Wed, Sep 04, 2024 at 09:19:44PM +0530, Manivannan Sadhasivam wrote:
> On Wed, Sep 04, 2024 at 11:30:08AM +0200, Johan Hovold wrote:
> > On Wed, Sep 04, 2024 at 12:41:58PM +0530, Manivannan Sadhasivam via B4 Relay wrote:
> > > From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> > > + /*
> > > + * Even if the platform doesn't want to limit the maximum link speed,
> > > + * just cache the hardware default value so that the vendor drivers can
> > > + * use it to do any link specific configuration.
> > > + */
> > > + if (pci->max_link_speed < 0) {
> >
> > This should be
> >
> > if (pci->max_link_speed < 1) {
> >
>
> Well I was trying to catch the error value here because if neither driver nor
> platform limits the max link speed, this would have -EINVAL (returned by
> of_pci_get_max_link_speed()).
Indeed, I thought I'd traced it do be zero here, but I must have made a
mistake. The old code did check for 0 before calling this function,
though (e.g. in case max_link_speed was never initialised as intended).
> But logically it makes sense to use 'pci->max_link_speed < 1' since anything
> below value 1 is an invalid value.
>
> Will change it.
Sounds good.
> > > @@ -1058,8 +1069,7 @@ void dw_pcie_setup(struct dw_pcie *pci)
> > > {
> > > u32 val;
> > >
> > > - if (pci->max_link_speed > 0)
> > > - dw_pcie_link_set_max_speed(pci, pci->max_link_speed);
> > > + dw_pcie_link_set_max_speed(pci);
Johan
© 2016 - 2026 Red Hat, Inc.