diff options
author | Pali Rohár <pali@kernel.org> | 2022-04-12 11:49:45 +0200 |
---|---|---|
committer | Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> | 2022-04-25 11:53:39 +0200 |
commit | 35662423fb879dd0f32b7beae71fc5f6d8abf45c (patch) | |
tree | f1a19a5749d95a8d8c694389f98da83d6bf20627 /drivers/pci/of.c | |
parent | PCI: Add PCI_EXP_SLTCTL_ASPL_DISABLE macro (diff) | |
download | linux-35662423fb879dd0f32b7beae71fc5f6d8abf45c.tar.xz linux-35662423fb879dd0f32b7beae71fc5f6d8abf45c.zip |
PCI: Add function for parsing 'slot-power-limit-milliwatt' DT property
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.
Link: https://lore.kernel.org/r/20220412094946.27069-4-pali@kernel.org
Signed-off-by: Pali Rohár <pali@kernel.org>
Signed-off-by: Marek Behún <kabel@kernel.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: Rob Herring <robh@kernel.org>
Reviewed-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/of.c')
-rw-r--r-- | drivers/pci/of.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/drivers/pci/of.c b/drivers/pci/of.c index cb2e8351c2cc..6c1b81304665 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -633,3 +633,73 @@ 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; + slot_power_limit_mw = slot_power_limit_mw / 10 * 10; + } else if (slot_power_limit_mw <= 255*100) { + value = slot_power_limit_mw / 100; + scale = 1; + slot_power_limit_mw = slot_power_limit_mw / 100 * 100; + } else if (slot_power_limit_mw <= 239*1000) { + value = slot_power_limit_mw / 1000; + scale = 0; + slot_power_limit_mw = slot_power_limit_mw / 1000 * 1000; + } else if (slot_power_limit_mw < 250*1000) { + value = 0xEF; + scale = 0; + slot_power_limit_mw = 239*1000; + } else if (slot_power_limit_mw <= 600*1000) { + value = 0xF0 + (slot_power_limit_mw / 1000 - 250) / 25; + scale = 0; + slot_power_limit_mw = slot_power_limit_mw / (1000*25) * (1000*25); + } else { + value = 0xFE; + scale = 0; + slot_power_limit_mw = 600*1000; + } + + 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); |