mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Rob Herring <robh@kernel.org>
To: "Pali Rohár" <pali@kernel.org>
Cc: "Lorenzo Pieralisi" <lorenzo.pieralisi@arm.com>,
	"Bjorn Helgaas" <bhelgaas@google.com>,
	"Marek Behún" <kabel@kernel.org>,
	linux-pci@vger.kernel.org, devicetree@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [RFC PATCH 2/3] PCI: aardvark: Add support for sending Set_Slot_Power_Limit message
Date: Tue, 24 Aug 2021 10:58:31 -0500	[thread overview]
Message-ID: <YSUXJwrpLpzzjgvO@robh.at.kernel.org> (raw)
In-Reply-To: <20210820160023.3243-3-pali@kernel.org>

On Fri, Aug 20, 2021 at 06:00:22PM +0200, Pali Rohár wrote:
> According to PCIe Base specification 3.0, when transitioning from a
> non-DL_Up Status to a DL_Up Status, the Port must initiate the
> transmission of a Set_Slot_Power_Limit Message to the other component
> on the Link to convey the value programmed in the Slot Power Limit
> Scale and Value fields of the Slot Capabilities register. This
> Transmission is optional if the Slot Capabilities register has not
> yet been initialized.
> 
> As PCIe Root Bridge is emulated by kernel emulate readback of Slot Power
> Limit Scale and Value bits in Slot Capabilities register.
> 
> Also send that Set_Slot_Power_Limit message via Message Generation Control
> Register in Link Up handler when link changes from down to up state and
> slot power limit value was defined.
> 
> Slot power limit value is read from DT property 'slot-power-limit' which
> value is in mW unit. When this DT property is not specified then it is
> treated as "Slot Capabilities register has not yet been initialized".
> 
> Signed-off-by: Pali Rohár <pali@kernel.org>
> ---
>  .../devicetree/bindings/pci/aardvark-pci.txt  |  2 +
>  drivers/pci/controller/pci-aardvark.c         | 66 ++++++++++++++++++-
>  2 files changed, 67 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/devicetree/bindings/pci/aardvark-pci.txt b/Documentation/devicetree/bindings/pci/aardvark-pci.txt
> index 2b8ca920a7fa..bb658f261db0 100644
> --- a/Documentation/devicetree/bindings/pci/aardvark-pci.txt
> +++ b/Documentation/devicetree/bindings/pci/aardvark-pci.txt
> @@ -20,6 +20,7 @@ contain the following properties:
>     define the mapping of the PCIe interface to interrupt numbers.
>   - bus-range: PCI bus numbers covered
>   - phys: the PCIe PHY handle
> + - slot-power-limit: see pci.txt
>   - max-link-speed: see pci.txt
>   - reset-gpios: see pci.txt
>  
> @@ -52,6 +53,7 @@ Example:
>  				<0 0 0 3 &pcie_intc 2>,
>  				<0 0 0 4 &pcie_intc 3>;
>  		phys = <&comphy1 0>;
> +		slot-power-limit: <10000>;
>  		pcie_intc: interrupt-controller {
>  			interrupt-controller;
>  			#interrupt-cells = <1>;
> diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
> index f94898f6072f..cf704c199c15 100644
> --- a/drivers/pci/controller/pci-aardvark.c
> +++ b/drivers/pci/controller/pci-aardvark.c
> @@ -166,6 +166,11 @@
>  #define VENDOR_ID_REG				(LMI_BASE_ADDR + 0x44)
>  #define DEBUG_MUX_CTRL_REG			(LMI_BASE_ADDR + 0x208)
>  #define     DIS_ORD_CHK				BIT(30)
> +#define PME_MSG_GEN_CTRL			(LMI_BASE_ADDR + 0x220)
> +#define     SEND_SET_SLOT_POWER_LIMIT		BIT(13)
> +#define     SEND_PME_TURN_OFF			BIT(14)
> +#define     SLOT_POWER_LIMIT_DATA_SHIFT		16
> +#define     SLOT_POWER_LIMIT_DATA_MASK		GENMASK(25, 16)
>  
>  /* PCIe core controller registers */
>  #define CTRL_CORE_BASE_ADDR			0x18000
> @@ -267,6 +272,7 @@ static bool advk_pcie_link_up(struct advk_pcie *pcie)
>  {
>  	u32 val, ltssm_state;
>  	u16 slotsta, slotctl;
> +	u32 slotpwr;
>  	bool link_up;
>  
>  	val = advk_readl(pcie, CFG_REG);
> @@ -277,7 +283,25 @@ static bool advk_pcie_link_up(struct advk_pcie *pcie)
>  		pcie->link_up = true;
>  		slotsta = le16_to_cpu(pcie->bridge.pcie_conf.slotsta);
>  		slotctl = le16_to_cpu(pcie->bridge.pcie_conf.slotctl);
> +		slotpwr = (le32_to_cpu(pcie->bridge.pcie_conf.slotcap) &
> +			   (PCI_EXP_SLTCAP_SPLV | PCI_EXP_SLTCAP_SPLS)) >> 7;
>  		pcie->bridge.pcie_conf.slotsta = cpu_to_le16(slotsta | PCI_EXP_SLTSTA_DLLSC);
> +		if (!(slotctl & PCI_EXP_SLTCTL_ASPL_DISABLE) && slotpwr) {
> +			/*
> +			 * According to PCIe Base specification 3.0, when transitioning from a
> +			 * non-DL_Up Status to a DL_Up Status, the Port must initiate the
> +			 * transmission of a Set_Slot_Power_Limit Message to the other component
> +			 * on the Link to convey the value programmed in the Slot Power Limit
> +			 * Scale and Value fields of the Slot Capabilities register. This
> +			 * Transmission is optional if the Slot Capabilities register has not
> +			 * yet been initialized.
> +			 */
> +			val = advk_readl(pcie, PME_MSG_GEN_CTRL);
> +			val &= ~SLOT_POWER_LIMIT_DATA_MASK;
> +			val |= slotpwr << SLOT_POWER_LIMIT_DATA_SHIFT;
> +			val |= SEND_SET_SLOT_POWER_LIMIT;
> +			advk_writel(pcie, val, PME_MSG_GEN_CTRL);
> +		}
>  		if ((slotctl & PCI_EXP_SLTCTL_DLLSCE) && (slotctl & PCI_EXP_SLTCTL_HPIE))
>  			mod_timer(&pcie->link_up_irq_timer, jiffies + 1);
>  	}
> @@ -956,6 +980,9 @@ static struct pci_bridge_emul_ops advk_pci_bridge_emul_ops = {
>  static int advk_sw_pci_bridge_init(struct advk_pcie *pcie)
>  {
>  	struct pci_bridge_emul *bridge = &pcie->bridge;
> +	struct device *dev = &pcie->pdev->dev;
> +	u8 slot_power_limit_scale, slot_power_limit_value;
> +	u32 slot_power_limit;
>  	int ret;
>  
>  	bridge->conf.vendor =
> @@ -988,6 +1015,40 @@ static int advk_sw_pci_bridge_init(struct advk_pcie *pcie)
>  	/* Indicates supports for Completion Retry Status */
>  	bridge->pcie_conf.rootcap = cpu_to_le16(PCI_EXP_RTCAP_CRSVIS);
>  

> +	if (of_property_read_u32(dev->of_node, "slot-power-limit", &slot_power_limit))
> +		slot_power_limit = 0;
> +
> +	if (slot_power_limit)
> +		dev_info(dev, "Slot power limit %u.%uW\n", slot_power_limit / 1000,
> +			 (slot_power_limit / 100) % 10);

Add a wrapper function for this.

> +
> +	/* Calculate Slot Power Limit Value and Slot Power Limit Scale */
> +	if (slot_power_limit == 0) {
> +		slot_power_limit_scale = 0;
> +		slot_power_limit_value = 0x00;
> +	} else if (slot_power_limit <= 255) {
> +		slot_power_limit_scale = 3;
> +		slot_power_limit_value = slot_power_limit;
> +	} else if (slot_power_limit <= 255*10) {
> +		slot_power_limit_scale = 2;
> +		slot_power_limit_value = slot_power_limit / 10;
> +	} else if (slot_power_limit <= 255*100) {
> +		slot_power_limit_scale = 1;
> +		slot_power_limit_value = slot_power_limit / 100;
> +	} else if (slot_power_limit <= 239*1000) {
> +		slot_power_limit_scale = 0;
> +		slot_power_limit_value = slot_power_limit / 1000;
> +	} else if (slot_power_limit <= 250*1000) {
> +		slot_power_limit_scale = 0;
> +		slot_power_limit_value = 0xF0;
> +	} else if (slot_power_limit <= 275*1000) {
> +		slot_power_limit_scale = 0;
> +		slot_power_limit_value = 0xF1;
> +	} else {
> +		slot_power_limit_scale = 0;
> +		slot_power_limit_value = 0xF2;
> +	}

This all looks like it should be common code.

> +
>  	/*
>  	 * Mark bridge as Hot-Plug Capable to allow delivering Data Link Layer
>  	 * State Changed interrupt. No Command Completed Support is set because
> @@ -996,7 +1057,10 @@ static int advk_sw_pci_bridge_init(struct advk_pcie *pcie)
>  	 * bit permanently as there is no support for unplugging PCIe card from
>  	 * the slot. Assume that PCIe card is always connected in slot.
>  	 */
> -	bridge->pcie_conf.slotcap = cpu_to_le32(PCI_EXP_SLTCAP_NCCS | PCI_EXP_SLTCAP_HPC);
> +	bridge->pcie_conf.slotcap = cpu_to_le32(PCI_EXP_SLTCAP_NCCS |
> +						PCI_EXP_SLTCAP_HPC |

While not new, how does the driver know the board is hotplug capable. 
IIRC, we have a property for that.

> +						slot_power_limit_value << 7 |
> +						slot_power_limit_scale << 15);
>  	bridge->pcie_conf.slotsta = cpu_to_le16(PCI_EXP_SLTSTA_PDS);
>  
>  	return 0;
> -- 
> 2.20.1
> 
> 

  reply	other threads:[~2021-08-24 15:58 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-20 16:00 [RFC PATCH 0/3] PCI: Define slot-power-limit DT property Pali Rohár
2021-08-20 16:00 ` [RFC PATCH 1/3] dt-bindings: Add 'slot-power-limit' PCIe port property Pali Rohár
2021-08-22 12:38   ` Marek Behún
2021-08-24 15:35   ` Rob Herring
2021-08-24 16:14     ` Pali Rohár
2021-08-25 14:57       ` Rob Herring
2021-08-25 15:10         ` Pali Rohár
2021-08-20 16:00 ` [RFC PATCH 2/3] PCI: aardvark: Add support for sending Set_Slot_Power_Limit message Pali Rohár
2021-08-24 15:58   ` Rob Herring [this message]
2021-08-24 16:17     ` Pali Rohár
2021-08-20 16:00 ` [RFC PATCH 3/3] arm64: dts: armada-3720-turris-mox: Define slot-power-limit for PCIe Pali Rohár

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=YSUXJwrpLpzzjgvO@robh.at.kernel.org \
    --to=robh@kernel.org \
    --cc=bhelgaas@google.com \
    --cc=devicetree@vger.kernel.org \
    --cc=kabel@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=pali@kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome