diff options
Diffstat (limited to 'drivers/pci/rebar.c')
| -rw-r--r-- | drivers/pci/rebar.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/pci/rebar.c b/drivers/pci/rebar.c index f6ed7e4893a7..f29810fe0a58 100644 --- a/drivers/pci/rebar.c +++ b/drivers/pci/rebar.c @@ -7,11 +7,34 @@ #include <linux/errno.h> #include <linux/export.h> #include <linux/ioport.h> +#include <linux/log2.h> #include <linux/pci.h> +#include <linux/sizes.h> #include <linux/types.h> #include "pci.h" +#define PCI_REBAR_MIN_SIZE ((resource_size_t)SZ_1M) + +/** + * pci_rebar_bytes_to_size - Convert size in bytes to PCI BAR Size + * @bytes: size in bytes + * + * Convert size in bytes to encoded BAR Size in Resizable BAR Capability + * (PCIe r6.2, sec. 7.8.6.3). + * + * Return: encoded BAR Size as defined in the PCIe spec (0=1MB, 31=128TB) + */ +int pci_rebar_bytes_to_size(u64 bytes) +{ + int rebar_minsize = ilog2(PCI_REBAR_MIN_SIZE); + + bytes = roundup_pow_of_two(bytes); + + return max(ilog2(bytes), rebar_minsize) - rebar_minsize; +} +EXPORT_SYMBOL_GPL(pci_rebar_bytes_to_size); + void pci_rebar_init(struct pci_dev *pdev) { pdev->rebar_cap = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_REBAR); |
