1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2025 Intel Corporation 4 */ 5 6 #include <linux/pci.h> 7 #include <linux/types.h> 8 9 #include "regs/xe_bars.h" 10 #include "xe_device_types.h" 11 #include "xe_module.h" 12 #include "xe_pci_rebar.h" 13 #include "xe_printk.h" 14 15 static void resize_bar(struct xe_device *xe, int resno, resource_size_t size) 16 { 17 struct pci_dev *pdev = to_pci_dev(xe->drm.dev); 18 int bar_size = pci_rebar_bytes_to_size(size); 19 int ret; 20 21 ret = pci_resize_resource(pdev, resno, bar_size, 0); 22 if (ret) { 23 xe_info(xe, "Failed to resize BAR%d to %dMiB (%pe). Consider enabling 'Resizable BAR' support in your BIOS\n", 24 resno, 1 << bar_size, ERR_PTR(ret)); 25 return; 26 } 27 28 xe_info(xe, "BAR%d resized to %dMiB\n", resno, 1 << bar_size); 29 } 30 31 /* 32 * xe_pci_rebar_resize - Resize the LMEMBAR 33 * @xe: xe device instance 34 * 35 * If vram_bar_size module param is set, attempt to set to the requested size 36 * else set to maximum possible size. 37 */ 38 void xe_pci_rebar_resize(struct xe_device *xe) 39 { 40 int force_vram_bar_size = xe_modparam.force_vram_bar_size; 41 struct pci_dev *pdev = to_pci_dev(xe->drm.dev); 42 struct pci_bus *root = pdev->bus; 43 resource_size_t current_size; 44 resource_size_t rebar_size; 45 struct resource *root_res; 46 int max_size, i; 47 u32 pci_cmd; 48 49 /* gather some relevant info */ 50 current_size = pci_resource_len(pdev, LMEM_BAR); 51 52 if (force_vram_bar_size < 0) 53 return; 54 55 /* set to a specific size? */ 56 if (force_vram_bar_size) { 57 rebar_size = pci_rebar_bytes_to_size(force_vram_bar_size * 58 (resource_size_t)SZ_1M); 59 60 if (!pci_rebar_size_supported(pdev, LMEM_BAR, rebar_size)) { 61 xe_info(xe, "Requested size %lluMiB is not supported by rebar sizes: 0x%llx. Leaving default: %lluMiB\n", 62 (u64)pci_rebar_size_to_bytes(rebar_size) >> ilog2(SZ_1M), 63 pci_rebar_get_possible_sizes(pdev, LMEM_BAR), 64 (u64)current_size >> ilog2(SZ_1M)); 65 return; 66 } 67 68 rebar_size = pci_rebar_size_to_bytes(rebar_size); 69 if (rebar_size == current_size) 70 return; 71 } else { 72 max_size = pci_rebar_get_max_size(pdev, LMEM_BAR); 73 if (max_size < 0) 74 return; 75 rebar_size = pci_rebar_size_to_bytes(max_size); 76 77 /* only resize if larger than current */ 78 if (rebar_size <= current_size) 79 return; 80 } 81 82 xe_info(xe, "Attempting to resize bar from %lluMiB -> %lluMiB\n", 83 (u64)current_size >> ilog2(SZ_1M), (u64)rebar_size >> ilog2(SZ_1M)); 84 85 while (root->parent) 86 root = root->parent; 87 88 pci_bus_for_each_resource(root, root_res, i) { 89 if (root_res && root_res->flags & (IORESOURCE_MEM | IORESOURCE_MEM_64) && 90 (u64)root_res->start > 0x100000000ul) 91 break; 92 } 93 94 if (!root_res) { 95 xe_info(xe, "Can't resize VRAM BAR - platform support is missing. Consider enabling 'Resizable BAR' support in your BIOS\n"); 96 return; 97 } 98 99 pci_read_config_dword(pdev, PCI_COMMAND, &pci_cmd); 100 pci_write_config_dword(pdev, PCI_COMMAND, pci_cmd & ~PCI_COMMAND_MEMORY); 101 102 resize_bar(xe, LMEM_BAR, rebar_size); 103 104 pci_assign_unassigned_bus_resources(pdev->bus); 105 pci_write_config_dword(pdev, PCI_COMMAND, pci_cmd); 106 } 107