1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * PCI Endpoint *Controller* Address Space Management 4 * 5 * Copyright (C) 2017 Texas Instruments 6 * Author: Kishon Vijay Abraham I <kishon@ti.com> 7 */ 8 9 #include <linux/io.h> 10 #include <linux/module.h> 11 #include <linux/slab.h> 12 13 #include <linux/pci-epc.h> 14 15 /** 16 * pci_epc_mem_get_order() - determine the allocation order of a memory size 17 * @mem: address space of the endpoint controller 18 * @size: the size for which to get the order 19 * 20 * Reimplement get_order() for mem->page_size since the generic get_order 21 * always gets order with a constant PAGE_SIZE. 22 */ 23 static int pci_epc_mem_get_order(struct pci_epc_mem *mem, size_t size) 24 { 25 int order; 26 unsigned int page_shift = ilog2(mem->window.page_size); 27 28 size--; 29 size >>= page_shift; 30 #if BITS_PER_LONG == 32 31 order = fls(size); 32 #else 33 order = fls64(size); 34 #endif 35 return order; 36 } 37 38 /** 39 * pci_epc_multi_mem_init() - initialize the pci_epc_mem structure 40 * @epc: the EPC device that invoked pci_epc_mem_init 41 * @windows: pointer to windows supported by the device 42 * @num_windows: number of windows device supports 43 * 44 * Invoke to initialize the pci_epc_mem structure used by the 45 * endpoint functions to allocate mapped PCI address. 46 */ 47 int pci_epc_multi_mem_init(struct pci_epc *epc, 48 struct pci_epc_mem_window *windows, 49 unsigned int num_windows) 50 { 51 struct pci_epc_mem *mem = NULL; 52 unsigned long *bitmap = NULL; 53 unsigned int page_shift; 54 size_t page_size; 55 int bitmap_size; 56 int pages; 57 int ret; 58 int i; 59 60 epc->num_windows = 0; 61 62 if (!windows || !num_windows) 63 return -EINVAL; 64 65 epc->windows = kcalloc(num_windows, sizeof(*epc->windows), GFP_KERNEL); 66 if (!epc->windows) 67 return -ENOMEM; 68 69 for (i = 0; i < num_windows; i++) { 70 page_size = windows[i].page_size; 71 if (page_size < PAGE_SIZE) 72 page_size = PAGE_SIZE; 73 page_shift = ilog2(page_size); 74 pages = windows[i].size >> page_shift; 75 bitmap_size = BITS_TO_LONGS(pages) * sizeof(long); 76 77 mem = kzalloc(sizeof(*mem), GFP_KERNEL); 78 if (!mem) { 79 ret = -ENOMEM; 80 i--; 81 goto err_mem; 82 } 83 84 bitmap = kzalloc(bitmap_size, GFP_KERNEL); 85 if (!bitmap) { 86 ret = -ENOMEM; 87 kfree(mem); 88 i--; 89 goto err_mem; 90 } 91 92 mem->window.phys_base = windows[i].phys_base; 93 mem->window.size = windows[i].size; 94 mem->window.page_size = page_size; 95 mem->bitmap = bitmap; 96 mem->pages = pages; 97 mutex_init(&mem->lock); 98 epc->windows[i] = mem; 99 } 100 101 epc->mem = epc->windows[0]; 102 epc->num_windows = num_windows; 103 104 return 0; 105 106 err_mem: 107 for (; i >= 0; i--) { 108 mem = epc->windows[i]; 109 kfree(mem->bitmap); 110 kfree(mem); 111 } 112 kfree(epc->windows); 113 114 return ret; 115 } 116 EXPORT_SYMBOL_GPL(pci_epc_multi_mem_init); 117 118 /** 119 * pci_epc_mem_init() - Initialize the pci_epc_mem structure 120 * @epc: the EPC device that invoked pci_epc_mem_init 121 * @base: Physical address of the window region 122 * @size: Total Size of the window region 123 * @page_size: Page size of the window region 124 * 125 * Invoke to initialize a single pci_epc_mem structure used by the 126 * endpoint functions to allocate memory for mapping the PCI host memory 127 */ 128 int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t base, 129 size_t size, size_t page_size) 130 { 131 struct pci_epc_mem_window mem_window; 132 133 mem_window.phys_base = base; 134 mem_window.size = size; 135 mem_window.page_size = page_size; 136 137 return pci_epc_multi_mem_init(epc, &mem_window, 1); 138 } 139 EXPORT_SYMBOL_GPL(pci_epc_mem_init); 140 141 /** 142 * pci_epc_mem_exit() - cleanup the pci_epc_mem structure 143 * @epc: the EPC device that invoked pci_epc_mem_exit 144 * 145 * Invoke to cleanup the pci_epc_mem structure allocated in 146 * pci_epc_mem_init(). 147 */ 148 void pci_epc_mem_exit(struct pci_epc *epc) 149 { 150 struct pci_epc_mem *mem; 151 int i; 152 153 if (!epc->num_windows) 154 return; 155 156 for (i = 0; i < epc->num_windows; i++) { 157 mem = epc->windows[i]; 158 kfree(mem->bitmap); 159 kfree(mem); 160 } 161 kfree(epc->windows); 162 163 epc->windows = NULL; 164 epc->mem = NULL; 165 epc->num_windows = 0; 166 } 167 EXPORT_SYMBOL_GPL(pci_epc_mem_exit); 168 169 /** 170 * pci_epc_mem_alloc_addr() - allocate memory address from EPC addr space 171 * @epc: the EPC device on which memory has to be allocated 172 * @phys_addr: populate the allocated physical address here 173 * @size: the size of the address space that has to be allocated 174 * 175 * Invoke to allocate memory address from the EPC address space. This 176 * is usually done to map the remote RC address into the local system. 177 */ 178 void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc, 179 phys_addr_t *phys_addr, size_t size) 180 { 181 void __iomem *virt_addr = NULL; 182 struct pci_epc_mem *mem; 183 unsigned int page_shift; 184 size_t align_size; 185 int pageno; 186 int order; 187 int i; 188 189 for (i = 0; i < epc->num_windows; i++) { 190 mem = epc->windows[i]; 191 mutex_lock(&mem->lock); 192 align_size = ALIGN(size, mem->window.page_size); 193 order = pci_epc_mem_get_order(mem, align_size); 194 195 pageno = bitmap_find_free_region(mem->bitmap, mem->pages, 196 order); 197 if (pageno >= 0) { 198 page_shift = ilog2(mem->window.page_size); 199 *phys_addr = mem->window.phys_base + 200 ((phys_addr_t)pageno << page_shift); 201 virt_addr = ioremap(*phys_addr, align_size); 202 if (!virt_addr) { 203 bitmap_release_region(mem->bitmap, 204 pageno, order); 205 mutex_unlock(&mem->lock); 206 continue; 207 } 208 mutex_unlock(&mem->lock); 209 return virt_addr; 210 } 211 mutex_unlock(&mem->lock); 212 } 213 214 return virt_addr; 215 } 216 EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr); 217 218 static struct pci_epc_mem *pci_epc_get_matching_window(struct pci_epc *epc, 219 phys_addr_t phys_addr) 220 { 221 struct pci_epc_mem *mem; 222 int i; 223 224 for (i = 0; i < epc->num_windows; i++) { 225 mem = epc->windows[i]; 226 227 if (phys_addr >= mem->window.phys_base && 228 phys_addr < (mem->window.phys_base + mem->window.size)) 229 return mem; 230 } 231 232 return NULL; 233 } 234 235 /** 236 * pci_epc_mem_free_addr() - free the allocated memory address 237 * @epc: the EPC device on which memory was allocated 238 * @phys_addr: the allocated physical address 239 * @virt_addr: virtual address of the allocated mem space 240 * @size: the size of the allocated address space 241 * 242 * Invoke to free the memory allocated using pci_epc_mem_alloc_addr. 243 */ 244 void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr, 245 void __iomem *virt_addr, size_t size) 246 { 247 struct pci_epc_mem *mem; 248 unsigned int page_shift; 249 size_t page_size; 250 int pageno; 251 int order; 252 253 mem = pci_epc_get_matching_window(epc, phys_addr); 254 if (!mem) { 255 pr_err("failed to get matching window\n"); 256 return; 257 } 258 259 page_size = mem->window.page_size; 260 page_shift = ilog2(page_size); 261 iounmap(virt_addr); 262 pageno = (phys_addr - mem->window.phys_base) >> page_shift; 263 size = ALIGN(size, page_size); 264 order = pci_epc_mem_get_order(mem, size); 265 mutex_lock(&mem->lock); 266 bitmap_release_region(mem->bitmap, pageno, order); 267 mutex_unlock(&mem->lock); 268 } 269 EXPORT_SYMBOL_GPL(pci_epc_mem_free_addr); 270 271 MODULE_DESCRIPTION("PCI EPC Address Space Management"); 272 MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>"); 273