// SPDX-License-Identifier: MIT /* * Copyright © 2023 Intel Corporation */ #include <linux/align.h> #include <drm/drm_managed.h> #include "regs/xe_gt_regs.h" #include "xe_assert.h" #include "xe_bo.h" #include "xe_lmtt.h" #include "xe_map.h" #include "xe_mmio.h" #include "xe_res_cursor.h" #include "xe_sriov.h" #include "xe_sriov_printk.h" /** * DOC: Local Memory Translation Table * * The Local Memory Translation Table (LMTT) provides additional abstraction * when Virtual Function (VF) is accessing device Local Memory (VRAM). * * The Root LMTT Page Directory contains one entry for each VF. Entries are * indexed by the function number (1-based, index 0 is unused). * * See `Two-Level LMTT Structure`_ and `Multi-Level LMTT Structure`_. */ #define lmtt_assert(lmtt, condition) … #define lmtt_debug(lmtt, msg...) … static bool xe_has_multi_level_lmtt(struct xe_device *xe) { … } static struct xe_tile *lmtt_to_tile(struct xe_lmtt *lmtt) { … } static struct xe_device *lmtt_to_xe(struct xe_lmtt *lmtt) { … } static u64 lmtt_page_size(struct xe_lmtt *lmtt) { … } static struct xe_lmtt_pt *lmtt_pt_alloc(struct xe_lmtt *lmtt, unsigned int level) { … } static void lmtt_pt_free(struct xe_lmtt_pt *pt) { … } static int lmtt_init_pd(struct xe_lmtt *lmtt) { … } static void lmtt_fini_pd(struct xe_lmtt *lmtt) { … } static void fini_lmtt(struct drm_device *drm, void *arg) { … } /** * xe_lmtt_init - LMTT software initialization. * @lmtt: the &xe_lmtt to initialize * * The LMTT initialization requires two steps. * * The xe_lmtt_init() checks if LMTT is required on current device and selects * and initialize proper variant of the LMTT Root Directory. Currently supported * variants are `Two-Level LMTT Structure`_ and `Multi-Level LMTT Structure`_. * * In next step xe_lmtt_init_hw() will register this directory on the hardware. * * Notes: * The LMTT allocations are managed and will be implicitly released on driver unload. * This function shall be called only once and only when running as a PF driver. * Any LMTT initialization failure should block VFs enabling. * * Return: 0 on success or a negative error code on failure. */ int xe_lmtt_init(struct xe_lmtt *lmtt) { … } static void lmtt_setup_dir_ptr(struct xe_lmtt *lmtt) { … } /** * xe_lmtt_init_hw - Perform LMTT hardware initialization. * @lmtt: the &xe_lmtt to initialize * * This function is a second step of the LMTT initialization. * This function registers LMTT Root Directory prepared in xe_lmtt_init(). * * This function shall be called after every hardware reset. * This function shall be called only when running as a PF driver. */ void xe_lmtt_init_hw(struct xe_lmtt *lmtt) { … } static void lmtt_write_pte(struct xe_lmtt *lmtt, struct xe_lmtt_pt *pt, u64 pte, unsigned int idx) { … } static void lmtt_destroy_pt(struct xe_lmtt *lmtt, struct xe_lmtt_pt *pd) { … } static void lmtt_drop_pages(struct xe_lmtt *lmtt, unsigned int vfid) { … } static int __lmtt_alloc_range(struct xe_lmtt *lmtt, struct xe_lmtt_pt *pd, u64 start, u64 end) { … } static int lmtt_alloc_range(struct xe_lmtt *lmtt, unsigned int vfid, u64 start, u64 end) { … } static struct xe_lmtt_pt *lmtt_leaf_pt(struct xe_lmtt *lmtt, unsigned int vfid, u64 addr) { … } static void lmtt_insert_bo(struct xe_lmtt *lmtt, unsigned int vfid, struct xe_bo *bo, u64 start) { … } /** * xe_lmtt_prepare_pages - Create VF's LMTT Page Tables. * @lmtt: the &xe_lmtt to update * @vfid: the VF identifier (1-based) * @range: top range of LMEM offset to be supported * * This function creates empty LMTT page tables for given VF to support * up to maximum #range LMEM offset. The LMTT page tables created by this * function must be released using xe_lmtt_drop_pages() function. * * Notes: * This function shall be called only after successful LMTT initialization. * See xe_lmtt_init(). * * Return: 0 on success or a negative error code on failure. */ int xe_lmtt_prepare_pages(struct xe_lmtt *lmtt, unsigned int vfid, u64 range) { … } /** * xe_lmtt_populate_pages - Update VF's LMTT Page Table Entries. * @lmtt: the &xe_lmtt to update * @vfid: the VF identifier (1-based) * @bo: the buffer object with LMEM allocation to be mapped * @offset: the offset at which #bo should be mapped * * This function updates VF's LMTT entries to use given buffer object as a backstore. * * Notes: * This function shall be called only after successful preparation of the * VF's LMTT Page Tables. See xe_lmtt_prepare(). * * Return: 0 on success or a negative error code on failure. */ int xe_lmtt_populate_pages(struct xe_lmtt *lmtt, unsigned int vfid, struct xe_bo *bo, u64 offset) { … } /** * xe_lmtt_drop_pages - Remove VF's LMTT Pages. * @lmtt: the &xe_lmtt to update * @vfid: the VF identifier (1-based) * * This function removes all LMTT Page Tables prepared by xe_lmtt_prepare_pages(). * * This function shall be called only after successful LMTT initialization. * See xe_lmtt_init(). */ void xe_lmtt_drop_pages(struct xe_lmtt *lmtt, unsigned int vfid) { … } /** * xe_lmtt_estimate_pt_size - Estimate size of LMTT PT allocations. * @lmtt: the &xe_lmtt * @size: the size of the LMEM to be mapped over LMTT (including any offset) * * This function shall be called only by PF. * * Return: size of the PT allocation(s) needed to support given LMEM size. */ u64 xe_lmtt_estimate_pt_size(struct xe_lmtt *lmtt, u64 size) { … } #if IS_BUILTIN(CONFIG_DRM_XE_KUNIT_TEST) #include "tests/xe_lmtt_test.c" #endif