1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2023 Intel Corporation 4 */ 5 6 #include <linux/align.h> 7 8 #include <drm/drm_managed.h> 9 10 #include "regs/xe_gt_regs.h" 11 12 #include "xe_assert.h" 13 #include "xe_bo.h" 14 #include "xe_lmtt.h" 15 #include "xe_map.h" 16 #include "xe_mmio.h" 17 #include "xe_res_cursor.h" 18 #include "xe_sriov.h" 19 #include "xe_sriov_printk.h" 20 21 /** 22 * DOC: Local Memory Translation Table 23 * 24 * The Local Memory Translation Table (LMTT) provides additional abstraction 25 * when Virtual Function (VF) is accessing device Local Memory (VRAM). 26 * 27 * The Root LMTT Page Directory contains one entry for each VF. Entries are 28 * indexed by the function number (1-based, index 0 is unused). 29 * 30 * See `Two-Level LMTT Structure`_ and `Multi-Level LMTT Structure`_. 31 */ 32 33 #define lmtt_assert(lmtt, condition) xe_tile_assert(lmtt_to_tile(lmtt), condition) 34 #define lmtt_debug(lmtt, msg...) xe_sriov_dbg_verbose(lmtt_to_xe(lmtt), "LMTT: " msg) 35 36 static bool xe_has_multi_level_lmtt(struct xe_device *xe) 37 { 38 return GRAPHICS_VERx100(xe) >= 1260; 39 } 40 41 static struct xe_tile *lmtt_to_tile(struct xe_lmtt *lmtt) 42 { 43 return container_of(lmtt, struct xe_tile, sriov.pf.lmtt); 44 } 45 46 static struct xe_device *lmtt_to_xe(struct xe_lmtt *lmtt) 47 { 48 return tile_to_xe(lmtt_to_tile(lmtt)); 49 } 50 51 static u64 lmtt_page_size(struct xe_lmtt *lmtt) 52 { 53 return BIT_ULL(lmtt->ops->lmtt_pte_shift(0)); 54 } 55 56 static struct xe_lmtt_pt *lmtt_pt_alloc(struct xe_lmtt *lmtt, unsigned int level) 57 { 58 unsigned int num_entries = level ? lmtt->ops->lmtt_pte_num(level) : 0; 59 struct xe_lmtt_pt *pt; 60 struct xe_bo *bo; 61 int err; 62 63 pt = kzalloc(struct_size(pt, entries, num_entries), GFP_KERNEL); 64 if (!pt) { 65 err = -ENOMEM; 66 goto out; 67 } 68 69 bo = xe_bo_create_pin_map(lmtt_to_xe(lmtt), lmtt_to_tile(lmtt), NULL, 70 PAGE_ALIGN(lmtt->ops->lmtt_pte_size(level) * 71 lmtt->ops->lmtt_pte_num(level)), 72 ttm_bo_type_kernel, 73 XE_BO_FLAG_VRAM_IF_DGFX(lmtt_to_tile(lmtt)) | 74 XE_BO_FLAG_NEEDS_64K); 75 if (IS_ERR(bo)) { 76 err = PTR_ERR(bo); 77 goto out_free_pt; 78 } 79 80 lmtt_assert(lmtt, xe_bo_is_vram(bo)); 81 lmtt_debug(lmtt, "level=%u addr=%#llx\n", level, (u64)xe_bo_main_addr(bo, XE_PAGE_SIZE)); 82 83 xe_map_memset(lmtt_to_xe(lmtt), &bo->vmap, 0, 0, bo->size); 84 85 pt->level = level; 86 pt->bo = bo; 87 return pt; 88 89 out_free_pt: 90 kfree(pt); 91 out: 92 return ERR_PTR(err); 93 } 94 95 static void lmtt_pt_free(struct xe_lmtt_pt *pt) 96 { 97 lmtt_debug(&pt->bo->tile->sriov.pf.lmtt, "level=%u addr=%llx\n", 98 pt->level, (u64)xe_bo_main_addr(pt->bo, XE_PAGE_SIZE)); 99 100 xe_bo_unpin_map_no_vm(pt->bo); 101 kfree(pt); 102 } 103 104 static int lmtt_init_pd(struct xe_lmtt *lmtt) 105 { 106 struct xe_lmtt_pt *pd; 107 108 lmtt_assert(lmtt, !lmtt->pd); 109 lmtt_assert(lmtt, lmtt->ops->lmtt_root_pd_level()); 110 111 pd = lmtt_pt_alloc(lmtt, lmtt->ops->lmtt_root_pd_level()); 112 if (IS_ERR(pd)) 113 return PTR_ERR(pd); 114 115 lmtt->pd = pd; 116 return 0; 117 } 118 119 static void lmtt_fini_pd(struct xe_lmtt *lmtt) 120 { 121 struct xe_lmtt_pt *pd = lmtt->pd; 122 unsigned int num_entries = lmtt->ops->lmtt_pte_num(pd->level); 123 unsigned int n = 0; 124 125 /* make sure we don't leak */ 126 for (n = 0; n < num_entries; n++) 127 lmtt_assert(lmtt, !pd->entries[n]); 128 129 lmtt->pd = NULL; 130 lmtt_pt_free(pd); 131 } 132 133 static void fini_lmtt(struct drm_device *drm, void *arg) 134 { 135 struct xe_lmtt *lmtt = arg; 136 137 lmtt_assert(lmtt, !(!!lmtt->ops ^ !!lmtt->pd)); 138 139 if (!lmtt->pd) 140 return; 141 142 lmtt_fini_pd(lmtt); 143 lmtt->ops = NULL; 144 } 145 146 /** 147 * xe_lmtt_init - LMTT software initialization. 148 * @lmtt: the &xe_lmtt to initialize 149 * 150 * The LMTT initialization requires two steps. 151 * 152 * The xe_lmtt_init() checks if LMTT is required on current device and selects 153 * and initialize proper variant of the LMTT Root Directory. Currently supported 154 * variants are `Two-Level LMTT Structure`_ and `Multi-Level LMTT Structure`_. 155 * 156 * In next step xe_lmtt_init_hw() will register this directory on the hardware. 157 * 158 * Notes: 159 * The LMTT allocations are managed and will be implicitly released on driver unload. 160 * This function shall be called only once and only when running as a PF driver. 161 * Any LMTT initialization failure should block VFs enabling. 162 * 163 * Return: 0 on success or a negative error code on failure. 164 */ 165 int xe_lmtt_init(struct xe_lmtt *lmtt) 166 { 167 struct xe_device *xe = lmtt_to_xe(lmtt); 168 int err; 169 170 lmtt_assert(lmtt, IS_SRIOV_PF(xe)); 171 lmtt_assert(lmtt, !lmtt->ops); 172 173 if (!xe_device_has_lmtt(xe)) 174 return 0; 175 176 if (xe_has_multi_level_lmtt(xe)) 177 lmtt->ops = &lmtt_ml_ops; 178 else 179 lmtt->ops = &lmtt_2l_ops; 180 181 err = lmtt_init_pd(lmtt); 182 if (unlikely(err)) 183 goto fail; 184 185 return drmm_add_action_or_reset(&xe->drm, fini_lmtt, lmtt); 186 187 fail: 188 lmtt->ops = NULL; 189 return err; 190 } 191 192 static void lmtt_setup_dir_ptr(struct xe_lmtt *lmtt) 193 { 194 struct xe_tile *tile = lmtt_to_tile(lmtt); 195 struct xe_device *xe = tile_to_xe(tile); 196 dma_addr_t offset = xe_bo_main_addr(lmtt->pd->bo, XE_PAGE_SIZE); 197 198 lmtt_debug(lmtt, "DIR offset %pad\n", &offset); 199 lmtt_assert(lmtt, xe_bo_is_vram(lmtt->pd->bo)); 200 lmtt_assert(lmtt, IS_ALIGNED(offset, SZ_64K)); 201 202 xe_mmio_write32(&tile->mmio, 203 GRAPHICS_VER(xe) >= 20 ? XE2_LMEM_CFG : LMEM_CFG, 204 LMEM_EN | REG_FIELD_PREP(LMTT_DIR_PTR, offset / SZ_64K)); 205 } 206 207 /** 208 * xe_lmtt_init_hw - Perform LMTT hardware initialization. 209 * @lmtt: the &xe_lmtt to initialize 210 * 211 * This function is a second step of the LMTT initialization. 212 * This function registers LMTT Root Directory prepared in xe_lmtt_init(). 213 * 214 * This function shall be called after every hardware reset. 215 * This function shall be called only when running as a PF driver. 216 */ 217 void xe_lmtt_init_hw(struct xe_lmtt *lmtt) 218 { 219 if (!lmtt->pd) 220 return; 221 222 lmtt_setup_dir_ptr(lmtt); 223 } 224 225 static void lmtt_write_pte(struct xe_lmtt *lmtt, struct xe_lmtt_pt *pt, 226 u64 pte, unsigned int idx) 227 { 228 unsigned int level = pt->level; 229 230 lmtt_assert(lmtt, idx <= lmtt->ops->lmtt_pte_num(level)); 231 lmtt_debug(lmtt, "WRITE level=%u index=%u pte=%#llx\n", level, idx, pte); 232 233 switch (lmtt->ops->lmtt_pte_size(level)) { 234 case sizeof(u32): 235 lmtt_assert(lmtt, !overflows_type(pte, u32)); 236 lmtt_assert(lmtt, !pte || !iosys_map_rd(&pt->bo->vmap, idx * sizeof(u32), u32)); 237 238 xe_map_wr(lmtt_to_xe(lmtt), &pt->bo->vmap, idx * sizeof(u32), u32, pte); 239 break; 240 case sizeof(u64): 241 lmtt_assert(lmtt, !pte || !iosys_map_rd(&pt->bo->vmap, idx * sizeof(u64), u64)); 242 243 xe_map_wr(lmtt_to_xe(lmtt), &pt->bo->vmap, idx * sizeof(u64), u64, pte); 244 break; 245 default: 246 lmtt_assert(lmtt, !!!"invalid pte size"); 247 } 248 } 249 250 static void lmtt_destroy_pt(struct xe_lmtt *lmtt, struct xe_lmtt_pt *pd) 251 { 252 unsigned int num_entries = pd->level ? lmtt->ops->lmtt_pte_num(pd->level) : 0; 253 struct xe_lmtt_pt *pt; 254 unsigned int i; 255 256 for (i = 0; i < num_entries; i++) { 257 pt = pd->entries[i]; 258 pd->entries[i] = NULL; 259 if (!pt) 260 continue; 261 262 lmtt_destroy_pt(lmtt, pt); 263 } 264 265 lmtt_pt_free(pd); 266 } 267 268 static void lmtt_drop_pages(struct xe_lmtt *lmtt, unsigned int vfid) 269 { 270 struct xe_lmtt_pt *pd = lmtt->pd; 271 struct xe_lmtt_pt *pt; 272 273 pt = pd->entries[vfid]; 274 pd->entries[vfid] = NULL; 275 if (!pt) 276 return; 277 278 lmtt_write_pte(lmtt, pd, LMTT_PTE_INVALID, vfid); 279 280 lmtt_assert(lmtt, pd->level > 0); 281 lmtt_assert(lmtt, pt->level == pd->level - 1); 282 lmtt_destroy_pt(lmtt, pt); 283 } 284 285 static int __lmtt_alloc_range(struct xe_lmtt *lmtt, struct xe_lmtt_pt *pd, 286 u64 start, u64 end) 287 { 288 u64 pte_addr_shift = BIT_ULL(lmtt->ops->lmtt_pte_shift(pd->level)); 289 u64 offset; 290 int err; 291 292 lmtt_assert(lmtt, pd->level > 0); 293 294 offset = start; 295 while (offset < end) { 296 struct xe_lmtt_pt *pt; 297 u64 next, pde, pt_addr; 298 unsigned int idx; 299 300 pt = lmtt_pt_alloc(lmtt, pd->level - 1); 301 if (IS_ERR(pt)) 302 return PTR_ERR(pt); 303 304 pt_addr = xe_bo_main_addr(pt->bo, XE_PAGE_SIZE); 305 306 idx = lmtt->ops->lmtt_pte_index(offset, pd->level); 307 pde = lmtt->ops->lmtt_pte_encode(pt_addr, pd->level); 308 309 lmtt_write_pte(lmtt, pd, pde, idx); 310 311 pd->entries[idx] = pt; 312 313 next = min(end, round_up(offset + 1, pte_addr_shift)); 314 315 if (pt->level != 0) { 316 err = __lmtt_alloc_range(lmtt, pt, offset, next); 317 if (err) 318 return err; 319 } 320 321 offset = next; 322 } 323 324 return 0; 325 } 326 327 static int lmtt_alloc_range(struct xe_lmtt *lmtt, unsigned int vfid, u64 start, u64 end) 328 { 329 struct xe_lmtt_pt *pd = lmtt->pd; 330 struct xe_lmtt_pt *pt; 331 u64 pt_addr; 332 u64 pde; 333 int err; 334 335 lmtt_assert(lmtt, pd->level > 0); 336 lmtt_assert(lmtt, vfid <= lmtt->ops->lmtt_pte_num(pd->level)); 337 lmtt_assert(lmtt, IS_ALIGNED(start, lmtt_page_size(lmtt))); 338 lmtt_assert(lmtt, IS_ALIGNED(end, lmtt_page_size(lmtt))); 339 340 if (pd->entries[vfid]) 341 return -ENOTEMPTY; 342 343 pt = lmtt_pt_alloc(lmtt, pd->level - 1); 344 if (IS_ERR(pt)) 345 return PTR_ERR(pt); 346 347 pt_addr = xe_bo_main_addr(pt->bo, XE_PAGE_SIZE); 348 349 pde = lmtt->ops->lmtt_pte_encode(pt_addr, pd->level); 350 351 lmtt_write_pte(lmtt, pd, pde, vfid); 352 353 pd->entries[vfid] = pt; 354 355 if (pt->level != 0) { 356 err = __lmtt_alloc_range(lmtt, pt, start, end); 357 if (err) 358 goto out_free_pt; 359 } 360 361 return 0; 362 363 out_free_pt: 364 lmtt_pt_free(pt); 365 return err; 366 } 367 368 static struct xe_lmtt_pt *lmtt_leaf_pt(struct xe_lmtt *lmtt, unsigned int vfid, u64 addr) 369 { 370 struct xe_lmtt_pt *pd = lmtt->pd; 371 struct xe_lmtt_pt *pt; 372 373 lmtt_assert(lmtt, vfid <= lmtt->ops->lmtt_pte_num(pd->level)); 374 pt = pd->entries[vfid]; 375 376 while (pt->level) { 377 lmtt_assert(lmtt, lmtt->ops->lmtt_pte_index(addr, pt->level) <= 378 lmtt->ops->lmtt_pte_num(pt->level)); 379 380 pt = pt->entries[lmtt->ops->lmtt_pte_index(addr, pt->level)]; 381 382 addr >>= lmtt->ops->lmtt_pte_shift(pt->level); 383 } 384 385 lmtt_assert(lmtt, lmtt->ops->lmtt_pte_index(addr, pt->level) <= 386 lmtt->ops->lmtt_pte_num(pt->level)); 387 lmtt_assert(lmtt, pt->level != pd->level); 388 lmtt_assert(lmtt, pt->level == 0); 389 return pt; 390 } 391 392 static void lmtt_insert_bo(struct xe_lmtt *lmtt, unsigned int vfid, struct xe_bo *bo, u64 start) 393 { 394 u64 page_size = lmtt_page_size(lmtt); 395 struct xe_res_cursor cur; 396 struct xe_lmtt_pt *pt; 397 u64 addr, vram_offset; 398 399 lmtt_assert(lmtt, IS_ALIGNED(start, page_size)); 400 lmtt_assert(lmtt, IS_ALIGNED(bo->size, page_size)); 401 lmtt_assert(lmtt, xe_bo_is_vram(bo)); 402 403 vram_offset = vram_region_gpu_offset(bo->ttm.resource); 404 xe_res_first(bo->ttm.resource, 0, bo->size, &cur); 405 while (cur.remaining) { 406 addr = xe_res_dma(&cur); 407 addr += vram_offset; /* XXX */ 408 409 pt = lmtt_leaf_pt(lmtt, vfid, start); 410 411 lmtt_write_pte(lmtt, pt, lmtt->ops->lmtt_pte_encode(addr, 0), 412 lmtt->ops->lmtt_pte_index(start, 0)); 413 414 xe_res_next(&cur, page_size); 415 start += page_size; 416 } 417 } 418 419 /** 420 * xe_lmtt_prepare_pages - Create VF's LMTT Page Tables. 421 * @lmtt: the &xe_lmtt to update 422 * @vfid: the VF identifier (1-based) 423 * @range: top range of LMEM offset to be supported 424 * 425 * This function creates empty LMTT page tables for given VF to support 426 * up to maximum #range LMEM offset. The LMTT page tables created by this 427 * function must be released using xe_lmtt_drop_pages() function. 428 * 429 * Notes: 430 * This function shall be called only after successful LMTT initialization. 431 * See xe_lmtt_init(). 432 * 433 * Return: 0 on success or a negative error code on failure. 434 */ 435 int xe_lmtt_prepare_pages(struct xe_lmtt *lmtt, unsigned int vfid, u64 range) 436 { 437 lmtt_assert(lmtt, lmtt->pd); 438 lmtt_assert(lmtt, vfid); 439 440 return lmtt_alloc_range(lmtt, vfid, 0, range); 441 } 442 443 /** 444 * xe_lmtt_populate_pages - Update VF's LMTT Page Table Entries. 445 * @lmtt: the &xe_lmtt to update 446 * @vfid: the VF identifier (1-based) 447 * @bo: the buffer object with LMEM allocation to be mapped 448 * @offset: the offset at which #bo should be mapped 449 * 450 * This function updates VF's LMTT entries to use given buffer object as a backstore. 451 * 452 * Notes: 453 * This function shall be called only after successful preparation of the 454 * VF's LMTT Page Tables. See xe_lmtt_prepare(). 455 * 456 * Return: 0 on success or a negative error code on failure. 457 */ 458 int xe_lmtt_populate_pages(struct xe_lmtt *lmtt, unsigned int vfid, struct xe_bo *bo, u64 offset) 459 { 460 lmtt_assert(lmtt, lmtt->pd); 461 lmtt_assert(lmtt, vfid); 462 463 lmtt_insert_bo(lmtt, vfid, bo, offset); 464 return 0; 465 } 466 467 /** 468 * xe_lmtt_drop_pages - Remove VF's LMTT Pages. 469 * @lmtt: the &xe_lmtt to update 470 * @vfid: the VF identifier (1-based) 471 * 472 * This function removes all LMTT Page Tables prepared by xe_lmtt_prepare_pages(). 473 * 474 * This function shall be called only after successful LMTT initialization. 475 * See xe_lmtt_init(). 476 */ 477 void xe_lmtt_drop_pages(struct xe_lmtt *lmtt, unsigned int vfid) 478 { 479 lmtt_assert(lmtt, lmtt->pd); 480 lmtt_assert(lmtt, vfid); 481 482 lmtt_drop_pages(lmtt, vfid); 483 } 484 485 /** 486 * xe_lmtt_estimate_pt_size - Estimate size of LMTT PT allocations. 487 * @lmtt: the &xe_lmtt 488 * @size: the size of the LMEM to be mapped over LMTT (including any offset) 489 * 490 * This function shall be called only by PF. 491 * 492 * Return: size of the PT allocation(s) needed to support given LMEM size. 493 */ 494 u64 xe_lmtt_estimate_pt_size(struct xe_lmtt *lmtt, u64 size) 495 { 496 unsigned int level = 0; 497 u64 pt_size; 498 499 lmtt_assert(lmtt, IS_SRIOV_PF(lmtt_to_xe(lmtt))); 500 lmtt_assert(lmtt, xe_device_has_lmtt(lmtt_to_xe(lmtt))); 501 lmtt_assert(lmtt, lmtt->ops); 502 503 pt_size = PAGE_ALIGN(lmtt->ops->lmtt_pte_size(level) * 504 lmtt->ops->lmtt_pte_num(level)); 505 506 while (++level < lmtt->ops->lmtt_root_pd_level()) { 507 pt_size *= lmtt->ops->lmtt_pte_index(size, level) + 1; 508 pt_size += PAGE_ALIGN(lmtt->ops->lmtt_pte_size(level) * 509 lmtt->ops->lmtt_pte_num(level)); 510 } 511 512 return pt_size; 513 } 514 515 #if IS_BUILTIN(CONFIG_DRM_XE_KUNIT_TEST) 516 #include "tests/xe_lmtt_test.c" 517 #endif 518