// 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_gt_tlb_invalidation.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)	xe_tile_assert(lmtt_to_tile(lmtt), condition)
#define lmtt_debug(lmtt, msg...)	xe_sriov_dbg_verbose(lmtt_to_xe(lmtt), "LMTT: " msg)

static bool xe_has_multi_level_lmtt(struct xe_device *xe)
{
	return GRAPHICS_VERx100(xe) >= 1260;
}

static struct xe_tile *lmtt_to_tile(struct xe_lmtt *lmtt)
{
	return container_of(lmtt, struct xe_tile, sriov.pf.lmtt);
}

static struct xe_device *lmtt_to_xe(struct xe_lmtt *lmtt)
{
	return tile_to_xe(lmtt_to_tile(lmtt));
}

static u64 lmtt_page_size(struct xe_lmtt *lmtt)
{
	return BIT_ULL(lmtt->ops->lmtt_pte_shift(0));
}

static struct xe_lmtt_pt *lmtt_pt_alloc(struct xe_lmtt *lmtt, unsigned int level)
{
	unsigned int num_entries = level ? lmtt->ops->lmtt_pte_num(level) : 0;
	struct xe_lmtt_pt *pt;
	struct xe_bo *bo;
	int err;

	pt = kzalloc(struct_size(pt, entries, num_entries), GFP_KERNEL);
	if (!pt) {
		err = -ENOMEM;
		goto out;
	}

	bo = xe_bo_create_pin_map(lmtt_to_xe(lmtt), lmtt_to_tile(lmtt), NULL,
				  PAGE_ALIGN(lmtt->ops->lmtt_pte_size(level) *
					     lmtt->ops->lmtt_pte_num(level)),
				  ttm_bo_type_kernel,
				  XE_BO_FLAG_VRAM_IF_DGFX(lmtt_to_tile(lmtt)) |
				  XE_BO_FLAG_NEEDS_64K);
	if (IS_ERR(bo)) {
		err = PTR_ERR(bo);
		goto out_free_pt;
	}

	lmtt_assert(lmtt, xe_bo_is_vram(bo));
	lmtt_debug(lmtt, "level=%u addr=%#llx\n", level, (u64)xe_bo_main_addr(bo, XE_PAGE_SIZE));

	xe_map_memset(lmtt_to_xe(lmtt), &bo->vmap, 0, 0, xe_bo_size(bo));

	pt->level = level;
	pt->bo = bo;
	return pt;

out_free_pt:
	kfree(pt);
out:
	return ERR_PTR(err);
}

static void lmtt_pt_free(struct xe_lmtt_pt *pt)
{
	lmtt_debug(&pt->bo->tile->sriov.pf.lmtt, "level=%u addr=%llx\n",
		   pt->level, (u64)xe_bo_main_addr(pt->bo, XE_PAGE_SIZE));

	xe_bo_unpin_map_no_vm(pt->bo);
	kfree(pt);
}

static int lmtt_init_pd(struct xe_lmtt *lmtt)
{
	struct xe_lmtt_pt *pd;

	lmtt_assert(lmtt, !lmtt->pd);
	lmtt_assert(lmtt, lmtt->ops->lmtt_root_pd_level());

	pd = lmtt_pt_alloc(lmtt, lmtt->ops->lmtt_root_pd_level());
	if (IS_ERR(pd))
		return PTR_ERR(pd);

	lmtt->pd = pd;
	return 0;
}

static void lmtt_fini_pd(struct xe_lmtt *lmtt)
{
	struct xe_lmtt_pt *pd = lmtt->pd;
	unsigned int num_entries = lmtt->ops->lmtt_pte_num(pd->level);
	unsigned int n = 0;

	/* make sure we don't leak */
	for (n = 0; n < num_entries; n++)
		lmtt_assert(lmtt, !pd->entries[n]);

	lmtt->pd = NULL;
	lmtt_pt_free(pd);
}

static void fini_lmtt(struct drm_device *drm, void *arg)
{
	struct xe_lmtt *lmtt = arg;

	lmtt_assert(lmtt, !(!!lmtt->ops ^ !!lmtt->pd));

	if (!lmtt->pd)
		return;

	lmtt_fini_pd(lmtt);
	lmtt->ops = NULL;
}

/**
 * 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)
{
	struct xe_device *xe = lmtt_to_xe(lmtt);
	int err;

	lmtt_assert(lmtt, IS_SRIOV_PF(xe));
	lmtt_assert(lmtt, !lmtt->ops);

	if (!xe_device_has_lmtt(xe))
		return 0;

	if (xe_has_multi_level_lmtt(xe))
		lmtt->ops = &lmtt_ml_ops;
	else
		lmtt->ops = &lmtt_2l_ops;

	err = lmtt_init_pd(lmtt);
	if (unlikely(err))
		goto fail;

	return drmm_add_action_or_reset(&xe->drm, fini_lmtt, lmtt);

fail:
	lmtt->ops = NULL;
	return err;
}

static void lmtt_setup_dir_ptr(struct xe_lmtt *lmtt)
{
	struct xe_tile *tile = lmtt_to_tile(lmtt);
	struct xe_device *xe = tile_to_xe(tile);
	dma_addr_t offset = xe_bo_main_addr(lmtt->pd->bo, XE_PAGE_SIZE);

	lmtt_debug(lmtt, "DIR offset %pad\n", &offset);
	lmtt_assert(lmtt, xe_bo_is_vram(lmtt->pd->bo));
	lmtt_assert(lmtt, IS_ALIGNED(offset, SZ_64K));

	xe_mmio_write32(&tile->mmio,
			GRAPHICS_VER(xe) >= 20 ? XE2_LMEM_CFG : LMEM_CFG,
			LMEM_EN | REG_FIELD_PREP(LMTT_DIR_PTR, offset / SZ_64K));
}

/**
 * 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)
{
	if (!lmtt->pd)
		return;

	lmtt_setup_dir_ptr(lmtt);
}

static int lmtt_invalidate_hw(struct xe_lmtt *lmtt)
{
	struct xe_gt_tlb_invalidation_fence fences[XE_MAX_GT_PER_TILE];
	struct xe_gt_tlb_invalidation_fence *fence = fences;
	struct xe_tile *tile = lmtt_to_tile(lmtt);
	struct xe_gt *gt;
	int result = 0;
	int err;
	u8 id;

	for_each_gt_on_tile(gt, tile, id) {
		xe_gt_tlb_invalidation_fence_init(gt, fence, true);
		err = xe_gt_tlb_invalidation_all(gt, fence);
		result = result ?: err;
		fence++;
	}

	lmtt_debug(lmtt, "num_fences=%d err=%d\n", (int)(fence - fences), result);

	/*
	 * It is fine to wait for all fences, even for those which covers the
	 * invalidation request that failed, as such fence should be already
	 * marked as signaled.
	 */
	fence = fences;
	for_each_gt_on_tile(gt, tile, id)
		xe_gt_tlb_invalidation_fence_wait(fence++);

	return result;
}

/**
 * xe_lmtt_invalidate_hw - Invalidate LMTT hardware.
 * @lmtt: the &xe_lmtt to invalidate
 *
 * Send requests to all GuCs on this tile to invalidate all TLBs.
 *
 * This function should be called only when running as a PF driver.
 */
void xe_lmtt_invalidate_hw(struct xe_lmtt *lmtt)
{
	struct xe_device *xe = lmtt_to_xe(lmtt);
	int err;

	lmtt_assert(lmtt, IS_SRIOV_PF(xe));

	err = lmtt_invalidate_hw(lmtt);
	if (err)
		xe_sriov_warn(xe, "LMTT%u invalidation failed (%pe)",
			      lmtt_to_tile(lmtt)->id, ERR_PTR(err));
}

static void lmtt_write_pte(struct xe_lmtt *lmtt, struct xe_lmtt_pt *pt,
			   u64 pte, unsigned int idx)
{
	unsigned int level = pt->level;

	lmtt_assert(lmtt, idx <= lmtt->ops->lmtt_pte_num(level));
	lmtt_debug(lmtt, "WRITE level=%u index=%u pte=%#llx\n", level, idx, pte);

	switch (lmtt->ops->lmtt_pte_size(level)) {
	case sizeof(u32):
		lmtt_assert(lmtt, !overflows_type(pte, u32));
		lmtt_assert(lmtt, !pte || !iosys_map_rd(&pt->bo->vmap, idx * sizeof(u32), u32));

		xe_map_wr(lmtt_to_xe(lmtt), &pt->bo->vmap, idx * sizeof(u32), u32, pte);
		break;
	case sizeof(u64):
		lmtt_assert(lmtt, !pte || !iosys_map_rd(&pt->bo->vmap, idx * sizeof(u64), u64));

		xe_map_wr(lmtt_to_xe(lmtt), &pt->bo->vmap, idx * sizeof(u64), u64, pte);
		break;
	default:
		lmtt_assert(lmtt, !!!"invalid pte size");
	}
}

static void lmtt_destroy_pt(struct xe_lmtt *lmtt, struct xe_lmtt_pt *pd)
{
	unsigned int num_entries = pd->level ? lmtt->ops->lmtt_pte_num(pd->level) : 0;
	struct xe_lmtt_pt *pt;
	unsigned int i;

	for (i = 0; i < num_entries; i++) {
		pt = pd->entries[i];
		pd->entries[i] = NULL;
		if (!pt)
			continue;

		lmtt_destroy_pt(lmtt, pt);
	}

	lmtt_pt_free(pd);
}

static void lmtt_drop_pages(struct xe_lmtt *lmtt, unsigned int vfid)
{
	struct xe_lmtt_pt *pd = lmtt->pd;
	struct xe_lmtt_pt *pt;

	pt = pd->entries[vfid];
	pd->entries[vfid] = NULL;
	if (!pt)
		return;

	lmtt_write_pte(lmtt, pd, LMTT_PTE_INVALID, vfid);
	lmtt_invalidate_hw(lmtt);

	lmtt_assert(lmtt, pd->level > 0);
	lmtt_assert(lmtt, pt->level == pd->level - 1);
	lmtt_destroy_pt(lmtt, pt);
}

static int __lmtt_alloc_range(struct xe_lmtt *lmtt, struct xe_lmtt_pt *pd,
			      u64 start, u64 end)
{
	u64 pte_addr_shift = BIT_ULL(lmtt->ops->lmtt_pte_shift(pd->level));
	u64 offset;
	int err;

	lmtt_assert(lmtt, pd->level > 0);

	offset = start;
	while (offset < end) {
		struct xe_lmtt_pt *pt;
		u64 next, pde, pt_addr;
		unsigned int idx;

		pt = lmtt_pt_alloc(lmtt, pd->level - 1);
		if (IS_ERR(pt))
			return PTR_ERR(pt);

		pt_addr = xe_bo_main_addr(pt->bo, XE_PAGE_SIZE);

		idx = lmtt->ops->lmtt_pte_index(offset, pd->level);
		pde = lmtt->ops->lmtt_pte_encode(pt_addr, pd->level);

		lmtt_write_pte(lmtt, pd, pde, idx);

		pd->entries[idx] = pt;

		next = min(end, round_up(offset + 1, pte_addr_shift));

		if (pt->level != 0) {
			err = __lmtt_alloc_range(lmtt, pt, offset, next);
			if (err)
				return err;
		}

		offset = next;
	}

	return 0;
}

static int lmtt_alloc_range(struct xe_lmtt *lmtt, unsigned int vfid, u64 start, u64 end)
{
	struct xe_lmtt_pt *pd = lmtt->pd;
	struct xe_lmtt_pt *pt;
	u64 pt_addr;
	u64 pde;
	int err;

	lmtt_assert(lmtt, pd->level > 0);
	lmtt_assert(lmtt, vfid <= lmtt->ops->lmtt_pte_num(pd->level));
	lmtt_assert(lmtt, IS_ALIGNED(start, lmtt_page_size(lmtt)));
	lmtt_assert(lmtt, IS_ALIGNED(end, lmtt_page_size(lmtt)));

	if (pd->entries[vfid])
		return -ENOTEMPTY;

	pt = lmtt_pt_alloc(lmtt, pd->level - 1);
	if (IS_ERR(pt))
		return PTR_ERR(pt);

	pt_addr = xe_bo_main_addr(pt->bo, XE_PAGE_SIZE);

	pde = lmtt->ops->lmtt_pte_encode(pt_addr, pd->level);

	lmtt_write_pte(lmtt, pd, pde, vfid);

	pd->entries[vfid] = pt;

	if (pt->level != 0) {
		err = __lmtt_alloc_range(lmtt, pt, start, end);
		if (err)
			goto out_free_pt;
	}

	return 0;

out_free_pt:
	lmtt_pt_free(pt);
	return err;
}

static struct xe_lmtt_pt *lmtt_leaf_pt(struct xe_lmtt *lmtt, unsigned int vfid, u64 addr)
{
	struct xe_lmtt_pt *pd = lmtt->pd;
	struct xe_lmtt_pt *pt;

	lmtt_assert(lmtt, vfid <= lmtt->ops->lmtt_pte_num(pd->level));
	pt = pd->entries[vfid];

	while (pt->level) {
		lmtt_assert(lmtt, lmtt->ops->lmtt_pte_index(addr, pt->level) <=
			    lmtt->ops->lmtt_pte_num(pt->level));

		pt = pt->entries[lmtt->ops->lmtt_pte_index(addr, pt->level)];

		addr >>= lmtt->ops->lmtt_pte_shift(pt->level);
	}

	lmtt_assert(lmtt, lmtt->ops->lmtt_pte_index(addr, pt->level) <=
		    lmtt->ops->lmtt_pte_num(pt->level));
	lmtt_assert(lmtt, pt->level != pd->level);
	lmtt_assert(lmtt, pt->level == 0);
	return pt;
}

static void lmtt_insert_bo(struct xe_lmtt *lmtt, unsigned int vfid, struct xe_bo *bo, u64 start)
{
	u64 page_size = lmtt_page_size(lmtt);
	struct xe_res_cursor cur;
	struct xe_lmtt_pt *pt;
	u64 addr, vram_offset;

	lmtt_assert(lmtt, IS_ALIGNED(start, page_size));
	lmtt_assert(lmtt, IS_ALIGNED(xe_bo_size(bo), page_size));
	lmtt_assert(lmtt, xe_bo_is_vram(bo));

	vram_offset = vram_region_gpu_offset(bo->ttm.resource);
	xe_res_first(bo->ttm.resource, 0, xe_bo_size(bo), &cur);
	while (cur.remaining) {
		addr = xe_res_dma(&cur);
		addr += vram_offset; /* XXX */

		pt = lmtt_leaf_pt(lmtt, vfid, start);

		lmtt_write_pte(lmtt, pt, lmtt->ops->lmtt_pte_encode(addr, 0),
					 lmtt->ops->lmtt_pte_index(start, 0));

		xe_res_next(&cur, page_size);
		start += page_size;
	}
}

/**
 * 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)
{
	lmtt_assert(lmtt, lmtt->pd);
	lmtt_assert(lmtt, vfid);

	return lmtt_alloc_range(lmtt, vfid, 0, 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)
{
	lmtt_assert(lmtt, lmtt->pd);
	lmtt_assert(lmtt, vfid);

	lmtt_insert_bo(lmtt, vfid, bo, offset);
	return 0;
}

/**
 * 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)
{
	lmtt_assert(lmtt, lmtt->pd);
	lmtt_assert(lmtt, vfid);

	lmtt_drop_pages(lmtt, 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)
{
	unsigned int level = 0;
	u64 pt_size;

	lmtt_assert(lmtt, IS_SRIOV_PF(lmtt_to_xe(lmtt)));
	lmtt_assert(lmtt, xe_device_has_lmtt(lmtt_to_xe(lmtt)));
	lmtt_assert(lmtt, lmtt->ops);

	pt_size = PAGE_ALIGN(lmtt->ops->lmtt_pte_size(level) *
			     lmtt->ops->lmtt_pte_num(level));

	while (++level < lmtt->ops->lmtt_root_pd_level()) {
		pt_size *= lmtt->ops->lmtt_pte_index(size, level) + 1;
		pt_size += PAGE_ALIGN(lmtt->ops->lmtt_pte_size(level) *
				      lmtt->ops->lmtt_pte_num(level));
	}

	return pt_size;
}

#if IS_BUILTIN(CONFIG_DRM_XE_KUNIT_TEST)
#include "tests/xe_lmtt_test.c"
#endif
