All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/4] PCI: mvebu: Slot support
@ 2022-03-02 14:57 ` Pali Rohár
  0 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2022-03-02 14:57 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King
  Cc: linux-pci, linux-arm-kernel, linux-kernel

This patch series add slot support to pci-mvebu.c driver.

It is based on branch pci/mvebu of git repository:
https://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git

Changes in v2:
* Dropped patch with PCI_EXP_SLTCAP_*_SHIFT macros as it is not needed anymore
* Dropped patch "ARM: dts: turris-omnia: Set PCIe slot-power-limit-milliwatt properties" which was applied
* Added support for PCIe 6.0 slot power limit encodings
* Round down slot power limit value
* Fix handling of slot power limit with scale x1.0 (0x00 value)
* Use FIELD_PREP instead of _SHIFT macros
* Changed commit message to Bjorn's suggestion
* Changed comments in the code to match PCIe spec
* Preserve user settings of PCI_EXP_SLTCTL_ASPL_DISABLE bit

Pali Rohár (4):
  PCI: Add PCI_EXP_SLTCTL_ASPL_DISABLE macro
  dt-bindings: Add 'slot-power-limit-milliwatt' PCIe port property
  PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property
  PCI: mvebu: Add support for sending Set_Slot_Power_Limit message

 Documentation/devicetree/bindings/pci/pci.txt |  6 ++
 drivers/pci/controller/pci-mvebu.c            | 96 ++++++++++++++++++-
 drivers/pci/of.c                              | 64 +++++++++++++
 drivers/pci/pci.h                             | 15 +++
 include/uapi/linux/pci_regs.h                 |  1 +
 5 files changed, 177 insertions(+), 5 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 0/4] PCI: mvebu: Slot support
@ 2022-03-02 14:57 ` Pali Rohár
  0 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2022-03-02 14:57 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King
  Cc: linux-pci, linux-arm-kernel, linux-kernel

This patch series add slot support to pci-mvebu.c driver.

It is based on branch pci/mvebu of git repository:
https://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git

Changes in v2:
* Dropped patch with PCI_EXP_SLTCAP_*_SHIFT macros as it is not needed anymore
* Dropped patch "ARM: dts: turris-omnia: Set PCIe slot-power-limit-milliwatt properties" which was applied
* Added support for PCIe 6.0 slot power limit encodings
* Round down slot power limit value
* Fix handling of slot power limit with scale x1.0 (0x00 value)
* Use FIELD_PREP instead of _SHIFT macros
* Changed commit message to Bjorn's suggestion
* Changed comments in the code to match PCIe spec
* Preserve user settings of PCI_EXP_SLTCTL_ASPL_DISABLE bit

Pali Rohár (4):
  PCI: Add PCI_EXP_SLTCTL_ASPL_DISABLE macro
  dt-bindings: Add 'slot-power-limit-milliwatt' PCIe port property
  PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property
  PCI: mvebu: Add support for sending Set_Slot_Power_Limit message

 Documentation/devicetree/bindings/pci/pci.txt |  6 ++
 drivers/pci/controller/pci-mvebu.c            | 96 ++++++++++++++++++-
 drivers/pci/of.c                              | 64 +++++++++++++
 drivers/pci/pci.h                             | 15 +++
 include/uapi/linux/pci_regs.h                 |  1 +
 5 files changed, 177 insertions(+), 5 deletions(-)

-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH v2 1/4] PCI: Add PCI_EXP_SLTCTL_ASPL_DISABLE macro
  2022-03-02 14:57 ` Pali Rohár
@ 2022-03-02 14:57   ` Pali Rohár
  -1 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2022-03-02 14:57 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King
  Cc: linux-pci, linux-arm-kernel, linux-kernel

Add macro defining Auto Slot Power Limit Disable bit in Slot Control
Register.

Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Marek Behún <kabel@kernel.org>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
 include/uapi/linux/pci_regs.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
index bee1a9ed6e66..108f8523fa04 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -616,6 +616,7 @@
 #define  PCI_EXP_SLTCTL_PWR_OFF        0x0400 /* Power Off */
 #define  PCI_EXP_SLTCTL_EIC	0x0800	/* Electromechanical Interlock Control */
 #define  PCI_EXP_SLTCTL_DLLSCE	0x1000	/* Data Link Layer State Changed Enable */
+#define  PCI_EXP_SLTCTL_ASPL_DISABLE	0x2000 /* Auto Slot Power Limit Disable */
 #define  PCI_EXP_SLTCTL_IBPD_DISABLE	0x4000 /* In-band PD disable */
 #define PCI_EXP_SLTSTA		0x1a	/* Slot Status */
 #define  PCI_EXP_SLTSTA_ABP	0x0001	/* Attention Button Pressed */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 1/4] PCI: Add PCI_EXP_SLTCTL_ASPL_DISABLE macro
@ 2022-03-02 14:57   ` Pali Rohár
  0 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2022-03-02 14:57 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King
  Cc: linux-pci, linux-arm-kernel, linux-kernel

Add macro defining Auto Slot Power Limit Disable bit in Slot Control
Register.

Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Marek Behún <kabel@kernel.org>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
---
 include/uapi/linux/pci_regs.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/uapi/linux/pci_regs.h b/include/uapi/linux/pci_regs.h
index bee1a9ed6e66..108f8523fa04 100644
--- a/include/uapi/linux/pci_regs.h
+++ b/include/uapi/linux/pci_regs.h
@@ -616,6 +616,7 @@
 #define  PCI_EXP_SLTCTL_PWR_OFF        0x0400 /* Power Off */
 #define  PCI_EXP_SLTCTL_EIC	0x0800	/* Electromechanical Interlock Control */
 #define  PCI_EXP_SLTCTL_DLLSCE	0x1000	/* Data Link Layer State Changed Enable */
+#define  PCI_EXP_SLTCTL_ASPL_DISABLE	0x2000 /* Auto Slot Power Limit Disable */
 #define  PCI_EXP_SLTCTL_IBPD_DISABLE	0x4000 /* In-band PD disable */
 #define PCI_EXP_SLTSTA		0x1a	/* Slot Status */
 #define  PCI_EXP_SLTSTA_ABP	0x0001	/* Attention Button Pressed */
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 2/4] dt-bindings: Add 'slot-power-limit-milliwatt' PCIe port property
  2022-03-02 14:57 ` Pali Rohár
@ 2022-03-02 14:57   ` Pali Rohár
  -1 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2022-03-02 14:57 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King
  Cc: linux-pci, linux-arm-kernel, linux-kernel

This property specifies slot power limit in mW unit. It is a form-factor
and board specific value and must be initialized by hardware.

Some PCIe controllers delegate this work to software to allow hardware
flexibility and therefore this property basically specifies what should
host bridge program into PCIe Slot Capabilities registers.

The property needs to be specified in mW unit instead of the special format
defined by Slot Capabilities (which encodes scaling factor or different
unit). Host drivers should convert the value from mW to needed format.

Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Marek Behún <kabel@kernel.org>

---
This change was already accepted into dt-schema repo by Rob Herring:
https://github.com/devicetree-org/dt-schema/pull/66
---
 Documentation/devicetree/bindings/pci/pci.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/pci.txt b/Documentation/devicetree/bindings/pci/pci.txt
index 6a8f2874a24d..b0cc133ed00d 100644
--- a/Documentation/devicetree/bindings/pci/pci.txt
+++ b/Documentation/devicetree/bindings/pci/pci.txt
@@ -32,6 +32,12 @@ driver implementation may support the following properties:
    root port to downstream device and host bridge drivers can do programming
    which depends on CLKREQ signal existence. For example, programming root port
    not to advertise ASPM L1 Sub-States support if there is no CLKREQ signal.
+- slot-power-limit-milliwatt:
+   If present, this property specifies slot power limit in milliwatts. Host
+   drivers can parse this property and use it for programming Root Port or host
+   bridge, or for composing and sending PCIe Set_Slot_Power_Limit messages
+   through the Root Port or host bridge when transitioning PCIe link from a
+   non-DL_Up Status to a DL_Up Status.
 
 PCI-PCI Bridge properties
 -------------------------
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 2/4] dt-bindings: Add 'slot-power-limit-milliwatt' PCIe port property
@ 2022-03-02 14:57   ` Pali Rohár
  0 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2022-03-02 14:57 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King
  Cc: linux-pci, linux-arm-kernel, linux-kernel

This property specifies slot power limit in mW unit. It is a form-factor
and board specific value and must be initialized by hardware.

Some PCIe controllers delegate this work to software to allow hardware
flexibility and therefore this property basically specifies what should
host bridge program into PCIe Slot Capabilities registers.

The property needs to be specified in mW unit instead of the special format
defined by Slot Capabilities (which encodes scaling factor or different
unit). Host drivers should convert the value from mW to needed format.

Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Marek Behún <kabel@kernel.org>

---
This change was already accepted into dt-schema repo by Rob Herring:
https://github.com/devicetree-org/dt-schema/pull/66
---
 Documentation/devicetree/bindings/pci/pci.txt | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/Documentation/devicetree/bindings/pci/pci.txt b/Documentation/devicetree/bindings/pci/pci.txt
index 6a8f2874a24d..b0cc133ed00d 100644
--- a/Documentation/devicetree/bindings/pci/pci.txt
+++ b/Documentation/devicetree/bindings/pci/pci.txt
@@ -32,6 +32,12 @@ driver implementation may support the following properties:
    root port to downstream device and host bridge drivers can do programming
    which depends on CLKREQ signal existence. For example, programming root port
    not to advertise ASPM L1 Sub-States support if there is no CLKREQ signal.
+- slot-power-limit-milliwatt:
+   If present, this property specifies slot power limit in milliwatts. Host
+   drivers can parse this property and use it for programming Root Port or host
+   bridge, or for composing and sending PCIe Set_Slot_Power_Limit messages
+   through the Root Port or host bridge when transitioning PCIe link from a
+   non-DL_Up Status to a DL_Up Status.
 
 PCI-PCI Bridge properties
 -------------------------
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 3/4] PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property
  2022-03-02 14:57 ` Pali Rohár
@ 2022-03-02 14:57   ` Pali Rohár
  -1 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2022-03-02 14:57 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King
  Cc: linux-pci, linux-arm-kernel, linux-kernel

Add function of_pci_get_slot_power_limit(), which parses the
'slot-power-limit-milliwatt' DT property, returning the value in
milliwatts and in format ready for the PCIe Slot Capabilities Register.

Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Marek Behún <kabel@kernel.org>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Changes in v2:
* Added support for PCIe 6.0 slot power limit encodings
* Round down slot power limit value
---
 drivers/pci/of.c  | 64 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/pci/pci.h | 15 +++++++++++
 2 files changed, 79 insertions(+)

diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index cb2e8351c2cc..549a404bd536 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -633,3 +633,67 @@ int of_pci_get_max_link_speed(struct device_node *node)
 	return max_link_speed;
 }
 EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed);
+
+/**
+ * of_pci_get_slot_power_limit - Parses the "slot-power-limit-milliwatt"
+ *				 property.
+ *
+ * @node: device tree node with the slot power limit information
+ * @slot_power_limit_value: pointer where the value should be stored in PCIe
+ *			    Slot Capabilities Register format
+ * @slot_power_limit_scale: pointer where the scale should be stored in PCIe
+ *			    Slot Capabilities Register format
+ *
+ * Returns the slot power limit in milliwatts and if @slot_power_limit_value
+ * and @slot_power_limit_scale pointers are non-NULL, fills in the value and
+ * scale in format used by PCIe Slot Capabilities Register.
+ *
+ * If the property is not found or is invalid, returns 0.
+ */
+u32 of_pci_get_slot_power_limit(struct device_node *node,
+				u8 *slot_power_limit_value,
+				u8 *slot_power_limit_scale)
+{
+	u32 slot_power_limit_mw;
+	u8 value, scale;
+
+	if (of_property_read_u32(node, "slot-power-limit-milliwatt",
+				 &slot_power_limit_mw))
+		slot_power_limit_mw = 0;
+
+	/* Calculate Slot Power Limit Value and Slot Power Limit Scale */
+	if (slot_power_limit_mw == 0) {
+		value = 0x00;
+		scale = 0;
+	} else if (slot_power_limit_mw <= 255) {
+		value = slot_power_limit_mw;
+		scale = 3;
+	} else if (slot_power_limit_mw <= 255*10) {
+		value = slot_power_limit_mw / 10;
+		scale = 2;
+	} else if (slot_power_limit_mw <= 255*100) {
+		value = slot_power_limit_mw / 100;
+		scale = 1;
+	} else if (slot_power_limit_mw <= 239*1000) {
+		value = slot_power_limit_mw / 1000;
+		scale = 0;
+	} else if (slot_power_limit_mw <= 250*1000) {
+		value = 0xF0;
+		scale = 0;
+	} else if (slot_power_limit_mw <= 600*1000) {
+		value = 0xF0 + (slot_power_limit_mw / 1000 - 250) / 25;
+		scale = 0;
+	} else {
+		value = 0xFF;
+		scale = 0;
+	}
+
+	if (slot_power_limit_value)
+		*slot_power_limit_value = value;
+
+	if (slot_power_limit_scale)
+		*slot_power_limit_scale = scale;
+
+	return slot_power_limit_mw;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_slot_power_limit);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 3d60cabde1a1..e10cdec6c56e 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -627,6 +627,9 @@ struct device_node;
 int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
 int of_get_pci_domain_nr(struct device_node *node);
 int of_pci_get_max_link_speed(struct device_node *node);
+u32 of_pci_get_slot_power_limit(struct device_node *node,
+				u8 *slot_power_limit_value,
+				u8 *slot_power_limit_scale);
 void pci_set_of_node(struct pci_dev *dev);
 void pci_release_of_node(struct pci_dev *dev);
 void pci_set_bus_of_node(struct pci_bus *bus);
@@ -653,6 +656,18 @@ of_pci_get_max_link_speed(struct device_node *node)
 	return -EINVAL;
 }
 
+static inline u32
+of_pci_get_slot_power_limit(struct device_node *node,
+			    u8 *slot_power_limit_value,
+			    u8 *slot_power_limit_scale)
+{
+	if (slot_power_limit_value)
+		*slot_power_limit_value = 0;
+	if (slot_power_limit_scale)
+		*slot_power_limit_scale = 0;
+	return 0;
+}
+
 static inline void pci_set_of_node(struct pci_dev *dev) { }
 static inline void pci_release_of_node(struct pci_dev *dev) { }
 static inline void pci_set_bus_of_node(struct pci_bus *bus) { }
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 3/4] PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property
@ 2022-03-02 14:57   ` Pali Rohár
  0 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2022-03-02 14:57 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King
  Cc: linux-pci, linux-arm-kernel, linux-kernel

Add function of_pci_get_slot_power_limit(), which parses the
'slot-power-limit-milliwatt' DT property, returning the value in
milliwatts and in format ready for the PCIe Slot Capabilities Register.

Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Marek Behún <kabel@kernel.org>
Reviewed-by: Rob Herring <robh@kernel.org>
---
Changes in v2:
* Added support for PCIe 6.0 slot power limit encodings
* Round down slot power limit value
---
 drivers/pci/of.c  | 64 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/pci/pci.h | 15 +++++++++++
 2 files changed, 79 insertions(+)

diff --git a/drivers/pci/of.c b/drivers/pci/of.c
index cb2e8351c2cc..549a404bd536 100644
--- a/drivers/pci/of.c
+++ b/drivers/pci/of.c
@@ -633,3 +633,67 @@ int of_pci_get_max_link_speed(struct device_node *node)
 	return max_link_speed;
 }
 EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed);
+
+/**
+ * of_pci_get_slot_power_limit - Parses the "slot-power-limit-milliwatt"
+ *				 property.
+ *
+ * @node: device tree node with the slot power limit information
+ * @slot_power_limit_value: pointer where the value should be stored in PCIe
+ *			    Slot Capabilities Register format
+ * @slot_power_limit_scale: pointer where the scale should be stored in PCIe
+ *			    Slot Capabilities Register format
+ *
+ * Returns the slot power limit in milliwatts and if @slot_power_limit_value
+ * and @slot_power_limit_scale pointers are non-NULL, fills in the value and
+ * scale in format used by PCIe Slot Capabilities Register.
+ *
+ * If the property is not found or is invalid, returns 0.
+ */
+u32 of_pci_get_slot_power_limit(struct device_node *node,
+				u8 *slot_power_limit_value,
+				u8 *slot_power_limit_scale)
+{
+	u32 slot_power_limit_mw;
+	u8 value, scale;
+
+	if (of_property_read_u32(node, "slot-power-limit-milliwatt",
+				 &slot_power_limit_mw))
+		slot_power_limit_mw = 0;
+
+	/* Calculate Slot Power Limit Value and Slot Power Limit Scale */
+	if (slot_power_limit_mw == 0) {
+		value = 0x00;
+		scale = 0;
+	} else if (slot_power_limit_mw <= 255) {
+		value = slot_power_limit_mw;
+		scale = 3;
+	} else if (slot_power_limit_mw <= 255*10) {
+		value = slot_power_limit_mw / 10;
+		scale = 2;
+	} else if (slot_power_limit_mw <= 255*100) {
+		value = slot_power_limit_mw / 100;
+		scale = 1;
+	} else if (slot_power_limit_mw <= 239*1000) {
+		value = slot_power_limit_mw / 1000;
+		scale = 0;
+	} else if (slot_power_limit_mw <= 250*1000) {
+		value = 0xF0;
+		scale = 0;
+	} else if (slot_power_limit_mw <= 600*1000) {
+		value = 0xF0 + (slot_power_limit_mw / 1000 - 250) / 25;
+		scale = 0;
+	} else {
+		value = 0xFF;
+		scale = 0;
+	}
+
+	if (slot_power_limit_value)
+		*slot_power_limit_value = value;
+
+	if (slot_power_limit_scale)
+		*slot_power_limit_scale = scale;
+
+	return slot_power_limit_mw;
+}
+EXPORT_SYMBOL_GPL(of_pci_get_slot_power_limit);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 3d60cabde1a1..e10cdec6c56e 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -627,6 +627,9 @@ struct device_node;
 int of_pci_parse_bus_range(struct device_node *node, struct resource *res);
 int of_get_pci_domain_nr(struct device_node *node);
 int of_pci_get_max_link_speed(struct device_node *node);
+u32 of_pci_get_slot_power_limit(struct device_node *node,
+				u8 *slot_power_limit_value,
+				u8 *slot_power_limit_scale);
 void pci_set_of_node(struct pci_dev *dev);
 void pci_release_of_node(struct pci_dev *dev);
 void pci_set_bus_of_node(struct pci_bus *bus);
@@ -653,6 +656,18 @@ of_pci_get_max_link_speed(struct device_node *node)
 	return -EINVAL;
 }
 
+static inline u32
+of_pci_get_slot_power_limit(struct device_node *node,
+			    u8 *slot_power_limit_value,
+			    u8 *slot_power_limit_scale)
+{
+	if (slot_power_limit_value)
+		*slot_power_limit_value = 0;
+	if (slot_power_limit_scale)
+		*slot_power_limit_scale = 0;
+	return 0;
+}
+
 static inline void pci_set_of_node(struct pci_dev *dev) { }
 static inline void pci_release_of_node(struct pci_dev *dev) { }
 static inline void pci_set_bus_of_node(struct pci_bus *bus) { }
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 4/4] PCI: mvebu: Add support for sending Set_Slot_Power_Limit message
  2022-03-02 14:57 ` Pali Rohár
@ 2022-03-02 14:57   ` Pali Rohár
  -1 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2022-03-02 14:57 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King
  Cc: linux-pci, linux-arm-kernel, linux-kernel

If DT supplies the 'slot-power-limit-milliwatt' property, program
the value in the Slot Power Limit in the Slot Capabilities register
and program the Root Port to send a Set_Slot_Power_Limit Message
when the Link transitions to DL_Up.

Signed-off-by: Pali Rohár <pali@kernel.org>
---
Changes in v2:
* Fix handling of slot power limit with scale x1.0 (0x00 value)
* Use FIELD_PREP instead of _SHIFT macros
* Changed commit message to Bjorn's suggestion
* Changed comments in the code to match PCIe spec
* Preserve user settings of PCI_EXP_SLTCTL_ASPL_DISABLE bit
---
 drivers/pci/controller/pci-mvebu.c | 96 ++++++++++++++++++++++++++++--
 1 file changed, 91 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index a75d2b9196f9..26ae7c29fece 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -8,6 +8,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
@@ -66,6 +67,12 @@
 #define  PCIE_STAT_BUS                  0xff00
 #define  PCIE_STAT_DEV                  0x1f0000
 #define  PCIE_STAT_LINK_DOWN		BIT(0)
+#define PCIE_SSPL_OFF		0x1a0c
+#define  PCIE_SSPL_VALUE_SHIFT		0
+#define  PCIE_SSPL_VALUE_MASK		GENMASK(7, 0)
+#define  PCIE_SSPL_SCALE_SHIFT		8
+#define  PCIE_SSPL_SCALE_MASK		GENMASK(9, 8)
+#define  PCIE_SSPL_ENABLE		BIT(16)
 #define PCIE_RC_RTSTA		0x1a14
 #define PCIE_DEBUG_CTRL         0x1a60
 #define  PCIE_DEBUG_SOFT_RESET		BIT(20)
@@ -111,6 +118,8 @@ struct mvebu_pcie_port {
 	struct mvebu_pcie_window iowin;
 	u32 saved_pcie_stat;
 	struct resource regs;
+	u8 slot_power_limit_value;
+	u8 slot_power_limit_scale;
 	struct irq_domain *intx_irq_domain;
 	raw_spinlock_t irq_lock;
 	int intx_irq;
@@ -239,7 +248,7 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
 
 static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
 {
-	u32 ctrl, lnkcap, cmd, dev_rev, unmask;
+	u32 ctrl, lnkcap, cmd, dev_rev, unmask, sspl;
 
 	/* Setup PCIe controller to Root Complex mode. */
 	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
@@ -292,6 +301,20 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
 	/* Point PCIe unit MBUS decode windows to DRAM space. */
 	mvebu_pcie_setup_wins(port);
 
+	/*
+	 * Program Root Port to automatically send Set_Slot_Power_Limit
+	 * PCIe Message when changing status from Dl_Down to Dl_Up and valid
+	 * slot power limit was specified.
+	 */
+	sspl = mvebu_readl(port, PCIE_SSPL_OFF);
+	sspl &= ~(PCIE_SSPL_VALUE_MASK | PCIE_SSPL_SCALE_MASK | PCIE_SSPL_ENABLE);
+	if (port->slot_power_limit_value) {
+		sspl |= port->slot_power_limit_value << PCIE_SSPL_VALUE_SHIFT;
+		sspl |= port->slot_power_limit_scale << PCIE_SSPL_SCALE_SHIFT;
+		sspl |= PCIE_SSPL_ENABLE;
+	}
+	mvebu_writel(port, sspl, PCIE_SSPL_OFF);
+
 	/* Mask all interrupt sources. */
 	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
 
@@ -628,9 +651,23 @@ mvebu_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
 			  (PCI_EXP_LNKSTA_DLLLA << 16) : 0);
 		break;
 
-	case PCI_EXP_SLTCTL:
-		*value = PCI_EXP_SLTSTA_PDS << 16;
+	case PCI_EXP_SLTCTL: {
+		u16 slotsta = le16_to_cpu(bridge->pcie_conf.slotsta);
+		u32 val = 0;
+		/*
+		 * When slot power limit was not specified in DT then
+		 * ASPL_DISABLE bit is stored only in emulated config space.
+		 * Otherwise reflect status of PCIE_SSPL_ENABLE bit in HW.
+		 */
+		if (!port->slot_power_limit_value)
+			val |= slotctl & PCI_EXP_SLTCTL_ASPL_DISABLE;
+		else if (!(mvebu_readl(port, PCIE_SSPL_OFF) & PCIE_SSPL_ENABLE))
+			val |= PCI_EXP_SLTCTL_ASPL_DISABLE;
+		/* This callback is 32-bit and in high bits is slot status. */
+		val |= slotsta << 16;
+		*value = val;
 		break;
+	}
 
 	case PCI_EXP_RTSTA:
 		*value = mvebu_readl(port, PCIE_RC_RTSTA);
@@ -774,6 +811,22 @@ mvebu_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
 		mvebu_writel(port, new, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL);
 		break;
 
+	case PCI_EXP_SLTCTL:
+		/*
+		 * Allow to change PCIE_SSPL_ENABLE bit only when slot power
+		 * limit was specified in DT and configured into HW.
+		 */
+		if ((mask & PCI_EXP_SLTCTL_ASPL_DISABLE) &&
+		    port->slot_power_limit_value) {
+			u32 sspl = mvebu_readl(port, PCIE_SSPL_OFF);
+			if (new & PCI_EXP_SLTCTL_ASPL_DISABLE)
+				sspl &= ~PCIE_SSPL_ENABLE;
+			else
+				sspl |= PCIE_SSPL_ENABLE;
+			mvebu_writel(port, sspl, PCIE_SSPL_OFF);
+		}
+		break;
+
 	case PCI_EXP_RTSTA:
 		/*
 		 * PME Status bit in Root Status Register (PCIE_RC_RTSTA)
@@ -868,8 +921,26 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
 	/*
 	 * Older mvebu hardware provides PCIe Capability structure only in
 	 * version 1. New hardware provides it in version 2.
+	 * Enable slot support which is emulated.
 	 */
-	bridge->pcie_conf.cap = cpu_to_le16(pcie_cap_ver);
+	bridge->pcie_conf.cap = cpu_to_le16(pcie_cap_ver | PCI_EXP_FLAGS_SLOT);
+
+	/*
+	 * Set Presence Detect State bit permanently as there is no support for
+	 * unplugging PCIe card from the slot. Assume that PCIe card is always
+	 * connected in slot.
+	 *
+	 * Set physical slot number to port+1 as mvebu ports are indexed from
+	 * zero and zero value is reserved for ports within the same silicon
+	 * as Root Port which is not mvebu case.
+	 *
+	 * Also set correct slot power limit.
+	 */
+	bridge->pcie_conf.slotcap = cpu_to_le32(
+		FIELD_PREP(PCI_EXP_SLTCAP_SPLV, port->slot_power_limit_value) |
+		FIELD_PREP(PCI_EXP_SLTCAP_SPLS, port->slot_power_limit_scale) |
+		FIELD_PREP(PCI_EXP_SLTCAP_PSN, port->port+1));
+	bridge->pcie_conf.slotsta = cpu_to_le16(PCI_EXP_SLTSTA_PDS);
 
 	bridge->subsystem_vendor_id = ssdev_id & 0xffff;
 	bridge->subsystem_id = ssdev_id >> 16;
@@ -1191,6 +1262,7 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
 {
 	struct device *dev = &pcie->pdev->dev;
 	enum of_gpio_flags flags;
+	u32 slot_power_limit;
 	int reset_gpio, ret;
 	u32 num_lanes;
 
@@ -1291,6 +1363,15 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
 		port->reset_gpio = gpio_to_desc(reset_gpio);
 	}
 
+	slot_power_limit = of_pci_get_slot_power_limit(child,
+				&port->slot_power_limit_value,
+				&port->slot_power_limit_scale);
+	if (slot_power_limit)
+		dev_info(dev, "%s: Slot power limit %u.%uW\n",
+			 port->name,
+			 slot_power_limit / 1000,
+			 (slot_power_limit / 100) % 10);
+
 	port->clk = of_clk_get_by_name(child, NULL);
 	if (IS_ERR(port->clk)) {
 		dev_err(dev, "%s: cannot get clock\n", port->name);
@@ -1587,7 +1668,7 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
 {
 	struct mvebu_pcie *pcie = platform_get_drvdata(pdev);
 	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
-	u32 cmd;
+	u32 cmd, sspl;
 	int i;
 
 	/* Remove PCI bus with all devices. */
@@ -1624,6 +1705,11 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
 		/* Free config space for emulated root bridge. */
 		pci_bridge_emul_cleanup(&port->bridge);
 
+		/* Disable sending Set_Slot_Power_Limit PCIe Message. */
+		sspl = mvebu_readl(port, PCIE_SSPL_OFF);
+		sspl &= ~(PCIE_SSPL_VALUE_MASK | PCIE_SSPL_SCALE_MASK | PCIE_SSPL_ENABLE);
+		mvebu_writel(port, sspl, PCIE_SSPL_OFF);
+
 		/* Disable and clear BARs and windows. */
 		mvebu_pcie_disable_wins(port);
 
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH v2 4/4] PCI: mvebu: Add support for sending Set_Slot_Power_Limit message
@ 2022-03-02 14:57   ` Pali Rohár
  0 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2022-03-02 14:57 UTC (permalink / raw)
  To: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King
  Cc: linux-pci, linux-arm-kernel, linux-kernel

If DT supplies the 'slot-power-limit-milliwatt' property, program
the value in the Slot Power Limit in the Slot Capabilities register
and program the Root Port to send a Set_Slot_Power_Limit Message
when the Link transitions to DL_Up.

Signed-off-by: Pali Rohár <pali@kernel.org>
---
Changes in v2:
* Fix handling of slot power limit with scale x1.0 (0x00 value)
* Use FIELD_PREP instead of _SHIFT macros
* Changed commit message to Bjorn's suggestion
* Changed comments in the code to match PCIe spec
* Preserve user settings of PCI_EXP_SLTCTL_ASPL_DISABLE bit
---
 drivers/pci/controller/pci-mvebu.c | 96 ++++++++++++++++++++++++++++--
 1 file changed, 91 insertions(+), 5 deletions(-)

diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
index a75d2b9196f9..26ae7c29fece 100644
--- a/drivers/pci/controller/pci-mvebu.c
+++ b/drivers/pci/controller/pci-mvebu.c
@@ -8,6 +8,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/pci.h>
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/gpio.h>
@@ -66,6 +67,12 @@
 #define  PCIE_STAT_BUS                  0xff00
 #define  PCIE_STAT_DEV                  0x1f0000
 #define  PCIE_STAT_LINK_DOWN		BIT(0)
+#define PCIE_SSPL_OFF		0x1a0c
+#define  PCIE_SSPL_VALUE_SHIFT		0
+#define  PCIE_SSPL_VALUE_MASK		GENMASK(7, 0)
+#define  PCIE_SSPL_SCALE_SHIFT		8
+#define  PCIE_SSPL_SCALE_MASK		GENMASK(9, 8)
+#define  PCIE_SSPL_ENABLE		BIT(16)
 #define PCIE_RC_RTSTA		0x1a14
 #define PCIE_DEBUG_CTRL         0x1a60
 #define  PCIE_DEBUG_SOFT_RESET		BIT(20)
@@ -111,6 +118,8 @@ struct mvebu_pcie_port {
 	struct mvebu_pcie_window iowin;
 	u32 saved_pcie_stat;
 	struct resource regs;
+	u8 slot_power_limit_value;
+	u8 slot_power_limit_scale;
 	struct irq_domain *intx_irq_domain;
 	raw_spinlock_t irq_lock;
 	int intx_irq;
@@ -239,7 +248,7 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
 
 static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
 {
-	u32 ctrl, lnkcap, cmd, dev_rev, unmask;
+	u32 ctrl, lnkcap, cmd, dev_rev, unmask, sspl;
 
 	/* Setup PCIe controller to Root Complex mode. */
 	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
@@ -292,6 +301,20 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
 	/* Point PCIe unit MBUS decode windows to DRAM space. */
 	mvebu_pcie_setup_wins(port);
 
+	/*
+	 * Program Root Port to automatically send Set_Slot_Power_Limit
+	 * PCIe Message when changing status from Dl_Down to Dl_Up and valid
+	 * slot power limit was specified.
+	 */
+	sspl = mvebu_readl(port, PCIE_SSPL_OFF);
+	sspl &= ~(PCIE_SSPL_VALUE_MASK | PCIE_SSPL_SCALE_MASK | PCIE_SSPL_ENABLE);
+	if (port->slot_power_limit_value) {
+		sspl |= port->slot_power_limit_value << PCIE_SSPL_VALUE_SHIFT;
+		sspl |= port->slot_power_limit_scale << PCIE_SSPL_SCALE_SHIFT;
+		sspl |= PCIE_SSPL_ENABLE;
+	}
+	mvebu_writel(port, sspl, PCIE_SSPL_OFF);
+
 	/* Mask all interrupt sources. */
 	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
 
@@ -628,9 +651,23 @@ mvebu_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
 			  (PCI_EXP_LNKSTA_DLLLA << 16) : 0);
 		break;
 
-	case PCI_EXP_SLTCTL:
-		*value = PCI_EXP_SLTSTA_PDS << 16;
+	case PCI_EXP_SLTCTL: {
+		u16 slotsta = le16_to_cpu(bridge->pcie_conf.slotsta);
+		u32 val = 0;
+		/*
+		 * When slot power limit was not specified in DT then
+		 * ASPL_DISABLE bit is stored only in emulated config space.
+		 * Otherwise reflect status of PCIE_SSPL_ENABLE bit in HW.
+		 */
+		if (!port->slot_power_limit_value)
+			val |= slotctl & PCI_EXP_SLTCTL_ASPL_DISABLE;
+		else if (!(mvebu_readl(port, PCIE_SSPL_OFF) & PCIE_SSPL_ENABLE))
+			val |= PCI_EXP_SLTCTL_ASPL_DISABLE;
+		/* This callback is 32-bit and in high bits is slot status. */
+		val |= slotsta << 16;
+		*value = val;
 		break;
+	}
 
 	case PCI_EXP_RTSTA:
 		*value = mvebu_readl(port, PCIE_RC_RTSTA);
@@ -774,6 +811,22 @@ mvebu_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
 		mvebu_writel(port, new, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL);
 		break;
 
+	case PCI_EXP_SLTCTL:
+		/*
+		 * Allow to change PCIE_SSPL_ENABLE bit only when slot power
+		 * limit was specified in DT and configured into HW.
+		 */
+		if ((mask & PCI_EXP_SLTCTL_ASPL_DISABLE) &&
+		    port->slot_power_limit_value) {
+			u32 sspl = mvebu_readl(port, PCIE_SSPL_OFF);
+			if (new & PCI_EXP_SLTCTL_ASPL_DISABLE)
+				sspl &= ~PCIE_SSPL_ENABLE;
+			else
+				sspl |= PCIE_SSPL_ENABLE;
+			mvebu_writel(port, sspl, PCIE_SSPL_OFF);
+		}
+		break;
+
 	case PCI_EXP_RTSTA:
 		/*
 		 * PME Status bit in Root Status Register (PCIE_RC_RTSTA)
@@ -868,8 +921,26 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
 	/*
 	 * Older mvebu hardware provides PCIe Capability structure only in
 	 * version 1. New hardware provides it in version 2.
+	 * Enable slot support which is emulated.
 	 */
-	bridge->pcie_conf.cap = cpu_to_le16(pcie_cap_ver);
+	bridge->pcie_conf.cap = cpu_to_le16(pcie_cap_ver | PCI_EXP_FLAGS_SLOT);
+
+	/*
+	 * Set Presence Detect State bit permanently as there is no support for
+	 * unplugging PCIe card from the slot. Assume that PCIe card is always
+	 * connected in slot.
+	 *
+	 * Set physical slot number to port+1 as mvebu ports are indexed from
+	 * zero and zero value is reserved for ports within the same silicon
+	 * as Root Port which is not mvebu case.
+	 *
+	 * Also set correct slot power limit.
+	 */
+	bridge->pcie_conf.slotcap = cpu_to_le32(
+		FIELD_PREP(PCI_EXP_SLTCAP_SPLV, port->slot_power_limit_value) |
+		FIELD_PREP(PCI_EXP_SLTCAP_SPLS, port->slot_power_limit_scale) |
+		FIELD_PREP(PCI_EXP_SLTCAP_PSN, port->port+1));
+	bridge->pcie_conf.slotsta = cpu_to_le16(PCI_EXP_SLTSTA_PDS);
 
 	bridge->subsystem_vendor_id = ssdev_id & 0xffff;
 	bridge->subsystem_id = ssdev_id >> 16;
@@ -1191,6 +1262,7 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
 {
 	struct device *dev = &pcie->pdev->dev;
 	enum of_gpio_flags flags;
+	u32 slot_power_limit;
 	int reset_gpio, ret;
 	u32 num_lanes;
 
@@ -1291,6 +1363,15 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
 		port->reset_gpio = gpio_to_desc(reset_gpio);
 	}
 
+	slot_power_limit = of_pci_get_slot_power_limit(child,
+				&port->slot_power_limit_value,
+				&port->slot_power_limit_scale);
+	if (slot_power_limit)
+		dev_info(dev, "%s: Slot power limit %u.%uW\n",
+			 port->name,
+			 slot_power_limit / 1000,
+			 (slot_power_limit / 100) % 10);
+
 	port->clk = of_clk_get_by_name(child, NULL);
 	if (IS_ERR(port->clk)) {
 		dev_err(dev, "%s: cannot get clock\n", port->name);
@@ -1587,7 +1668,7 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
 {
 	struct mvebu_pcie *pcie = platform_get_drvdata(pdev);
 	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
-	u32 cmd;
+	u32 cmd, sspl;
 	int i;
 
 	/* Remove PCI bus with all devices. */
@@ -1624,6 +1705,11 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
 		/* Free config space for emulated root bridge. */
 		pci_bridge_emul_cleanup(&port->bridge);
 
+		/* Disable sending Set_Slot_Power_Limit PCIe Message. */
+		sspl = mvebu_readl(port, PCIE_SSPL_OFF);
+		sspl &= ~(PCIE_SSPL_VALUE_MASK | PCIE_SSPL_SCALE_MASK | PCIE_SSPL_ENABLE);
+		mvebu_writel(port, sspl, PCIE_SSPL_OFF);
+
 		/* Disable and clear BARs and windows. */
 		mvebu_pcie_disable_wins(port);
 
-- 
2.20.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 0/4] PCI: mvebu: Slot support
  2022-03-02 14:57 ` Pali Rohár
@ 2022-03-08 11:38   ` Pali Rohár
  -1 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2022-03-08 11:38 UTC (permalink / raw)
  To: Bjorn Helgaas, Lorenzo Pieralisi, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King
  Cc: linux-pci, linux-arm-kernel, linux-kernel

Hello Bjorn! Could you look if v2 changes are now fine?

On Wednesday 02 March 2022 15:57:29 Pali Rohár wrote:
> This patch series add slot support to pci-mvebu.c driver.
> 
> It is based on branch pci/mvebu of git repository:
> https://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git
> 
> Changes in v2:
> * Dropped patch with PCI_EXP_SLTCAP_*_SHIFT macros as it is not needed anymore
> * Dropped patch "ARM: dts: turris-omnia: Set PCIe slot-power-limit-milliwatt properties" which was applied
> * Added support for PCIe 6.0 slot power limit encodings
> * Round down slot power limit value
> * Fix handling of slot power limit with scale x1.0 (0x00 value)
> * Use FIELD_PREP instead of _SHIFT macros
> * Changed commit message to Bjorn's suggestion
> * Changed comments in the code to match PCIe spec
> * Preserve user settings of PCI_EXP_SLTCTL_ASPL_DISABLE bit
> 
> Pali Rohár (4):
>   PCI: Add PCI_EXP_SLTCTL_ASPL_DISABLE macro
>   dt-bindings: Add 'slot-power-limit-milliwatt' PCIe port property
>   PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property
>   PCI: mvebu: Add support for sending Set_Slot_Power_Limit message
> 
>  Documentation/devicetree/bindings/pci/pci.txt |  6 ++
>  drivers/pci/controller/pci-mvebu.c            | 96 ++++++++++++++++++-
>  drivers/pci/of.c                              | 64 +++++++++++++
>  drivers/pci/pci.h                             | 15 +++
>  include/uapi/linux/pci_regs.h                 |  1 +
>  5 files changed, 177 insertions(+), 5 deletions(-)
> 
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 0/4] PCI: mvebu: Slot support
@ 2022-03-08 11:38   ` Pali Rohár
  0 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2022-03-08 11:38 UTC (permalink / raw)
  To: Bjorn Helgaas, Lorenzo Pieralisi, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King
  Cc: linux-pci, linux-arm-kernel, linux-kernel

Hello Bjorn! Could you look if v2 changes are now fine?

On Wednesday 02 March 2022 15:57:29 Pali Rohár wrote:
> This patch series add slot support to pci-mvebu.c driver.
> 
> It is based on branch pci/mvebu of git repository:
> https://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git
> 
> Changes in v2:
> * Dropped patch with PCI_EXP_SLTCAP_*_SHIFT macros as it is not needed anymore
> * Dropped patch "ARM: dts: turris-omnia: Set PCIe slot-power-limit-milliwatt properties" which was applied
> * Added support for PCIe 6.0 slot power limit encodings
> * Round down slot power limit value
> * Fix handling of slot power limit with scale x1.0 (0x00 value)
> * Use FIELD_PREP instead of _SHIFT macros
> * Changed commit message to Bjorn's suggestion
> * Changed comments in the code to match PCIe spec
> * Preserve user settings of PCI_EXP_SLTCTL_ASPL_DISABLE bit
> 
> Pali Rohár (4):
>   PCI: Add PCI_EXP_SLTCTL_ASPL_DISABLE macro
>   dt-bindings: Add 'slot-power-limit-milliwatt' PCIe port property
>   PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property
>   PCI: mvebu: Add support for sending Set_Slot_Power_Limit message
> 
>  Documentation/devicetree/bindings/pci/pci.txt |  6 ++
>  drivers/pci/controller/pci-mvebu.c            | 96 ++++++++++++++++++-
>  drivers/pci/of.c                              | 64 +++++++++++++
>  drivers/pci/pci.h                             | 15 +++
>  include/uapi/linux/pci_regs.h                 |  1 +
>  5 files changed, 177 insertions(+), 5 deletions(-)
> 
> -- 
> 2.20.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 0/4] PCI: mvebu: Slot support
  2022-03-08 11:38   ` Pali Rohár
@ 2022-03-21 18:29     ` Pali Rohár
  -1 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2022-03-21 18:29 UTC (permalink / raw)
  To: Bjorn Helgaas, Lorenzo Pieralisi, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King
  Cc: linux-pci, linux-arm-kernel, linux-kernel

PING?

On Tuesday 08 March 2022 12:38:31 Pali Rohár wrote:
> Hello Bjorn! Could you look if v2 changes are now fine?
> 
> On Wednesday 02 March 2022 15:57:29 Pali Rohár wrote:
> > This patch series add slot support to pci-mvebu.c driver.
> > 
> > It is based on branch pci/mvebu of git repository:
> > https://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git
> > 
> > Changes in v2:
> > * Dropped patch with PCI_EXP_SLTCAP_*_SHIFT macros as it is not needed anymore
> > * Dropped patch "ARM: dts: turris-omnia: Set PCIe slot-power-limit-milliwatt properties" which was applied
> > * Added support for PCIe 6.0 slot power limit encodings
> > * Round down slot power limit value
> > * Fix handling of slot power limit with scale x1.0 (0x00 value)
> > * Use FIELD_PREP instead of _SHIFT macros
> > * Changed commit message to Bjorn's suggestion
> > * Changed comments in the code to match PCIe spec
> > * Preserve user settings of PCI_EXP_SLTCTL_ASPL_DISABLE bit
> > 
> > Pali Rohár (4):
> >   PCI: Add PCI_EXP_SLTCTL_ASPL_DISABLE macro
> >   dt-bindings: Add 'slot-power-limit-milliwatt' PCIe port property
> >   PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property
> >   PCI: mvebu: Add support for sending Set_Slot_Power_Limit message
> > 
> >  Documentation/devicetree/bindings/pci/pci.txt |  6 ++
> >  drivers/pci/controller/pci-mvebu.c            | 96 ++++++++++++++++++-
> >  drivers/pci/of.c                              | 64 +++++++++++++
> >  drivers/pci/pci.h                             | 15 +++
> >  include/uapi/linux/pci_regs.h                 |  1 +
> >  5 files changed, 177 insertions(+), 5 deletions(-)
> > 
> > -- 
> > 2.20.1
> > 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 0/4] PCI: mvebu: Slot support
@ 2022-03-21 18:29     ` Pali Rohár
  0 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2022-03-21 18:29 UTC (permalink / raw)
  To: Bjorn Helgaas, Lorenzo Pieralisi, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King
  Cc: linux-pci, linux-arm-kernel, linux-kernel

PING?

On Tuesday 08 March 2022 12:38:31 Pali Rohár wrote:
> Hello Bjorn! Could you look if v2 changes are now fine?
> 
> On Wednesday 02 March 2022 15:57:29 Pali Rohár wrote:
> > This patch series add slot support to pci-mvebu.c driver.
> > 
> > It is based on branch pci/mvebu of git repository:
> > https://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git
> > 
> > Changes in v2:
> > * Dropped patch with PCI_EXP_SLTCAP_*_SHIFT macros as it is not needed anymore
> > * Dropped patch "ARM: dts: turris-omnia: Set PCIe slot-power-limit-milliwatt properties" which was applied
> > * Added support for PCIe 6.0 slot power limit encodings
> > * Round down slot power limit value
> > * Fix handling of slot power limit with scale x1.0 (0x00 value)
> > * Use FIELD_PREP instead of _SHIFT macros
> > * Changed commit message to Bjorn's suggestion
> > * Changed comments in the code to match PCIe spec
> > * Preserve user settings of PCI_EXP_SLTCTL_ASPL_DISABLE bit
> > 
> > Pali Rohár (4):
> >   PCI: Add PCI_EXP_SLTCTL_ASPL_DISABLE macro
> >   dt-bindings: Add 'slot-power-limit-milliwatt' PCIe port property
> >   PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property
> >   PCI: mvebu: Add support for sending Set_Slot_Power_Limit message
> > 
> >  Documentation/devicetree/bindings/pci/pci.txt |  6 ++
> >  drivers/pci/controller/pci-mvebu.c            | 96 ++++++++++++++++++-
> >  drivers/pci/of.c                              | 64 +++++++++++++
> >  drivers/pci/pci.h                             | 15 +++
> >  include/uapi/linux/pci_regs.h                 |  1 +
> >  5 files changed, 177 insertions(+), 5 deletions(-)
> > 
> > -- 
> > 2.20.1
> > 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 0/4] PCI: mvebu: Slot support
  2022-03-21 18:29     ` Pali Rohár
@ 2022-03-24 17:12       ` Bjorn Helgaas
  -1 siblings, 0 replies; 26+ messages in thread
From: Bjorn Helgaas @ 2022-03-24 17:12 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Bjorn Helgaas, Lorenzo Pieralisi, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King, linux-pci, linux-arm-kernel, linux-kernel

On Mon, Mar 21, 2022 at 07:29:08PM +0100, Pali Rohár wrote:
> PING?

Sorry, my fault.  I reviewed v1 of this patch, so obviously Lorenzo
would wait for me to chime in here.

> On Tuesday 08 March 2022 12:38:31 Pali Rohár wrote:
> > Hello Bjorn! Could you look if v2 changes are now fine?
> > 
> > On Wednesday 02 March 2022 15:57:29 Pali Rohár wrote:
> > > This patch series add slot support to pci-mvebu.c driver.
> > > 
> > > It is based on branch pci/mvebu of git repository:
> > > https://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git
> > > 
> > > Changes in v2:
> > > * Dropped patch with PCI_EXP_SLTCAP_*_SHIFT macros as it is not needed anymore
> > > * Dropped patch "ARM: dts: turris-omnia: Set PCIe slot-power-limit-milliwatt properties" which was applied
> > > * Added support for PCIe 6.0 slot power limit encodings
> > > * Round down slot power limit value
> > > * Fix handling of slot power limit with scale x1.0 (0x00 value)
> > > * Use FIELD_PREP instead of _SHIFT macros
> > > * Changed commit message to Bjorn's suggestion
> > > * Changed comments in the code to match PCIe spec
> > > * Preserve user settings of PCI_EXP_SLTCTL_ASPL_DISABLE bit
> > > 
> > > Pali Rohár (4):
> > >   PCI: Add PCI_EXP_SLTCTL_ASPL_DISABLE macro
> > >   dt-bindings: Add 'slot-power-limit-milliwatt' PCIe port property
> > >   PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property
> > >   PCI: mvebu: Add support for sending Set_Slot_Power_Limit message
> > > 
> > >  Documentation/devicetree/bindings/pci/pci.txt |  6 ++
> > >  drivers/pci/controller/pci-mvebu.c            | 96 ++++++++++++++++++-
> > >  drivers/pci/of.c                              | 64 +++++++++++++
> > >  drivers/pci/pci.h                             | 15 +++
> > >  include/uapi/linux/pci_regs.h                 |  1 +
> > >  5 files changed, 177 insertions(+), 5 deletions(-)
> > > 
> > > -- 
> > > 2.20.1
> > > 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 0/4] PCI: mvebu: Slot support
@ 2022-03-24 17:12       ` Bjorn Helgaas
  0 siblings, 0 replies; 26+ messages in thread
From: Bjorn Helgaas @ 2022-03-24 17:12 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Bjorn Helgaas, Lorenzo Pieralisi, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King, linux-pci, linux-arm-kernel, linux-kernel

On Mon, Mar 21, 2022 at 07:29:08PM +0100, Pali Rohár wrote:
> PING?

Sorry, my fault.  I reviewed v1 of this patch, so obviously Lorenzo
would wait for me to chime in here.

> On Tuesday 08 March 2022 12:38:31 Pali Rohár wrote:
> > Hello Bjorn! Could you look if v2 changes are now fine?
> > 
> > On Wednesday 02 March 2022 15:57:29 Pali Rohár wrote:
> > > This patch series add slot support to pci-mvebu.c driver.
> > > 
> > > It is based on branch pci/mvebu of git repository:
> > > https://git.kernel.org/pub/scm/linux/kernel/git/lpieralisi/pci.git
> > > 
> > > Changes in v2:
> > > * Dropped patch with PCI_EXP_SLTCAP_*_SHIFT macros as it is not needed anymore
> > > * Dropped patch "ARM: dts: turris-omnia: Set PCIe slot-power-limit-milliwatt properties" which was applied
> > > * Added support for PCIe 6.0 slot power limit encodings
> > > * Round down slot power limit value
> > > * Fix handling of slot power limit with scale x1.0 (0x00 value)
> > > * Use FIELD_PREP instead of _SHIFT macros
> > > * Changed commit message to Bjorn's suggestion
> > > * Changed comments in the code to match PCIe spec
> > > * Preserve user settings of PCI_EXP_SLTCTL_ASPL_DISABLE bit
> > > 
> > > Pali Rohár (4):
> > >   PCI: Add PCI_EXP_SLTCTL_ASPL_DISABLE macro
> > >   dt-bindings: Add 'slot-power-limit-milliwatt' PCIe port property
> > >   PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property
> > >   PCI: mvebu: Add support for sending Set_Slot_Power_Limit message
> > > 
> > >  Documentation/devicetree/bindings/pci/pci.txt |  6 ++
> > >  drivers/pci/controller/pci-mvebu.c            | 96 ++++++++++++++++++-
> > >  drivers/pci/of.c                              | 64 +++++++++++++
> > >  drivers/pci/pci.h                             | 15 +++
> > >  include/uapi/linux/pci_regs.h                 |  1 +
> > >  5 files changed, 177 insertions(+), 5 deletions(-)
> > > 
> > > -- 
> > > 2.20.1
> > > 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 3/4] PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property
  2022-03-02 14:57   ` Pali Rohár
@ 2022-03-24 17:13     ` Bjorn Helgaas
  -1 siblings, 0 replies; 26+ messages in thread
From: Bjorn Helgaas @ 2022-03-24 17:13 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King, linux-pci, linux-arm-kernel, linux-kernel

On Wed, Mar 02, 2022 at 03:57:32PM +0100, Pali Rohár wrote:
> Add function of_pci_get_slot_power_limit(), which parses the
> 'slot-power-limit-milliwatt' DT property, returning the value in
> milliwatts and in format ready for the PCIe Slot Capabilities Register.
> 
> Signed-off-by: Pali Rohár <pali@kernel.org>
> Signed-off-by: Marek Behún <kabel@kernel.org>
> Reviewed-by: Rob Herring <robh@kernel.org>
> ---
> Changes in v2:
> * Added support for PCIe 6.0 slot power limit encodings
> * Round down slot power limit value
> ---
>  drivers/pci/of.c  | 64 +++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/pci/pci.h | 15 +++++++++++
>  2 files changed, 79 insertions(+)
> 
> diff --git a/drivers/pci/of.c b/drivers/pci/of.c
> index cb2e8351c2cc..549a404bd536 100644
> --- a/drivers/pci/of.c
> +++ b/drivers/pci/of.c
> @@ -633,3 +633,67 @@ int of_pci_get_max_link_speed(struct device_node *node)
>  	return max_link_speed;
>  }
>  EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed);
> +
> +/**
> + * of_pci_get_slot_power_limit - Parses the "slot-power-limit-milliwatt"
> + *				 property.
> + *
> + * @node: device tree node with the slot power limit information
> + * @slot_power_limit_value: pointer where the value should be stored in PCIe
> + *			    Slot Capabilities Register format
> + * @slot_power_limit_scale: pointer where the scale should be stored in PCIe
> + *			    Slot Capabilities Register format
> + *
> + * Returns the slot power limit in milliwatts and if @slot_power_limit_value
> + * and @slot_power_limit_scale pointers are non-NULL, fills in the value and
> + * scale in format used by PCIe Slot Capabilities Register.
> + *
> + * If the property is not found or is invalid, returns 0.
> + */
> +u32 of_pci_get_slot_power_limit(struct device_node *node,
> +				u8 *slot_power_limit_value,
> +				u8 *slot_power_limit_scale)
> +{
> +	u32 slot_power_limit_mw;
> +	u8 value, scale;
> +
> +	if (of_property_read_u32(node, "slot-power-limit-milliwatt",
> +				 &slot_power_limit_mw))
> +		slot_power_limit_mw = 0;
> +
> +	/* Calculate Slot Power Limit Value and Slot Power Limit Scale */
> +	if (slot_power_limit_mw == 0) {
> +		value = 0x00;
> +		scale = 0;
> +	} else if (slot_power_limit_mw <= 255) {
> +		value = slot_power_limit_mw;
> +		scale = 3;
> +	} else if (slot_power_limit_mw <= 255*10) {
> +		value = slot_power_limit_mw / 10;
> +		scale = 2;
> +	} else if (slot_power_limit_mw <= 255*100) {
> +		value = slot_power_limit_mw / 100;
> +		scale = 1;
> +	} else if (slot_power_limit_mw <= 239*1000) {
> +		value = slot_power_limit_mw / 1000;
> +		scale = 0;
> +	} else if (slot_power_limit_mw <= 250*1000) {
> +		value = 0xF0;
> +		scale = 0;
> +	} else if (slot_power_limit_mw <= 600*1000) {
> +		value = 0xF0 + (slot_power_limit_mw / 1000 - 250) / 25;
> +		scale = 0;
> +	} else {
> +		value = 0xFF;
> +		scale = 0;

The purpose of this function is to return values that can be
programmed into the Slot Capabilities register.  The 0xFF Slot Power
Limit Value is reserved, and I don't think we should use it until the
spec defines a meaning for it.

If the DT tells us 800W is available, we'll put 0xFF in Slot Power
Limit Value.  If the spec eventually defines (0xFF, 0) to mean "1000W
available", a device may try to consume all 1000W, which will not
work.

If slot_power_limit_mw > 600*1000, I think we should advertise 600W
available (value 0xFE, scale 0) and return 600W (600*1000).

Bjorn

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 3/4] PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property
@ 2022-03-24 17:13     ` Bjorn Helgaas
  0 siblings, 0 replies; 26+ messages in thread
From: Bjorn Helgaas @ 2022-03-24 17:13 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King, linux-pci, linux-arm-kernel, linux-kernel

On Wed, Mar 02, 2022 at 03:57:32PM +0100, Pali Rohár wrote:
> Add function of_pci_get_slot_power_limit(), which parses the
> 'slot-power-limit-milliwatt' DT property, returning the value in
> milliwatts and in format ready for the PCIe Slot Capabilities Register.
> 
> Signed-off-by: Pali Rohár <pali@kernel.org>
> Signed-off-by: Marek Behún <kabel@kernel.org>
> Reviewed-by: Rob Herring <robh@kernel.org>
> ---
> Changes in v2:
> * Added support for PCIe 6.0 slot power limit encodings
> * Round down slot power limit value
> ---
>  drivers/pci/of.c  | 64 +++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/pci/pci.h | 15 +++++++++++
>  2 files changed, 79 insertions(+)
> 
> diff --git a/drivers/pci/of.c b/drivers/pci/of.c
> index cb2e8351c2cc..549a404bd536 100644
> --- a/drivers/pci/of.c
> +++ b/drivers/pci/of.c
> @@ -633,3 +633,67 @@ int of_pci_get_max_link_speed(struct device_node *node)
>  	return max_link_speed;
>  }
>  EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed);
> +
> +/**
> + * of_pci_get_slot_power_limit - Parses the "slot-power-limit-milliwatt"
> + *				 property.
> + *
> + * @node: device tree node with the slot power limit information
> + * @slot_power_limit_value: pointer where the value should be stored in PCIe
> + *			    Slot Capabilities Register format
> + * @slot_power_limit_scale: pointer where the scale should be stored in PCIe
> + *			    Slot Capabilities Register format
> + *
> + * Returns the slot power limit in milliwatts and if @slot_power_limit_value
> + * and @slot_power_limit_scale pointers are non-NULL, fills in the value and
> + * scale in format used by PCIe Slot Capabilities Register.
> + *
> + * If the property is not found or is invalid, returns 0.
> + */
> +u32 of_pci_get_slot_power_limit(struct device_node *node,
> +				u8 *slot_power_limit_value,
> +				u8 *slot_power_limit_scale)
> +{
> +	u32 slot_power_limit_mw;
> +	u8 value, scale;
> +
> +	if (of_property_read_u32(node, "slot-power-limit-milliwatt",
> +				 &slot_power_limit_mw))
> +		slot_power_limit_mw = 0;
> +
> +	/* Calculate Slot Power Limit Value and Slot Power Limit Scale */
> +	if (slot_power_limit_mw == 0) {
> +		value = 0x00;
> +		scale = 0;
> +	} else if (slot_power_limit_mw <= 255) {
> +		value = slot_power_limit_mw;
> +		scale = 3;
> +	} else if (slot_power_limit_mw <= 255*10) {
> +		value = slot_power_limit_mw / 10;
> +		scale = 2;
> +	} else if (slot_power_limit_mw <= 255*100) {
> +		value = slot_power_limit_mw / 100;
> +		scale = 1;
> +	} else if (slot_power_limit_mw <= 239*1000) {
> +		value = slot_power_limit_mw / 1000;
> +		scale = 0;
> +	} else if (slot_power_limit_mw <= 250*1000) {
> +		value = 0xF0;
> +		scale = 0;
> +	} else if (slot_power_limit_mw <= 600*1000) {
> +		value = 0xF0 + (slot_power_limit_mw / 1000 - 250) / 25;
> +		scale = 0;
> +	} else {
> +		value = 0xFF;
> +		scale = 0;

The purpose of this function is to return values that can be
programmed into the Slot Capabilities register.  The 0xFF Slot Power
Limit Value is reserved, and I don't think we should use it until the
spec defines a meaning for it.

If the DT tells us 800W is available, we'll put 0xFF in Slot Power
Limit Value.  If the spec eventually defines (0xFF, 0) to mean "1000W
available", a device may try to consume all 1000W, which will not
work.

If slot_power_limit_mw > 600*1000, I think we should advertise 600W
available (value 0xFE, scale 0) and return 600W (600*1000).

Bjorn

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 4/4] PCI: mvebu: Add support for sending Set_Slot_Power_Limit message
  2022-03-02 14:57   ` Pali Rohár
@ 2022-03-24 17:15     ` Bjorn Helgaas
  -1 siblings, 0 replies; 26+ messages in thread
From: Bjorn Helgaas @ 2022-03-24 17:15 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King, linux-pci, linux-arm-kernel, linux-kernel

On Wed, Mar 02, 2022 at 03:57:33PM +0100, Pali Rohár wrote:
> If DT supplies the 'slot-power-limit-milliwatt' property, program
> the value in the Slot Power Limit in the Slot Capabilities register
> and program the Root Port to send a Set_Slot_Power_Limit Message
> when the Link transitions to DL_Up.
> 
> Signed-off-by: Pali Rohár <pali@kernel.org>

I didn't review this carefully but have no objection.

> ---
> Changes in v2:
> * Fix handling of slot power limit with scale x1.0 (0x00 value)
> * Use FIELD_PREP instead of _SHIFT macros
> * Changed commit message to Bjorn's suggestion
> * Changed comments in the code to match PCIe spec
> * Preserve user settings of PCI_EXP_SLTCTL_ASPL_DISABLE bit
> ---
>  drivers/pci/controller/pci-mvebu.c | 96 ++++++++++++++++++++++++++++--
>  1 file changed, 91 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> index a75d2b9196f9..26ae7c29fece 100644
> --- a/drivers/pci/controller/pci-mvebu.c
> +++ b/drivers/pci/controller/pci-mvebu.c
> @@ -8,6 +8,7 @@
>  #include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/pci.h>
> +#include <linux/bitfield.h>
>  #include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/gpio.h>
> @@ -66,6 +67,12 @@
>  #define  PCIE_STAT_BUS                  0xff00
>  #define  PCIE_STAT_DEV                  0x1f0000
>  #define  PCIE_STAT_LINK_DOWN		BIT(0)
> +#define PCIE_SSPL_OFF		0x1a0c
> +#define  PCIE_SSPL_VALUE_SHIFT		0
> +#define  PCIE_SSPL_VALUE_MASK		GENMASK(7, 0)
> +#define  PCIE_SSPL_SCALE_SHIFT		8
> +#define  PCIE_SSPL_SCALE_MASK		GENMASK(9, 8)
> +#define  PCIE_SSPL_ENABLE		BIT(16)
>  #define PCIE_RC_RTSTA		0x1a14
>  #define PCIE_DEBUG_CTRL         0x1a60
>  #define  PCIE_DEBUG_SOFT_RESET		BIT(20)
> @@ -111,6 +118,8 @@ struct mvebu_pcie_port {
>  	struct mvebu_pcie_window iowin;
>  	u32 saved_pcie_stat;
>  	struct resource regs;
> +	u8 slot_power_limit_value;
> +	u8 slot_power_limit_scale;
>  	struct irq_domain *intx_irq_domain;
>  	raw_spinlock_t irq_lock;
>  	int intx_irq;
> @@ -239,7 +248,7 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
>  
>  static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
>  {
> -	u32 ctrl, lnkcap, cmd, dev_rev, unmask;
> +	u32 ctrl, lnkcap, cmd, dev_rev, unmask, sspl;
>  
>  	/* Setup PCIe controller to Root Complex mode. */
>  	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
> @@ -292,6 +301,20 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
>  	/* Point PCIe unit MBUS decode windows to DRAM space. */
>  	mvebu_pcie_setup_wins(port);
>  
> +	/*
> +	 * Program Root Port to automatically send Set_Slot_Power_Limit
> +	 * PCIe Message when changing status from Dl_Down to Dl_Up and valid
> +	 * slot power limit was specified.
> +	 */
> +	sspl = mvebu_readl(port, PCIE_SSPL_OFF);
> +	sspl &= ~(PCIE_SSPL_VALUE_MASK | PCIE_SSPL_SCALE_MASK | PCIE_SSPL_ENABLE);
> +	if (port->slot_power_limit_value) {
> +		sspl |= port->slot_power_limit_value << PCIE_SSPL_VALUE_SHIFT;
> +		sspl |= port->slot_power_limit_scale << PCIE_SSPL_SCALE_SHIFT;
> +		sspl |= PCIE_SSPL_ENABLE;
> +	}
> +	mvebu_writel(port, sspl, PCIE_SSPL_OFF);
> +
>  	/* Mask all interrupt sources. */
>  	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
>  
> @@ -628,9 +651,23 @@ mvebu_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
>  			  (PCI_EXP_LNKSTA_DLLLA << 16) : 0);
>  		break;
>  
> -	case PCI_EXP_SLTCTL:
> -		*value = PCI_EXP_SLTSTA_PDS << 16;
> +	case PCI_EXP_SLTCTL: {
> +		u16 slotsta = le16_to_cpu(bridge->pcie_conf.slotsta);
> +		u32 val = 0;
> +		/*
> +		 * When slot power limit was not specified in DT then
> +		 * ASPL_DISABLE bit is stored only in emulated config space.
> +		 * Otherwise reflect status of PCIE_SSPL_ENABLE bit in HW.
> +		 */
> +		if (!port->slot_power_limit_value)
> +			val |= slotctl & PCI_EXP_SLTCTL_ASPL_DISABLE;
> +		else if (!(mvebu_readl(port, PCIE_SSPL_OFF) & PCIE_SSPL_ENABLE))
> +			val |= PCI_EXP_SLTCTL_ASPL_DISABLE;
> +		/* This callback is 32-bit and in high bits is slot status. */
> +		val |= slotsta << 16;
> +		*value = val;
>  		break;
> +	}
>  
>  	case PCI_EXP_RTSTA:
>  		*value = mvebu_readl(port, PCIE_RC_RTSTA);
> @@ -774,6 +811,22 @@ mvebu_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
>  		mvebu_writel(port, new, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL);
>  		break;
>  
> +	case PCI_EXP_SLTCTL:
> +		/*
> +		 * Allow to change PCIE_SSPL_ENABLE bit only when slot power
> +		 * limit was specified in DT and configured into HW.
> +		 */
> +		if ((mask & PCI_EXP_SLTCTL_ASPL_DISABLE) &&
> +		    port->slot_power_limit_value) {
> +			u32 sspl = mvebu_readl(port, PCIE_SSPL_OFF);
> +			if (new & PCI_EXP_SLTCTL_ASPL_DISABLE)
> +				sspl &= ~PCIE_SSPL_ENABLE;
> +			else
> +				sspl |= PCIE_SSPL_ENABLE;
> +			mvebu_writel(port, sspl, PCIE_SSPL_OFF);
> +		}
> +		break;
> +
>  	case PCI_EXP_RTSTA:
>  		/*
>  		 * PME Status bit in Root Status Register (PCIE_RC_RTSTA)
> @@ -868,8 +921,26 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
>  	/*
>  	 * Older mvebu hardware provides PCIe Capability structure only in
>  	 * version 1. New hardware provides it in version 2.
> +	 * Enable slot support which is emulated.
>  	 */
> -	bridge->pcie_conf.cap = cpu_to_le16(pcie_cap_ver);
> +	bridge->pcie_conf.cap = cpu_to_le16(pcie_cap_ver | PCI_EXP_FLAGS_SLOT);
> +
> +	/*
> +	 * Set Presence Detect State bit permanently as there is no support for
> +	 * unplugging PCIe card from the slot. Assume that PCIe card is always
> +	 * connected in slot.
> +	 *
> +	 * Set physical slot number to port+1 as mvebu ports are indexed from
> +	 * zero and zero value is reserved for ports within the same silicon
> +	 * as Root Port which is not mvebu case.
> +	 *
> +	 * Also set correct slot power limit.
> +	 */
> +	bridge->pcie_conf.slotcap = cpu_to_le32(
> +		FIELD_PREP(PCI_EXP_SLTCAP_SPLV, port->slot_power_limit_value) |
> +		FIELD_PREP(PCI_EXP_SLTCAP_SPLS, port->slot_power_limit_scale) |
> +		FIELD_PREP(PCI_EXP_SLTCAP_PSN, port->port+1));
> +	bridge->pcie_conf.slotsta = cpu_to_le16(PCI_EXP_SLTSTA_PDS);
>  
>  	bridge->subsystem_vendor_id = ssdev_id & 0xffff;
>  	bridge->subsystem_id = ssdev_id >> 16;
> @@ -1191,6 +1262,7 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
>  {
>  	struct device *dev = &pcie->pdev->dev;
>  	enum of_gpio_flags flags;
> +	u32 slot_power_limit;
>  	int reset_gpio, ret;
>  	u32 num_lanes;
>  
> @@ -1291,6 +1363,15 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
>  		port->reset_gpio = gpio_to_desc(reset_gpio);
>  	}
>  
> +	slot_power_limit = of_pci_get_slot_power_limit(child,
> +				&port->slot_power_limit_value,
> +				&port->slot_power_limit_scale);
> +	if (slot_power_limit)
> +		dev_info(dev, "%s: Slot power limit %u.%uW\n",
> +			 port->name,
> +			 slot_power_limit / 1000,
> +			 (slot_power_limit / 100) % 10);
> +
>  	port->clk = of_clk_get_by_name(child, NULL);
>  	if (IS_ERR(port->clk)) {
>  		dev_err(dev, "%s: cannot get clock\n", port->name);
> @@ -1587,7 +1668,7 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
>  {
>  	struct mvebu_pcie *pcie = platform_get_drvdata(pdev);
>  	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
> -	u32 cmd;
> +	u32 cmd, sspl;
>  	int i;
>  
>  	/* Remove PCI bus with all devices. */
> @@ -1624,6 +1705,11 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
>  		/* Free config space for emulated root bridge. */
>  		pci_bridge_emul_cleanup(&port->bridge);
>  
> +		/* Disable sending Set_Slot_Power_Limit PCIe Message. */
> +		sspl = mvebu_readl(port, PCIE_SSPL_OFF);
> +		sspl &= ~(PCIE_SSPL_VALUE_MASK | PCIE_SSPL_SCALE_MASK | PCIE_SSPL_ENABLE);
> +		mvebu_writel(port, sspl, PCIE_SSPL_OFF);
> +
>  		/* Disable and clear BARs and windows. */
>  		mvebu_pcie_disable_wins(port);
>  
> -- 
> 2.20.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 4/4] PCI: mvebu: Add support for sending Set_Slot_Power_Limit message
@ 2022-03-24 17:15     ` Bjorn Helgaas
  0 siblings, 0 replies; 26+ messages in thread
From: Bjorn Helgaas @ 2022-03-24 17:15 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King, linux-pci, linux-arm-kernel, linux-kernel

On Wed, Mar 02, 2022 at 03:57:33PM +0100, Pali Rohár wrote:
> If DT supplies the 'slot-power-limit-milliwatt' property, program
> the value in the Slot Power Limit in the Slot Capabilities register
> and program the Root Port to send a Set_Slot_Power_Limit Message
> when the Link transitions to DL_Up.
> 
> Signed-off-by: Pali Rohár <pali@kernel.org>

I didn't review this carefully but have no objection.

> ---
> Changes in v2:
> * Fix handling of slot power limit with scale x1.0 (0x00 value)
> * Use FIELD_PREP instead of _SHIFT macros
> * Changed commit message to Bjorn's suggestion
> * Changed comments in the code to match PCIe spec
> * Preserve user settings of PCI_EXP_SLTCTL_ASPL_DISABLE bit
> ---
>  drivers/pci/controller/pci-mvebu.c | 96 ++++++++++++++++++++++++++++--
>  1 file changed, 91 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c
> index a75d2b9196f9..26ae7c29fece 100644
> --- a/drivers/pci/controller/pci-mvebu.c
> +++ b/drivers/pci/controller/pci-mvebu.c
> @@ -8,6 +8,7 @@
>  #include <linux/kernel.h>
>  #include <linux/module.h>
>  #include <linux/pci.h>
> +#include <linux/bitfield.h>
>  #include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/gpio.h>
> @@ -66,6 +67,12 @@
>  #define  PCIE_STAT_BUS                  0xff00
>  #define  PCIE_STAT_DEV                  0x1f0000
>  #define  PCIE_STAT_LINK_DOWN		BIT(0)
> +#define PCIE_SSPL_OFF		0x1a0c
> +#define  PCIE_SSPL_VALUE_SHIFT		0
> +#define  PCIE_SSPL_VALUE_MASK		GENMASK(7, 0)
> +#define  PCIE_SSPL_SCALE_SHIFT		8
> +#define  PCIE_SSPL_SCALE_MASK		GENMASK(9, 8)
> +#define  PCIE_SSPL_ENABLE		BIT(16)
>  #define PCIE_RC_RTSTA		0x1a14
>  #define PCIE_DEBUG_CTRL         0x1a60
>  #define  PCIE_DEBUG_SOFT_RESET		BIT(20)
> @@ -111,6 +118,8 @@ struct mvebu_pcie_port {
>  	struct mvebu_pcie_window iowin;
>  	u32 saved_pcie_stat;
>  	struct resource regs;
> +	u8 slot_power_limit_value;
> +	u8 slot_power_limit_scale;
>  	struct irq_domain *intx_irq_domain;
>  	raw_spinlock_t irq_lock;
>  	int intx_irq;
> @@ -239,7 +248,7 @@ static void mvebu_pcie_setup_wins(struct mvebu_pcie_port *port)
>  
>  static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
>  {
> -	u32 ctrl, lnkcap, cmd, dev_rev, unmask;
> +	u32 ctrl, lnkcap, cmd, dev_rev, unmask, sspl;
>  
>  	/* Setup PCIe controller to Root Complex mode. */
>  	ctrl = mvebu_readl(port, PCIE_CTRL_OFF);
> @@ -292,6 +301,20 @@ static void mvebu_pcie_setup_hw(struct mvebu_pcie_port *port)
>  	/* Point PCIe unit MBUS decode windows to DRAM space. */
>  	mvebu_pcie_setup_wins(port);
>  
> +	/*
> +	 * Program Root Port to automatically send Set_Slot_Power_Limit
> +	 * PCIe Message when changing status from Dl_Down to Dl_Up and valid
> +	 * slot power limit was specified.
> +	 */
> +	sspl = mvebu_readl(port, PCIE_SSPL_OFF);
> +	sspl &= ~(PCIE_SSPL_VALUE_MASK | PCIE_SSPL_SCALE_MASK | PCIE_SSPL_ENABLE);
> +	if (port->slot_power_limit_value) {
> +		sspl |= port->slot_power_limit_value << PCIE_SSPL_VALUE_SHIFT;
> +		sspl |= port->slot_power_limit_scale << PCIE_SSPL_SCALE_SHIFT;
> +		sspl |= PCIE_SSPL_ENABLE;
> +	}
> +	mvebu_writel(port, sspl, PCIE_SSPL_OFF);
> +
>  	/* Mask all interrupt sources. */
>  	mvebu_writel(port, ~PCIE_INT_ALL_MASK, PCIE_INT_UNMASK_OFF);
>  
> @@ -628,9 +651,23 @@ mvebu_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge,
>  			  (PCI_EXP_LNKSTA_DLLLA << 16) : 0);
>  		break;
>  
> -	case PCI_EXP_SLTCTL:
> -		*value = PCI_EXP_SLTSTA_PDS << 16;
> +	case PCI_EXP_SLTCTL: {
> +		u16 slotsta = le16_to_cpu(bridge->pcie_conf.slotsta);
> +		u32 val = 0;
> +		/*
> +		 * When slot power limit was not specified in DT then
> +		 * ASPL_DISABLE bit is stored only in emulated config space.
> +		 * Otherwise reflect status of PCIE_SSPL_ENABLE bit in HW.
> +		 */
> +		if (!port->slot_power_limit_value)
> +			val |= slotctl & PCI_EXP_SLTCTL_ASPL_DISABLE;
> +		else if (!(mvebu_readl(port, PCIE_SSPL_OFF) & PCIE_SSPL_ENABLE))
> +			val |= PCI_EXP_SLTCTL_ASPL_DISABLE;
> +		/* This callback is 32-bit and in high bits is slot status. */
> +		val |= slotsta << 16;
> +		*value = val;
>  		break;
> +	}
>  
>  	case PCI_EXP_RTSTA:
>  		*value = mvebu_readl(port, PCIE_RC_RTSTA);
> @@ -774,6 +811,22 @@ mvebu_pci_bridge_emul_pcie_conf_write(struct pci_bridge_emul *bridge,
>  		mvebu_writel(port, new, PCIE_CAP_PCIEXP + PCI_EXP_LNKCTL);
>  		break;
>  
> +	case PCI_EXP_SLTCTL:
> +		/*
> +		 * Allow to change PCIE_SSPL_ENABLE bit only when slot power
> +		 * limit was specified in DT and configured into HW.
> +		 */
> +		if ((mask & PCI_EXP_SLTCTL_ASPL_DISABLE) &&
> +		    port->slot_power_limit_value) {
> +			u32 sspl = mvebu_readl(port, PCIE_SSPL_OFF);
> +			if (new & PCI_EXP_SLTCTL_ASPL_DISABLE)
> +				sspl &= ~PCIE_SSPL_ENABLE;
> +			else
> +				sspl |= PCIE_SSPL_ENABLE;
> +			mvebu_writel(port, sspl, PCIE_SSPL_OFF);
> +		}
> +		break;
> +
>  	case PCI_EXP_RTSTA:
>  		/*
>  		 * PME Status bit in Root Status Register (PCIE_RC_RTSTA)
> @@ -868,8 +921,26 @@ static int mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port)
>  	/*
>  	 * Older mvebu hardware provides PCIe Capability structure only in
>  	 * version 1. New hardware provides it in version 2.
> +	 * Enable slot support which is emulated.
>  	 */
> -	bridge->pcie_conf.cap = cpu_to_le16(pcie_cap_ver);
> +	bridge->pcie_conf.cap = cpu_to_le16(pcie_cap_ver | PCI_EXP_FLAGS_SLOT);
> +
> +	/*
> +	 * Set Presence Detect State bit permanently as there is no support for
> +	 * unplugging PCIe card from the slot. Assume that PCIe card is always
> +	 * connected in slot.
> +	 *
> +	 * Set physical slot number to port+1 as mvebu ports are indexed from
> +	 * zero and zero value is reserved for ports within the same silicon
> +	 * as Root Port which is not mvebu case.
> +	 *
> +	 * Also set correct slot power limit.
> +	 */
> +	bridge->pcie_conf.slotcap = cpu_to_le32(
> +		FIELD_PREP(PCI_EXP_SLTCAP_SPLV, port->slot_power_limit_value) |
> +		FIELD_PREP(PCI_EXP_SLTCAP_SPLS, port->slot_power_limit_scale) |
> +		FIELD_PREP(PCI_EXP_SLTCAP_PSN, port->port+1));
> +	bridge->pcie_conf.slotsta = cpu_to_le16(PCI_EXP_SLTSTA_PDS);
>  
>  	bridge->subsystem_vendor_id = ssdev_id & 0xffff;
>  	bridge->subsystem_id = ssdev_id >> 16;
> @@ -1191,6 +1262,7 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
>  {
>  	struct device *dev = &pcie->pdev->dev;
>  	enum of_gpio_flags flags;
> +	u32 slot_power_limit;
>  	int reset_gpio, ret;
>  	u32 num_lanes;
>  
> @@ -1291,6 +1363,15 @@ static int mvebu_pcie_parse_port(struct mvebu_pcie *pcie,
>  		port->reset_gpio = gpio_to_desc(reset_gpio);
>  	}
>  
> +	slot_power_limit = of_pci_get_slot_power_limit(child,
> +				&port->slot_power_limit_value,
> +				&port->slot_power_limit_scale);
> +	if (slot_power_limit)
> +		dev_info(dev, "%s: Slot power limit %u.%uW\n",
> +			 port->name,
> +			 slot_power_limit / 1000,
> +			 (slot_power_limit / 100) % 10);
> +
>  	port->clk = of_clk_get_by_name(child, NULL);
>  	if (IS_ERR(port->clk)) {
>  		dev_err(dev, "%s: cannot get clock\n", port->name);
> @@ -1587,7 +1668,7 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
>  {
>  	struct mvebu_pcie *pcie = platform_get_drvdata(pdev);
>  	struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
> -	u32 cmd;
> +	u32 cmd, sspl;
>  	int i;
>  
>  	/* Remove PCI bus with all devices. */
> @@ -1624,6 +1705,11 @@ static int mvebu_pcie_remove(struct platform_device *pdev)
>  		/* Free config space for emulated root bridge. */
>  		pci_bridge_emul_cleanup(&port->bridge);
>  
> +		/* Disable sending Set_Slot_Power_Limit PCIe Message. */
> +		sspl = mvebu_readl(port, PCIE_SSPL_OFF);
> +		sspl &= ~(PCIE_SSPL_VALUE_MASK | PCIE_SSPL_SCALE_MASK | PCIE_SSPL_ENABLE);
> +		mvebu_writel(port, sspl, PCIE_SSPL_OFF);
> +
>  		/* Disable and clear BARs and windows. */
>  		mvebu_pcie_disable_wins(port);
>  
> -- 
> 2.20.1
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 2/4] dt-bindings: Add 'slot-power-limit-milliwatt' PCIe port property
  2022-03-02 14:57   ` Pali Rohár
@ 2022-03-24 20:47     ` Rob Herring
  -1 siblings, 0 replies; 26+ messages in thread
From: Rob Herring @ 2022-03-24 20:47 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Lorenzo Pieralisi, Bjorn Helgaas, Andrew Lunn, Thomas Petazzoni,
	Krzysztof Wilczyński, Marek Behún, Russell King,
	linux-pci, linux-arm-kernel, linux-kernel

On Wed, Mar 02, 2022 at 03:57:31PM +0100, Pali Rohár wrote:
> This property specifies slot power limit in mW unit. It is a form-factor
> and board specific value and must be initialized by hardware.
> 
> Some PCIe controllers delegate this work to software to allow hardware
> flexibility and therefore this property basically specifies what should
> host bridge program into PCIe Slot Capabilities registers.
> 
> The property needs to be specified in mW unit instead of the special format
> defined by Slot Capabilities (which encodes scaling factor or different
> unit). Host drivers should convert the value from mW to needed format.
> 
> Signed-off-by: Pali Rohár <pali@kernel.org>
> Signed-off-by: Marek Behún <kabel@kernel.org>
> 
> ---
> This change was already accepted into dt-schema repo by Rob Herring:
> https://github.com/devicetree-org/dt-schema/pull/66

Which is the definitive source for it. pci.txt should shrink or be 
removed, not added to.

> ---
>  Documentation/devicetree/bindings/pci/pci.txt | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pci/pci.txt b/Documentation/devicetree/bindings/pci/pci.txt
> index 6a8f2874a24d..b0cc133ed00d 100644
> --- a/Documentation/devicetree/bindings/pci/pci.txt
> +++ b/Documentation/devicetree/bindings/pci/pci.txt
> @@ -32,6 +32,12 @@ driver implementation may support the following properties:
>     root port to downstream device and host bridge drivers can do programming
>     which depends on CLKREQ signal existence. For example, programming root port
>     not to advertise ASPM L1 Sub-States support if there is no CLKREQ signal.
> +- slot-power-limit-milliwatt:
> +   If present, this property specifies slot power limit in milliwatts. Host
> +   drivers can parse this property and use it for programming Root Port or host
> +   bridge, or for composing and sending PCIe Set_Slot_Power_Limit messages
> +   through the Root Port or host bridge when transitioning PCIe link from a
> +   non-DL_Up Status to a DL_Up Status.
>  
>  PCI-PCI Bridge properties
>  -------------------------
> -- 
> 2.20.1
> 

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 2/4] dt-bindings: Add 'slot-power-limit-milliwatt' PCIe port property
@ 2022-03-24 20:47     ` Rob Herring
  0 siblings, 0 replies; 26+ messages in thread
From: Rob Herring @ 2022-03-24 20:47 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Lorenzo Pieralisi, Bjorn Helgaas, Andrew Lunn, Thomas Petazzoni,
	Krzysztof Wilczyński, Marek Behún, Russell King,
	linux-pci, linux-arm-kernel, linux-kernel

On Wed, Mar 02, 2022 at 03:57:31PM +0100, Pali Rohár wrote:
> This property specifies slot power limit in mW unit. It is a form-factor
> and board specific value and must be initialized by hardware.
> 
> Some PCIe controllers delegate this work to software to allow hardware
> flexibility and therefore this property basically specifies what should
> host bridge program into PCIe Slot Capabilities registers.
> 
> The property needs to be specified in mW unit instead of the special format
> defined by Slot Capabilities (which encodes scaling factor or different
> unit). Host drivers should convert the value from mW to needed format.
> 
> Signed-off-by: Pali Rohár <pali@kernel.org>
> Signed-off-by: Marek Behún <kabel@kernel.org>
> 
> ---
> This change was already accepted into dt-schema repo by Rob Herring:
> https://github.com/devicetree-org/dt-schema/pull/66

Which is the definitive source for it. pci.txt should shrink or be 
removed, not added to.

> ---
>  Documentation/devicetree/bindings/pci/pci.txt | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/pci/pci.txt b/Documentation/devicetree/bindings/pci/pci.txt
> index 6a8f2874a24d..b0cc133ed00d 100644
> --- a/Documentation/devicetree/bindings/pci/pci.txt
> +++ b/Documentation/devicetree/bindings/pci/pci.txt
> @@ -32,6 +32,12 @@ driver implementation may support the following properties:
>     root port to downstream device and host bridge drivers can do programming
>     which depends on CLKREQ signal existence. For example, programming root port
>     not to advertise ASPM L1 Sub-States support if there is no CLKREQ signal.
> +- slot-power-limit-milliwatt:
> +   If present, this property specifies slot power limit in milliwatts. Host
> +   drivers can parse this property and use it for programming Root Port or host
> +   bridge, or for composing and sending PCIe Set_Slot_Power_Limit messages
> +   through the Root Port or host bridge when transitioning PCIe link from a
> +   non-DL_Up Status to a DL_Up Status.
>  
>  PCI-PCI Bridge properties
>  -------------------------
> -- 
> 2.20.1
> 

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 4/4] PCI: mvebu: Add support for sending Set_Slot_Power_Limit message
  2022-03-02 14:57   ` Pali Rohár
@ 2022-03-24 20:50     ` Rob Herring
  -1 siblings, 0 replies; 26+ messages in thread
From: Rob Herring @ 2022-03-24 20:50 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Lorenzo Pieralisi, Bjorn Helgaas, Andrew Lunn, Thomas Petazzoni,
	Krzysztof Wilczyński, Marek Behún, Russell King,
	linux-pci, linux-arm-kernel, linux-kernel

On Wed, Mar 02, 2022 at 03:57:33PM +0100, Pali Rohár wrote:
> If DT supplies the 'slot-power-limit-milliwatt' property, program
> the value in the Slot Power Limit in the Slot Capabilities register
> and program the Root Port to send a Set_Slot_Power_Limit Message
> when the Link transitions to DL_Up.
> 
> Signed-off-by: Pali Rohár <pali@kernel.org>
> ---
> Changes in v2:
> * Fix handling of slot power limit with scale x1.0 (0x00 value)
> * Use FIELD_PREP instead of _SHIFT macros
> * Changed commit message to Bjorn's suggestion
> * Changed comments in the code to match PCIe spec
> * Preserve user settings of PCI_EXP_SLTCTL_ASPL_DISABLE bit
> ---
>  drivers/pci/controller/pci-mvebu.c | 96 ++++++++++++++++++++++++++++--
>  1 file changed, 91 insertions(+), 5 deletions(-)

Reviewed-by: Rob Herring <robh@kernel.org>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 4/4] PCI: mvebu: Add support for sending Set_Slot_Power_Limit message
@ 2022-03-24 20:50     ` Rob Herring
  0 siblings, 0 replies; 26+ messages in thread
From: Rob Herring @ 2022-03-24 20:50 UTC (permalink / raw)
  To: Pali Rohár
  Cc: Lorenzo Pieralisi, Bjorn Helgaas, Andrew Lunn, Thomas Petazzoni,
	Krzysztof Wilczyński, Marek Behún, Russell King,
	linux-pci, linux-arm-kernel, linux-kernel

On Wed, Mar 02, 2022 at 03:57:33PM +0100, Pali Rohár wrote:
> If DT supplies the 'slot-power-limit-milliwatt' property, program
> the value in the Slot Power Limit in the Slot Capabilities register
> and program the Root Port to send a Set_Slot_Power_Limit Message
> when the Link transitions to DL_Up.
> 
> Signed-off-by: Pali Rohár <pali@kernel.org>
> ---
> Changes in v2:
> * Fix handling of slot power limit with scale x1.0 (0x00 value)
> * Use FIELD_PREP instead of _SHIFT macros
> * Changed commit message to Bjorn's suggestion
> * Changed comments in the code to match PCIe spec
> * Preserve user settings of PCI_EXP_SLTCTL_ASPL_DISABLE bit
> ---
>  drivers/pci/controller/pci-mvebu.c | 96 ++++++++++++++++++++++++++++--
>  1 file changed, 91 insertions(+), 5 deletions(-)

Reviewed-by: Rob Herring <robh@kernel.org>

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 3/4] PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property
  2022-03-24 17:13     ` Bjorn Helgaas
@ 2022-03-25  9:20       ` Pali Rohár
  -1 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2022-03-25  9:20 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King, linux-pci, linux-arm-kernel, linux-kernel

On Thursday 24 March 2022 12:13:37 Bjorn Helgaas wrote:
> On Wed, Mar 02, 2022 at 03:57:32PM +0100, Pali Rohár wrote:
> > Add function of_pci_get_slot_power_limit(), which parses the
> > 'slot-power-limit-milliwatt' DT property, returning the value in
> > milliwatts and in format ready for the PCIe Slot Capabilities Register.
> > 
> > Signed-off-by: Pali Rohár <pali@kernel.org>
> > Signed-off-by: Marek Behún <kabel@kernel.org>
> > Reviewed-by: Rob Herring <robh@kernel.org>
> > ---
> > Changes in v2:
> > * Added support for PCIe 6.0 slot power limit encodings
> > * Round down slot power limit value
> > ---
> >  drivers/pci/of.c  | 64 +++++++++++++++++++++++++++++++++++++++++++++++
> >  drivers/pci/pci.h | 15 +++++++++++
> >  2 files changed, 79 insertions(+)
> > 
> > diff --git a/drivers/pci/of.c b/drivers/pci/of.c
> > index cb2e8351c2cc..549a404bd536 100644
> > --- a/drivers/pci/of.c
> > +++ b/drivers/pci/of.c
> > @@ -633,3 +633,67 @@ int of_pci_get_max_link_speed(struct device_node *node)
> >  	return max_link_speed;
> >  }
> >  EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed);
> > +
> > +/**
> > + * of_pci_get_slot_power_limit - Parses the "slot-power-limit-milliwatt"
> > + *				 property.
> > + *
> > + * @node: device tree node with the slot power limit information
> > + * @slot_power_limit_value: pointer where the value should be stored in PCIe
> > + *			    Slot Capabilities Register format
> > + * @slot_power_limit_scale: pointer where the scale should be stored in PCIe
> > + *			    Slot Capabilities Register format
> > + *
> > + * Returns the slot power limit in milliwatts and if @slot_power_limit_value
> > + * and @slot_power_limit_scale pointers are non-NULL, fills in the value and
> > + * scale in format used by PCIe Slot Capabilities Register.
> > + *
> > + * If the property is not found or is invalid, returns 0.
> > + */
> > +u32 of_pci_get_slot_power_limit(struct device_node *node,
> > +				u8 *slot_power_limit_value,
> > +				u8 *slot_power_limit_scale)
> > +{
> > +	u32 slot_power_limit_mw;
> > +	u8 value, scale;
> > +
> > +	if (of_property_read_u32(node, "slot-power-limit-milliwatt",
> > +				 &slot_power_limit_mw))
> > +		slot_power_limit_mw = 0;
> > +
> > +	/* Calculate Slot Power Limit Value and Slot Power Limit Scale */
> > +	if (slot_power_limit_mw == 0) {
> > +		value = 0x00;
> > +		scale = 0;
> > +	} else if (slot_power_limit_mw <= 255) {
> > +		value = slot_power_limit_mw;
> > +		scale = 3;
> > +	} else if (slot_power_limit_mw <= 255*10) {
> > +		value = slot_power_limit_mw / 10;
> > +		scale = 2;
> > +	} else if (slot_power_limit_mw <= 255*100) {
> > +		value = slot_power_limit_mw / 100;
> > +		scale = 1;
> > +	} else if (slot_power_limit_mw <= 239*1000) {
> > +		value = slot_power_limit_mw / 1000;
> > +		scale = 0;
> > +	} else if (slot_power_limit_mw <= 250*1000) {
> > +		value = 0xF0;
> > +		scale = 0;
> > +	} else if (slot_power_limit_mw <= 600*1000) {
> > +		value = 0xF0 + (slot_power_limit_mw / 1000 - 250) / 25;
> > +		scale = 0;
> > +	} else {
> > +		value = 0xFF;
> > +		scale = 0;
> 
> The purpose of this function is to return values that can be
> programmed into the Slot Capabilities register.  The 0xFF Slot Power
> Limit Value is reserved, and I don't think we should use it until the
> spec defines a meaning for it.
> 
> If the DT tells us 800W is available, we'll put 0xFF in Slot Power
> Limit Value.  If the spec eventually defines (0xFF, 0) to mean "1000W
> available", a device may try to consume all 1000W, which will not
> work.
> 
> If slot_power_limit_mw > 600*1000, I think we should advertise 600W
> available (value 0xFE, scale 0) and return 600W (600*1000).
> 
> Bjorn

Ok, I will send a v3 with this change.

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH v2 3/4] PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property
@ 2022-03-25  9:20       ` Pali Rohár
  0 siblings, 0 replies; 26+ messages in thread
From: Pali Rohár @ 2022-03-25  9:20 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Lorenzo Pieralisi, Bjorn Helgaas, Rob Herring, Andrew Lunn,
	Thomas Petazzoni, Krzysztof Wilczyński, Marek Behún,
	Russell King, linux-pci, linux-arm-kernel, linux-kernel

On Thursday 24 March 2022 12:13:37 Bjorn Helgaas wrote:
> On Wed, Mar 02, 2022 at 03:57:32PM +0100, Pali Rohár wrote:
> > Add function of_pci_get_slot_power_limit(), which parses the
> > 'slot-power-limit-milliwatt' DT property, returning the value in
> > milliwatts and in format ready for the PCIe Slot Capabilities Register.
> > 
> > Signed-off-by: Pali Rohár <pali@kernel.org>
> > Signed-off-by: Marek Behún <kabel@kernel.org>
> > Reviewed-by: Rob Herring <robh@kernel.org>
> > ---
> > Changes in v2:
> > * Added support for PCIe 6.0 slot power limit encodings
> > * Round down slot power limit value
> > ---
> >  drivers/pci/of.c  | 64 +++++++++++++++++++++++++++++++++++++++++++++++
> >  drivers/pci/pci.h | 15 +++++++++++
> >  2 files changed, 79 insertions(+)
> > 
> > diff --git a/drivers/pci/of.c b/drivers/pci/of.c
> > index cb2e8351c2cc..549a404bd536 100644
> > --- a/drivers/pci/of.c
> > +++ b/drivers/pci/of.c
> > @@ -633,3 +633,67 @@ int of_pci_get_max_link_speed(struct device_node *node)
> >  	return max_link_speed;
> >  }
> >  EXPORT_SYMBOL_GPL(of_pci_get_max_link_speed);
> > +
> > +/**
> > + * of_pci_get_slot_power_limit - Parses the "slot-power-limit-milliwatt"
> > + *				 property.
> > + *
> > + * @node: device tree node with the slot power limit information
> > + * @slot_power_limit_value: pointer where the value should be stored in PCIe
> > + *			    Slot Capabilities Register format
> > + * @slot_power_limit_scale: pointer where the scale should be stored in PCIe
> > + *			    Slot Capabilities Register format
> > + *
> > + * Returns the slot power limit in milliwatts and if @slot_power_limit_value
> > + * and @slot_power_limit_scale pointers are non-NULL, fills in the value and
> > + * scale in format used by PCIe Slot Capabilities Register.
> > + *
> > + * If the property is not found or is invalid, returns 0.
> > + */
> > +u32 of_pci_get_slot_power_limit(struct device_node *node,
> > +				u8 *slot_power_limit_value,
> > +				u8 *slot_power_limit_scale)
> > +{
> > +	u32 slot_power_limit_mw;
> > +	u8 value, scale;
> > +
> > +	if (of_property_read_u32(node, "slot-power-limit-milliwatt",
> > +				 &slot_power_limit_mw))
> > +		slot_power_limit_mw = 0;
> > +
> > +	/* Calculate Slot Power Limit Value and Slot Power Limit Scale */
> > +	if (slot_power_limit_mw == 0) {
> > +		value = 0x00;
> > +		scale = 0;
> > +	} else if (slot_power_limit_mw <= 255) {
> > +		value = slot_power_limit_mw;
> > +		scale = 3;
> > +	} else if (slot_power_limit_mw <= 255*10) {
> > +		value = slot_power_limit_mw / 10;
> > +		scale = 2;
> > +	} else if (slot_power_limit_mw <= 255*100) {
> > +		value = slot_power_limit_mw / 100;
> > +		scale = 1;
> > +	} else if (slot_power_limit_mw <= 239*1000) {
> > +		value = slot_power_limit_mw / 1000;
> > +		scale = 0;
> > +	} else if (slot_power_limit_mw <= 250*1000) {
> > +		value = 0xF0;
> > +		scale = 0;
> > +	} else if (slot_power_limit_mw <= 600*1000) {
> > +		value = 0xF0 + (slot_power_limit_mw / 1000 - 250) / 25;
> > +		scale = 0;
> > +	} else {
> > +		value = 0xFF;
> > +		scale = 0;
> 
> The purpose of this function is to return values that can be
> programmed into the Slot Capabilities register.  The 0xFF Slot Power
> Limit Value is reserved, and I don't think we should use it until the
> spec defines a meaning for it.
> 
> If the DT tells us 800W is available, we'll put 0xFF in Slot Power
> Limit Value.  If the spec eventually defines (0xFF, 0) to mean "1000W
> available", a device may try to consume all 1000W, which will not
> work.
> 
> If slot_power_limit_mw > 600*1000, I think we should advertise 600W
> available (value 0xFE, scale 0) and return 600W (600*1000).
> 
> Bjorn

Ok, I will send a v3 with this change.

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2022-03-25  9:21 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-03-02 14:57 [PATCH v2 0/4] PCI: mvebu: Slot support Pali Rohár
2022-03-02 14:57 ` Pali Rohár
2022-03-02 14:57 ` [PATCH v2 1/4] PCI: Add PCI_EXP_SLTCTL_ASPL_DISABLE macro Pali Rohár
2022-03-02 14:57   ` Pali Rohár
2022-03-02 14:57 ` [PATCH v2 2/4] dt-bindings: Add 'slot-power-limit-milliwatt' PCIe port property Pali Rohár
2022-03-02 14:57   ` Pali Rohár
2022-03-24 20:47   ` Rob Herring
2022-03-24 20:47     ` Rob Herring
2022-03-02 14:57 ` [PATCH v2 3/4] PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property Pali Rohár
2022-03-02 14:57   ` Pali Rohár
2022-03-24 17:13   ` Bjorn Helgaas
2022-03-24 17:13     ` Bjorn Helgaas
2022-03-25  9:20     ` Pali Rohár
2022-03-25  9:20       ` Pali Rohár
2022-03-02 14:57 ` [PATCH v2 4/4] PCI: mvebu: Add support for sending Set_Slot_Power_Limit message Pali Rohár
2022-03-02 14:57   ` Pali Rohár
2022-03-24 17:15   ` Bjorn Helgaas
2022-03-24 17:15     ` Bjorn Helgaas
2022-03-24 20:50   ` Rob Herring
2022-03-24 20:50     ` Rob Herring
2022-03-08 11:38 ` [PATCH v2 0/4] PCI: mvebu: Slot support Pali Rohár
2022-03-08 11:38   ` Pali Rohár
2022-03-21 18:29   ` Pali Rohár
2022-03-21 18:29     ` Pali Rohár
2022-03-24 17:12     ` Bjorn Helgaas
2022-03-24 17:12       ` Bjorn Helgaas

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.