// SPDX-License-Identifier: GPL-2.0

/*
 * Copyright 2016-2020 HabanaLabs, Ltd.
 * All Rights Reserved.
 */

#include <linux/slab.h>

#include "habanalabs.h"

static bool is_dram_va(struct hl_device *hdev, u64 virt_addr)
{
	struct asic_fixed_properties *prop = &hdev->asic_prop;

	return hl_mem_area_inside_range(virt_addr, prop->dmmu.page_size,
					prop->dmmu.start_addr,
					prop->dmmu.end_addr);
}

/**
 * hl_mmu_init() - initialize the MMU module.
 * @hdev: habanalabs device structure.
 *
 * Return: 0 for success, non-zero for failure.
 */
int hl_mmu_init(struct hl_device *hdev)
{
	int rc = -EOPNOTSUPP;

	if (!hdev->mmu_enable)
		return 0;

	if (hdev->mmu_func[MMU_DR_PGT].init != NULL) {
		rc = hdev->mmu_func[MMU_DR_PGT].init(hdev);
		if (rc)
			return rc;
	}

	if (hdev->mmu_func[MMU_HR_PGT].init != NULL)
		rc = hdev->mmu_func[MMU_HR_PGT].init(hdev);

	return rc;
}

/**
 * hl_mmu_fini() - release the MMU module.
 * @hdev: habanalabs device structure.
 *
 * This function does the following:
 * - Disable MMU in H/W.
 * - Free the pgt_infos pool.
 *
 * All contexts should be freed before calling this function.
 */
void hl_mmu_fini(struct hl_device *hdev)
{
	if (!hdev->mmu_enable)
		return;

	if (hdev->mmu_func[MMU_DR_PGT].fini != NULL)
		hdev->mmu_func[MMU_DR_PGT].fini(hdev);

	if (hdev->mmu_func[MMU_HR_PGT].fini != NULL)
		hdev->mmu_func[MMU_HR_PGT].fini(hdev);
}

/**
 * hl_mmu_ctx_init() - initialize a context for using the MMU module.
 * @ctx: pointer to the context structure to initialize.
 *
 * Initialize a mutex to protect the concurrent mapping flow, a hash to hold all
 * page tables hops related to this context.
 * Return: 0 on success, non-zero otherwise.
 */
int hl_mmu_ctx_init(struct hl_ctx *ctx)
{
	struct hl_device *hdev = ctx->hdev;
	int rc = -EOPNOTSUPP;

	if (!hdev->mmu_enable)
		return 0;

	mutex_init(&ctx->mmu_lock);

	if (hdev->mmu_func[MMU_DR_PGT].ctx_init != NULL) {
		rc = hdev->mmu_func[MMU_DR_PGT].ctx_init(ctx);
		if (rc)
			return rc;
	}

	if (hdev->mmu_func[MMU_HR_PGT].ctx_init != NULL)
		rc = hdev->mmu_func[MMU_HR_PGT].ctx_init(ctx);

	return rc;
}

/*
 * hl_mmu_ctx_fini - disable a ctx from using the mmu module
 *
 * @ctx: pointer to the context structure
 *
 * This function does the following:
 * - Free any pgts which were not freed yet
 * - Free the mutex
 * - Free DRAM default page mapping hops
 */
void hl_mmu_ctx_fini(struct hl_ctx *ctx)
{
	struct hl_device *hdev = ctx->hdev;

	if (!hdev->mmu_enable)
		return;

	if (hdev->mmu_func[MMU_DR_PGT].ctx_fini != NULL)
		hdev->mmu_func[MMU_DR_PGT].ctx_fini(ctx);

	if (hdev->mmu_func[MMU_HR_PGT].ctx_fini != NULL)
		hdev->mmu_func[MMU_HR_PGT].ctx_fini(ctx);

	mutex_destroy(&ctx->mmu_lock);
}

/*
 * hl_mmu_unmap_page - unmaps a virtual addr
 *
 * @ctx: pointer to the context structure
 * @virt_addr: virt addr to map from
 * @page_size: size of the page to unmap
 * @flush_pte: whether to do a PCI flush
 *
 * This function does the following:
 * - Check that the virt addr is mapped
 * - Unmap the virt addr and frees pgts if possible
 * - Returns 0 on success, -EINVAL if the given addr is not mapped
 *
 * Because this function changes the page tables in the device and because it
 * changes the MMU hash, it must be protected by a lock.
 * However, because it maps only a single page, the lock should be implemented
 * in a higher level in order to protect the entire mapping of the memory area
 *
 * For optimization reasons PCI flush may be requested once after unmapping of
 * large area.
 */
int hl_mmu_unmap_page(struct hl_ctx *ctx, u64 virt_addr, u32 page_size,
		bool flush_pte)
{
	struct hl_device *hdev = ctx->hdev;
	struct asic_fixed_properties *prop = &hdev->asic_prop;
	struct hl_mmu_properties *mmu_prop;
	u64 real_virt_addr;
	u32 real_page_size, npages;
	int i, rc = 0, pgt_residency;
	bool is_dram_addr;

	if (!hdev->mmu_enable)
		return 0;

	is_dram_addr = is_dram_va(hdev, virt_addr);

	if (is_dram_addr)
		mmu_prop = &prop->dmmu;
	else if ((page_size % prop->pmmu_huge.page_size) == 0)
		mmu_prop = &prop->pmmu_huge;
	else
		mmu_prop = &prop->pmmu;

	pgt_residency = mmu_prop->host_resident ? MMU_HR_PGT : MMU_DR_PGT;

	/*
	 * The H/W handles mapping of specific page sizes. Hence if the page
	 * size is bigger, we break it to sub-pages and unmap them separately.
	 */
	if ((page_size % mmu_prop->page_size) == 0) {
		real_page_size = mmu_prop->page_size;
	} else {
		dev_err(hdev->dev,
			"page size of %u is not %uKB aligned, can't unmap\n",
			page_size, mmu_prop->page_size >> 10);

		return -EFAULT;
	}

	npages = page_size / real_page_size;
	real_virt_addr = virt_addr;

	for (i = 0 ; i < npages ; i++) {
		rc = hdev->mmu_func[pgt_residency].unmap(ctx,
						real_virt_addr, is_dram_addr);
		if (rc)
			break;

		real_virt_addr += real_page_size;
	}

	if (flush_pte)
		hdev->mmu_func[pgt_residency].flush(ctx);

	return rc;
}

/*
 * hl_mmu_map_page - maps a virtual addr to physical addr
 *
 * @ctx: pointer to the context structure
 * @virt_addr: virt addr to map from
 * @phys_addr: phys addr to map to
 * @page_size: physical page size
 * @flush_pte: whether to do a PCI flush
 *
 * This function does the following:
 * - Check that the virt addr is not mapped
 * - Allocate pgts as necessary in order to map the virt addr to the phys
 * - Returns 0 on success, -EINVAL if addr is already mapped, or -ENOMEM.
 *
 * Because this function changes the page tables in the device and because it
 * changes the MMU hash, it must be protected by a lock.
 * However, because it maps only a single page, the lock should be implemented
 * in a higher level in order to protect the entire mapping of the memory area
 *
 * For optimization reasons PCI flush may be requested once after mapping of
 * large area.
 */
int hl_mmu_map_page(struct hl_ctx *ctx, u64 virt_addr, u64 phys_addr,
		u32 page_size, bool flush_pte)
{
	struct hl_device *hdev = ctx->hdev;
	struct asic_fixed_properties *prop = &hdev->asic_prop;
	struct hl_mmu_properties *mmu_prop;
	u64 real_virt_addr, real_phys_addr;
	u32 real_page_size, npages;
	int i, rc, pgt_residency, mapped_cnt = 0;
	bool is_dram_addr;


	if (!hdev->mmu_enable)
		return 0;

	is_dram_addr = is_dram_va(hdev, virt_addr);

	if (is_dram_addr)
		mmu_prop = &prop->dmmu;
	else if ((page_size % prop->pmmu_huge.page_size) == 0)
		mmu_prop = &prop->pmmu_huge;
	else
		mmu_prop = &prop->pmmu;

	pgt_residency = mmu_prop->host_resident ? MMU_HR_PGT : MMU_DR_PGT;

	/*
	 * The H/W handles mapping of specific page sizes. Hence if the page
	 * size is bigger, we break it to sub-pages and map them separately.
	 */
	if ((page_size % mmu_prop->page_size) == 0) {
		real_page_size = mmu_prop->page_size;
	} else {
		dev_err(hdev->dev,
			"page size of %u is not %uKB aligned, can't map\n",
			page_size, mmu_prop->page_size >> 10);

		return -EFAULT;
	}

	WARN_ONCE((phys_addr & (real_page_size - 1)),
		"Mapping 0x%llx with page size of 0x%x is erroneous! Address must be divisible by page size",
		phys_addr, real_page_size);

	npages = page_size / real_page_size;
	real_virt_addr = virt_addr;
	real_phys_addr = phys_addr;

	for (i = 0 ; i < npages ; i++) {
		rc = hdev->mmu_func[pgt_residency].map(ctx,
						real_virt_addr, real_phys_addr,
						real_page_size, is_dram_addr);
		if (rc)
			goto err;

		real_virt_addr += real_page_size;
		real_phys_addr += real_page_size;
		mapped_cnt++;
	}

	if (flush_pte)
		hdev->mmu_func[pgt_residency].flush(ctx);

	return 0;

err:
	real_virt_addr = virt_addr;
	for (i = 0 ; i < mapped_cnt ; i++) {
		if (hdev->mmu_func[pgt_residency].unmap(ctx,
						real_virt_addr, is_dram_addr))
			dev_warn_ratelimited(hdev->dev,
				"failed to unmap va: 0x%llx\n", real_virt_addr);

		real_virt_addr += real_page_size;
	}

	hdev->mmu_func[pgt_residency].flush(ctx);

	return rc;
}

/*
 * hl_mmu_map_contiguous - implements a wrapper for hl_mmu_map_page
 *                         for mapping contiguous physical memory
 *
 * @ctx: pointer to the context structure
 * @virt_addr: virt addr to map from
 * @phys_addr: phys addr to map to
 * @size: size to map
 *
 */
int hl_mmu_map_contiguous(struct hl_ctx *ctx, u64 virt_addr,
					u64 phys_addr, u32 size)
{
	struct hl_device *hdev = ctx->hdev;
	struct asic_fixed_properties *prop = &hdev->asic_prop;
	u64 curr_va, curr_pa;
	u32 page_size;
	bool flush_pte;
	int rc = 0, off;

	if (hl_mem_area_inside_range(virt_addr, size,
			prop->dmmu.start_addr, prop->dmmu.end_addr))
		page_size = prop->dmmu.page_size;
	else if (hl_mem_area_inside_range(virt_addr, size,
			prop->pmmu.start_addr, prop->pmmu.end_addr))
		page_size = prop->pmmu.page_size;
	else if (hl_mem_area_inside_range(virt_addr, size,
			prop->pmmu_huge.start_addr, prop->pmmu_huge.end_addr))
		page_size = prop->pmmu_huge.page_size;
	else
		return -EINVAL;

	for (off = 0 ; off < size ; off += page_size) {
		curr_va = virt_addr + off;
		curr_pa = phys_addr + off;
		flush_pte = (off + page_size) >= size;
		rc = hl_mmu_map_page(ctx, curr_va, curr_pa, page_size,
								flush_pte);
		if (rc) {
			dev_err(hdev->dev,
				"Map failed for va 0x%llx to pa 0x%llx\n",
				curr_va, curr_pa);
			goto unmap;
		}
	}

	return rc;

unmap:
	for (; off >= 0 ; off -= page_size) {
		curr_va = virt_addr + off;
		flush_pte = (off - (s32) page_size) < 0;
		if (hl_mmu_unmap_page(ctx, curr_va, page_size, flush_pte))
			dev_warn_ratelimited(hdev->dev,
				"failed to unmap va 0x%llx\n", curr_va);
	}

	return rc;
}

/*
 * hl_mmu_unmap_contiguous - implements a wrapper for hl_mmu_unmap_page
 *                           for unmapping contiguous physical memory
 *
 * @ctx: pointer to the context structure
 * @virt_addr: virt addr to unmap
 * @size: size to unmap
 *
 */
int hl_mmu_unmap_contiguous(struct hl_ctx *ctx, u64 virt_addr, u32 size)
{
	struct hl_device *hdev = ctx->hdev;
	struct asic_fixed_properties *prop = &hdev->asic_prop;
	u64 curr_va;
	u32 page_size;
	bool flush_pte;
	int rc = 0, off;

	if (hl_mem_area_inside_range(virt_addr, size,
			prop->dmmu.start_addr, prop->dmmu.end_addr))
		page_size = prop->dmmu.page_size;
	else if (hl_mem_area_inside_range(virt_addr, size,
			prop->pmmu.start_addr, prop->pmmu.end_addr))
		page_size = prop->pmmu.page_size;
	else if (hl_mem_area_inside_range(virt_addr, size,
			prop->pmmu_huge.start_addr, prop->pmmu_huge.end_addr))
		page_size = prop->pmmu_huge.page_size;
	else
		return -EINVAL;

	for (off = 0 ; off < size ; off += page_size) {
		curr_va = virt_addr + off;
		flush_pte = (off + page_size) >= size;
		rc = hl_mmu_unmap_page(ctx, curr_va, page_size, flush_pte);
		if (rc)
			dev_warn_ratelimited(hdev->dev,
				"Unmap failed for va 0x%llx\n", curr_va);
	}

	return rc;
}

/*
 * hl_mmu_swap_out - marks all mapping of the given ctx as swapped out
 *
 * @ctx: pointer to the context structure
 *
 */
void hl_mmu_swap_out(struct hl_ctx *ctx)
{
	struct hl_device *hdev = ctx->hdev;

	if (!hdev->mmu_enable)
		return;

	if (hdev->mmu_func[MMU_DR_PGT].swap_out != NULL)
		hdev->mmu_func[MMU_DR_PGT].swap_out(ctx);

	if (hdev->mmu_func[MMU_HR_PGT].swap_out != NULL)
		hdev->mmu_func[MMU_HR_PGT].swap_out(ctx);
}

/*
 * hl_mmu_swap_in - marks all mapping of the given ctx as swapped in
 *
 * @ctx: pointer to the context structure
 *
 */
void hl_mmu_swap_in(struct hl_ctx *ctx)
{
	struct hl_device *hdev = ctx->hdev;

	if (!hdev->mmu_enable)
		return;

	if (hdev->mmu_func[MMU_DR_PGT].swap_in != NULL)
		hdev->mmu_func[MMU_DR_PGT].swap_in(ctx);

	if (hdev->mmu_func[MMU_HR_PGT].swap_in != NULL)
		hdev->mmu_func[MMU_HR_PGT].swap_in(ctx);
}

int hl_mmu_va_to_pa(struct hl_ctx *ctx, u64 virt_addr, u64 *phys_addr)
{
	struct hl_mmu_hop_info hops;
	u64 tmp_addr;
	int rc;

	rc = hl_mmu_get_tlb_info(ctx, virt_addr, &hops);
	if (rc)
		return rc;

	/* last hop holds the phys address and flags */
	tmp_addr = hops.hop_info[hops.used_hops - 1].hop_pte_val;
	*phys_addr = (tmp_addr & HOP_PHYS_ADDR_MASK) | (virt_addr & FLAGS_MASK);

	return 0;
}

int hl_mmu_get_tlb_info(struct hl_ctx *ctx, u64 virt_addr,
			struct hl_mmu_hop_info *hops)
{
	struct hl_device *hdev = ctx->hdev;
	struct asic_fixed_properties *prop = &hdev->asic_prop;
	struct hl_mmu_properties *mmu_prop;
	int rc;
	bool is_dram_addr;

	if (!hdev->mmu_enable)
		return -EOPNOTSUPP;

	is_dram_addr = hl_mem_area_inside_range(virt_addr, prop->dmmu.page_size,
						prop->dmmu.start_addr,
						prop->dmmu.end_addr);

	/* host-residency is the same in PMMU and HPMMU, use one of them */
	mmu_prop = is_dram_addr ? &prop->dmmu : &prop->pmmu;

	mutex_lock(&ctx->mmu_lock);

	if (mmu_prop->host_resident)
		rc = hdev->mmu_func[MMU_HR_PGT].get_tlb_info(ctx,
							virt_addr, hops);
	else
		rc = hdev->mmu_func[MMU_DR_PGT].get_tlb_info(ctx,
							virt_addr, hops);

	mutex_unlock(&ctx->mmu_lock);

	return rc;
}

int hl_mmu_if_set_funcs(struct hl_device *hdev)
{
	if (!hdev->mmu_enable)
		return 0;

	switch (hdev->asic_type) {
	case ASIC_GOYA:
	case ASIC_GAUDI:
		hl_mmu_v1_set_funcs(hdev, &hdev->mmu_func[MMU_DR_PGT]);
		break;
	default:
		dev_err(hdev->dev, "Unrecognized ASIC type %d\n",
			hdev->asic_type);
		return -EOPNOTSUPP;
	}

	return 0;
}
