/*
 * Copyright 2018 Advanced Micro Devices, Inc.
 * All Rights Reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sub license, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
 * USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * The above copyright notice and this permission notice (including the
 * next paragraph) shall be included in all copies or substantial portions
 * of the Software.
 *
 */

#include <linux/io-64-nonatomic-lo-hi.h>
#ifdef CONFIG_X86
#include <asm/hypervisor.h>
#endif

#include "amdgpu.h"
#include "amdgpu_gmc.h"
#include "amdgpu_ras.h"
#include "amdgpu_reset.h"
#include "amdgpu_xgmi.h"
#include "amdgpu_atomfirmware.h"

#include <drm/drm_drv.h>
#include <drm/ttm/ttm_tt.h>

static const u64 four_gb = 0x100000000ULL;

bool amdgpu_gmc_is_pdb0_enabled(struct amdgpu_device *adev)
{
	return adev->gmc.xgmi.connected_to_cpu || amdgpu_virt_xgmi_migrate_enabled(adev);
}

/**
 * amdgpu_gmc_pdb0_alloc - allocate vram for pdb0
 *
 * @adev: amdgpu_device pointer
 *
 * Allocate video memory for pdb0 and map it for CPU access
 * Returns 0 for success, error for failure.
 */
int amdgpu_gmc_pdb0_alloc(struct amdgpu_device *adev)
{
	int r;
	struct amdgpu_bo_param bp;
	u64 vram_size = adev->gmc.xgmi.node_segment_size * adev->gmc.xgmi.num_physical_nodes;
	uint32_t pde0_page_shift = adev->gmc.vmid0_page_table_block_size + 21;
	uint32_t npdes = (vram_size + (1ULL << pde0_page_shift) - 1) >> pde0_page_shift;

	memset(&bp, 0, sizeof(bp));
	bp.size = PAGE_ALIGN((npdes + 1) * 8);
	bp.byte_align = PAGE_SIZE;
	bp.domain = AMDGPU_GEM_DOMAIN_VRAM;
	bp.flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED |
		AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
	bp.type = ttm_bo_type_kernel;
	bp.resv = NULL;
	bp.bo_ptr_size = sizeof(struct amdgpu_bo);

	r = amdgpu_bo_create(adev, &bp, &adev->gmc.pdb0_bo);
	if (r)
		return r;

	r = amdgpu_bo_reserve(adev->gmc.pdb0_bo, false);
	if (unlikely(r != 0))
		goto bo_reserve_failure;

	r = amdgpu_bo_pin(adev->gmc.pdb0_bo, AMDGPU_GEM_DOMAIN_VRAM);
	if (r)
		goto bo_pin_failure;
	r = amdgpu_bo_kmap(adev->gmc.pdb0_bo, &adev->gmc.ptr_pdb0);
	if (r)
		goto bo_kmap_failure;

	amdgpu_bo_unreserve(adev->gmc.pdb0_bo);
	return 0;

bo_kmap_failure:
	amdgpu_bo_unpin(adev->gmc.pdb0_bo);
bo_pin_failure:
	amdgpu_bo_unreserve(adev->gmc.pdb0_bo);
bo_reserve_failure:
	amdgpu_bo_unref(&adev->gmc.pdb0_bo);
	return r;
}

/**
 * amdgpu_gmc_get_pde_for_bo - get the PDE for a BO
 *
 * @bo: the BO to get the PDE for
 * @level: the level in the PD hirarchy
 * @addr: resulting addr
 * @flags: resulting flags
 *
 * Get the address and flags to be used for a PDE (Page Directory Entry).
 */
void amdgpu_gmc_get_pde_for_bo(struct amdgpu_bo *bo, int level,
			       uint64_t *addr, uint64_t *flags)
{
	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);

	switch (bo->tbo.resource->mem_type) {
	case TTM_PL_TT:
		*addr = bo->tbo.ttm->dma_address[0];
		break;
	case TTM_PL_VRAM:
		*addr = amdgpu_bo_gpu_offset(bo);
		break;
	default:
		*addr = 0;
		break;
	}
	*flags = amdgpu_ttm_tt_pde_flags(bo->tbo.ttm, bo->tbo.resource);
	amdgpu_gmc_get_vm_pde(adev, level, addr, flags);
}

/*
 * amdgpu_gmc_pd_addr - return the address of the root directory
 */
uint64_t amdgpu_gmc_pd_addr(struct amdgpu_bo *bo)
{
	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
	uint64_t pd_addr;

	/* TODO: move that into ASIC specific code */
	if (adev->asic_type >= CHIP_VEGA10) {
		uint64_t flags = AMDGPU_PTE_VALID;

		amdgpu_gmc_get_pde_for_bo(bo, -1, &pd_addr, &flags);
		pd_addr |= flags;
	} else {
		pd_addr = amdgpu_bo_gpu_offset(bo);
	}
	return pd_addr;
}

/**
 * amdgpu_gmc_set_pte_pde - update the page tables using CPU
 *
 * @adev: amdgpu_device pointer
 * @cpu_pt_addr: cpu address of the page table
 * @gpu_page_idx: entry in the page table to update
 * @addr: dst addr to write into pte/pde
 * @flags: access flags
 *
 * Update the page tables using CPU.
 */
int amdgpu_gmc_set_pte_pde(struct amdgpu_device *adev, void *cpu_pt_addr,
				uint32_t gpu_page_idx, uint64_t addr,
				uint64_t flags)
{
	void __iomem *ptr = (void *)cpu_pt_addr;
	uint64_t value;

	/*
	 * The following is for PTE only. GART does not have PDEs.
	*/
	value = addr & adev->gmc.pte_addr_mask;
	value |= flags;
	writeq(value, ptr + (gpu_page_idx * 8));

	return 0;
}

/**
 * amdgpu_gmc_agp_addr - return the address in the AGP address space
 *
 * @bo: TTM BO which needs the address, must be in GTT domain
 *
 * Tries to figure out how to access the BO through the AGP aperture. Returns
 * AMDGPU_BO_INVALID_OFFSET if that is not possible.
 */
uint64_t amdgpu_gmc_agp_addr(struct ttm_buffer_object *bo)
{
	struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);

	if (!bo->ttm)
		return AMDGPU_BO_INVALID_OFFSET;

	if (bo->ttm->num_pages != 1 || bo->ttm->caching == ttm_cached)
		return AMDGPU_BO_INVALID_OFFSET;

	if (bo->ttm->dma_address[0] + PAGE_SIZE >= adev->gmc.agp_size)
		return AMDGPU_BO_INVALID_OFFSET;

	return adev->gmc.agp_start + bo->ttm->dma_address[0];
}

/**
 * amdgpu_gmc_vram_location - try to find VRAM location
 *
 * @adev: amdgpu device structure holding all necessary information
 * @mc: memory controller structure holding memory information
 * @base: base address at which to put VRAM
 *
 * Function will try to place VRAM at base address provided
 * as parameter.
 */
void amdgpu_gmc_vram_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc,
			      u64 base)
{
	uint64_t vis_limit = (uint64_t)amdgpu_vis_vram_limit << 20;
	uint64_t limit = (uint64_t)amdgpu_vram_limit << 20;

	mc->vram_start = base;
	mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
	if (limit < mc->real_vram_size)
		mc->real_vram_size = limit;

	if (vis_limit && vis_limit < mc->visible_vram_size)
		mc->visible_vram_size = vis_limit;

	if (mc->real_vram_size < mc->visible_vram_size)
		mc->visible_vram_size = mc->real_vram_size;

	if (mc->xgmi.num_physical_nodes == 0) {
		mc->fb_start = mc->vram_start;
		mc->fb_end = mc->vram_end;
	}
	dev_info(adev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n",
			mc->mc_vram_size >> 20, mc->vram_start,
			mc->vram_end, mc->real_vram_size >> 20);
}

/** amdgpu_gmc_sysvm_location - place vram and gart in sysvm aperture
 *
 * @adev: amdgpu device structure holding all necessary information
 * @mc: memory controller structure holding memory information
 *
 * This function is only used if use GART for FB translation. In such
 * case, we use sysvm aperture (vmid0 page tables) for both vram
 * and gart (aka system memory) access.
 *
 * GPUVM (and our organization of vmid0 page tables) require sysvm
 * aperture to be placed at a location aligned with 8 times of native
 * page size. For example, if vm_context0_cntl.page_table_block_size
 * is 12, then native page size is 8G (2M*2^12), sysvm should start
 * with a 64G aligned address. For simplicity, we just put sysvm at
 * address 0. So vram start at address 0 and gart is right after vram.
 */
void amdgpu_gmc_sysvm_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc)
{
	u64 hive_vram_start = 0;
	u64 hive_vram_end = mc->xgmi.node_segment_size * mc->xgmi.num_physical_nodes - 1;
	mc->vram_start = mc->xgmi.node_segment_size * mc->xgmi.physical_node_id;
	mc->vram_end = mc->vram_start + mc->xgmi.node_segment_size - 1;
	/* node_segment_size may not 4GB aligned on SRIOV, align up is needed. */
	mc->gart_start = ALIGN(hive_vram_end + 1, four_gb);
	mc->gart_end = mc->gart_start + mc->gart_size - 1;
	if (amdgpu_virt_xgmi_migrate_enabled(adev)) {
		/* set mc->vram_start to 0 to switch the returned GPU address of
		 * amdgpu_bo_create_reserved() from FB aperture to GART aperture.
		 */
		mc->vram_start = 0;
		mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
		mc->visible_vram_size = min(mc->visible_vram_size, mc->real_vram_size);
	} else {
		mc->fb_start = hive_vram_start;
		mc->fb_end = hive_vram_end;
	}
	dev_info(adev->dev, "VRAM: %lluM 0x%016llX - 0x%016llX (%lluM used)\n",
			mc->mc_vram_size >> 20, mc->vram_start,
			mc->vram_end, mc->real_vram_size >> 20);
	dev_info(adev->dev, "GART: %lluM 0x%016llX - 0x%016llX\n",
			mc->gart_size >> 20, mc->gart_start, mc->gart_end);
}

void amdgpu_gmc_set_gart_size(struct amdgpu_device *adev, u64 default_size)
{
	if (amdgpu_gart_size == -1)
		adev->gmc.gart_size =
			default_size + adev->pm.smu_prv_buffer_size;
	else
		adev->gmc.gart_size = (u64)amdgpu_gart_size << 20;
}

/**
 * amdgpu_gmc_gart_location - try to find GART location
 *
 * @adev: amdgpu device structure holding all necessary information
 * @mc: memory controller structure holding memory information
 * @gart_placement: GART placement policy with respect to VRAM
 *
 * Function will try to place GART before or after VRAM.
 * If GART size is bigger than space left then we ajust GART size.
 * Thus function will never fails.
 */
void amdgpu_gmc_gart_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc,
			      enum amdgpu_gart_placement gart_placement)
{
	u64 size_af, size_bf;
	/*To avoid the hole, limit the max mc address to AMDGPU_GMC_HOLE_START*/
	u64 max_mc_address = min(adev->gmc.mc_mask, AMDGPU_GMC_HOLE_START - 1);

	/* VCE doesn't like it when BOs cross a 4GB segment, so align
	 * the GART base on a 4GB boundary as well.
	 */
	size_bf = mc->fb_start;
	size_af = max_mc_address + 1 - ALIGN(mc->fb_end + 1, four_gb);

	if (mc->gart_size > max(size_bf, size_af)) {
		dev_warn(adev->dev, "limiting GART\n");
		mc->gart_size = max(size_bf, size_af);
	}

	switch (gart_placement) {
	case AMDGPU_GART_PLACEMENT_HIGH:
		mc->gart_start = max_mc_address - mc->gart_size + 1;
		break;
	case AMDGPU_GART_PLACEMENT_LOW:
		if (size_bf >= mc->gart_size)
			mc->gart_start = 0;
		else
			mc->gart_start = ALIGN(mc->fb_end, four_gb);
		break;
	case AMDGPU_GART_PLACEMENT_BEST_FIT:
	default:
		if ((size_bf >= mc->gart_size && size_bf < size_af) ||
		    (size_af < mc->gart_size))
			mc->gart_start = 0;
		else
			mc->gart_start = max_mc_address - mc->gart_size + 1;
		break;
	}

	mc->gart_start &= ~(four_gb - 1);
	mc->gart_end = mc->gart_start + mc->gart_size - 1;
	dev_info(adev->dev, "GART: %lluM 0x%016llX - 0x%016llX\n",
			mc->gart_size >> 20, mc->gart_start, mc->gart_end);
}

/**
 * amdgpu_gmc_agp_location - try to find AGP location
 * @adev: amdgpu device structure holding all necessary information
 * @mc: memory controller structure holding memory information
 *
 * Function will place try to find a place for the AGP BAR in the MC address
 * space.
 *
 * AGP BAR will be assigned the largest available hole in the address space.
 * Should be called after VRAM and GART locations are setup.
 */
void amdgpu_gmc_agp_location(struct amdgpu_device *adev, struct amdgpu_gmc *mc)
{
	const uint64_t sixteen_gb = 1ULL << 34;
	const uint64_t sixteen_gb_mask = ~(sixteen_gb - 1);
	u64 size_af, size_bf;

	if (mc->fb_start > mc->gart_start) {
		size_bf = (mc->fb_start & sixteen_gb_mask) -
			ALIGN(mc->gart_end + 1, sixteen_gb);
		size_af = mc->mc_mask + 1 - ALIGN(mc->fb_end + 1, sixteen_gb);
	} else {
		size_bf = mc->fb_start & sixteen_gb_mask;
		size_af = (mc->gart_start & sixteen_gb_mask) -
			ALIGN(mc->fb_end + 1, sixteen_gb);
	}

	if (size_bf > size_af) {
		mc->agp_start = (mc->fb_start - size_bf) & sixteen_gb_mask;
		mc->agp_size = size_bf;
	} else {
		mc->agp_start = ALIGN(mc->fb_end + 1, sixteen_gb);
		mc->agp_size = size_af;
	}

	mc->agp_end = mc->agp_start + mc->agp_size - 1;
	dev_info(adev->dev, "AGP: %lluM 0x%016llX - 0x%016llX\n",
			mc->agp_size >> 20, mc->agp_start, mc->agp_end);
}

/**
 * amdgpu_gmc_set_agp_default - Set the default AGP aperture value.
 * @adev: amdgpu device structure holding all necessary information
 * @mc: memory controller structure holding memory information
 *
 * To disable the AGP aperture, you need to set the start to a larger
 * value than the end.  This function sets the default value which
 * can then be overridden using amdgpu_gmc_agp_location() if you want
 * to enable the AGP aperture on a specific chip.
 *
 */
void amdgpu_gmc_set_agp_default(struct amdgpu_device *adev,
				struct amdgpu_gmc *mc)
{
	mc->agp_start = 0xffffffffffff;
	mc->agp_end = 0;
	mc->agp_size = 0;
}

/**
 * amdgpu_gmc_fault_key - get hask key from vm fault address and pasid
 *
 * @addr: 48 bit physical address, page aligned (36 significant bits)
 * @pasid: 16 bit process address space identifier
 */
static inline uint64_t amdgpu_gmc_fault_key(uint64_t addr, uint16_t pasid)
{
	return addr << 4 | pasid;
}

/**
 * amdgpu_gmc_filter_faults - filter VM faults
 *
 * @adev: amdgpu device structure
 * @ih: interrupt ring that the fault received from
 * @addr: address of the VM fault
 * @pasid: PASID of the process causing the fault
 * @timestamp: timestamp of the fault
 *
 * Returns:
 * True if the fault was filtered and should not be processed further.
 * False if the fault is a new one and needs to be handled.
 */
bool amdgpu_gmc_filter_faults(struct amdgpu_device *adev,
			      struct amdgpu_ih_ring *ih, uint64_t addr,
			      uint16_t pasid, uint64_t timestamp)
{
	struct amdgpu_gmc *gmc = &adev->gmc;
	uint64_t stamp, key = amdgpu_gmc_fault_key(addr, pasid);
	struct amdgpu_gmc_fault *fault;
	uint32_t hash;

	/* Stale retry fault if timestamp goes backward */
	if (amdgpu_ih_ts_after(timestamp, ih->processed_timestamp))
		return true;

	/* If we don't have space left in the ring buffer return immediately */
	stamp = max(timestamp, AMDGPU_GMC_FAULT_TIMEOUT + 1) -
		AMDGPU_GMC_FAULT_TIMEOUT;
	if (gmc->fault_ring[gmc->last_fault].timestamp >= stamp)
		return true;

	/* Try to find the fault in the hash */
	hash = hash_64(key, AMDGPU_GMC_FAULT_HASH_ORDER);
	fault = &gmc->fault_ring[gmc->fault_hash[hash].idx];
	while (fault->timestamp >= stamp) {
		uint64_t tmp;

		if (atomic64_read(&fault->key) == key) {
			/*
			 * if we get a fault which is already present in
			 * the fault_ring and the timestamp of
			 * the fault is after the expired timestamp,
			 * then this is a new fault that needs to be added
			 * into the fault ring.
			 */
			if (fault->timestamp_expiry != 0 &&
			    amdgpu_ih_ts_after(fault->timestamp_expiry,
					       timestamp))
				break;
			else
				return true;
		}

		tmp = fault->timestamp;
		fault = &gmc->fault_ring[fault->next];

		/* Check if the entry was reused */
		if (fault->timestamp >= tmp)
			break;
	}

	/* Add the fault to the ring */
	fault = &gmc->fault_ring[gmc->last_fault];
	atomic64_set(&fault->key, key);
	fault->timestamp = timestamp;

	/* And update the hash */
	fault->next = gmc->fault_hash[hash].idx;
	gmc->fault_hash[hash].idx = gmc->last_fault++;
	return false;
}

/**
 * amdgpu_gmc_filter_faults_remove - remove address from VM faults filter
 *
 * @adev: amdgpu device structure
 * @addr: address of the VM fault
 * @pasid: PASID of the process causing the fault
 *
 * Remove the address from fault filter, then future vm fault on this address
 * will pass to retry fault handler to recover.
 */
void amdgpu_gmc_filter_faults_remove(struct amdgpu_device *adev, uint64_t addr,
				     uint16_t pasid)
{
	struct amdgpu_gmc *gmc = &adev->gmc;
	uint64_t key = amdgpu_gmc_fault_key(addr, pasid);
	struct amdgpu_ih_ring *ih;
	struct amdgpu_gmc_fault *fault;
	uint32_t last_wptr;
	uint64_t last_ts;
	uint32_t hash;
	uint64_t tmp;

	if (adev->irq.retry_cam_enabled)
		return;
	else if (adev->irq.ih1.ring_size)
		ih = &adev->irq.ih1;
	else if (adev->irq.ih_soft.enabled)
		ih = &adev->irq.ih_soft;
	else
		return;

	/* Get the WPTR of the last entry in IH ring */
	last_wptr = amdgpu_ih_get_wptr(adev, ih);
	/* Order wptr with ring data. */
	rmb();
	/* Get the timetamp of the last entry in IH ring */
	last_ts = amdgpu_ih_decode_iv_ts(adev, ih, last_wptr, -1);

	hash = hash_64(key, AMDGPU_GMC_FAULT_HASH_ORDER);
	fault = &gmc->fault_ring[gmc->fault_hash[hash].idx];
	do {
		if (atomic64_read(&fault->key) == key) {
			/*
			 * Update the timestamp when this fault
			 * expired.
			 */
			fault->timestamp_expiry = last_ts;
			break;
		}

		tmp = fault->timestamp;
		fault = &gmc->fault_ring[fault->next];
	} while (fault->timestamp < tmp);
}

int amdgpu_gmc_handle_retry_fault(struct amdgpu_device *adev,
				  struct amdgpu_iv_entry *entry,
				  u64 addr,
				  u32 cam_index,
				  u32 node_id,
				  bool write_fault)
{
	int ret;

	if (adev->irq.retry_cam_enabled) {
		/* Delegate it to a different ring if the hardware hasn't
		 * already done it.
		 */
		if (entry->ih == &adev->irq.ih) {
			amdgpu_irq_delegate(adev, entry, 8);
			return 1;
		}

		ret = amdgpu_vm_handle_fault(adev, entry->pasid, entry->vmid, node_id,
					     addr, entry->timestamp, write_fault);
		WDOORBELL32(adev->irq.retry_cam_doorbell_index, cam_index);
		if (ret)
			return 1;
	} else {
		/* Process it only if it's the first fault for this address */
		if (entry->ih != &adev->irq.ih_soft &&
		    amdgpu_gmc_filter_faults(adev, entry->ih, addr, entry->pasid,
					     entry->timestamp))
			return 1;

		/* Delegate it to a different ring if the hardware hasn't
		 * already done it.
		 */
		if (entry->ih == &adev->irq.ih) {
			amdgpu_irq_delegate(adev, entry, 8);
			return 1;
		}

		/* Try to handle the recoverable page faults by filling page
		 * tables
		 */
		if (amdgpu_vm_handle_fault(adev, entry->pasid, entry->vmid, node_id,
					   addr, entry->timestamp, write_fault))
			return 1;
	}
	return 0;
}

int amdgpu_gmc_ras_sw_init(struct amdgpu_device *adev)
{
	int r;

	/* umc ras block */
	r = amdgpu_umc_ras_sw_init(adev);
	if (r)
		return r;

	/* mmhub ras block */
	r = amdgpu_mmhub_ras_sw_init(adev);
	if (r)
		return r;

	/* hdp ras block */
	r = amdgpu_hdp_ras_sw_init(adev);
	if (r)
		return r;

	/* mca.x ras block */
	r = amdgpu_mca_mp0_ras_sw_init(adev);
	if (r)
		return r;

	r = amdgpu_mca_mp1_ras_sw_init(adev);
	if (r)
		return r;

	r = amdgpu_mca_mpio_ras_sw_init(adev);
	if (r)
		return r;

	/* xgmi ras block */
	r = amdgpu_xgmi_ras_sw_init(adev);
	if (r)
		return r;

	return 0;
}

	/*
	 * The latest engine allocation on gfx9/10 is:
	 * Engine 2, 3: firmware
	 * Engine 0, 1, 4~16: amdgpu ring,
	 *                    subject to change when ring number changes
	 * Engine 17: Gart flushes
	 */
#define AMDGPU_VMHUB_INV_ENG_BITMAP		0x1FFF3

int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev)
{
	struct amdgpu_ring *ring;
	unsigned vm_inv_engs[AMDGPU_MAX_VMHUBS] = {0};
	unsigned i;
	unsigned vmhub, inv_eng;
	struct amdgpu_ring *shared_ring;

	/* init the vm inv eng for all vmhubs */
	for_each_set_bit(i, adev->vmhubs_mask, AMDGPU_MAX_VMHUBS) {
		vm_inv_engs[i] = AMDGPU_VMHUB_INV_ENG_BITMAP;
		/* reserve engine 5 for firmware */
		if (adev->enable_mes)
			vm_inv_engs[i] &= ~(1 << 5);
		/* reserve engine 6 for uni mes */
		if (adev->enable_uni_mes)
			vm_inv_engs[i] &= ~(1 << 6);
		/* reserve mmhub engine 3 for firmware */
		if (adev->enable_umsch_mm)
			vm_inv_engs[i] &= ~(1 << 3);
	}

	for (i = 0; i < adev->num_rings; ++i) {
		ring = adev->rings[i];
		vmhub = ring->vm_hub;

		if (ring == &adev->mes.ring[0] ||
		    ring == &adev->mes.ring[1] ||
		    ring == &adev->umsch_mm.ring ||
		    ring == &adev->cper.ring_buf)
			continue;

		/* Skip if the ring is a shared ring */
		if (amdgpu_sdma_is_shared_inv_eng(adev, ring))
			continue;

		inv_eng = ffs(vm_inv_engs[vmhub]);
		if (!inv_eng) {
			dev_err(adev->dev, "no VM inv eng for ring %s\n",
				ring->name);
			return -EINVAL;
		}

		ring->vm_inv_eng = inv_eng - 1;
		vm_inv_engs[vmhub] &= ~(1 << ring->vm_inv_eng);

		dev_info(adev->dev, "ring %s uses VM inv eng %u on hub %u\n",
			 ring->name, ring->vm_inv_eng, ring->vm_hub);
		/* SDMA has a special packet which allows it to use the same
		 * invalidation engine for all the rings in one instance.
		 * Therefore, we do not allocate a separate VM invalidation engine
		 * for SDMA page rings. Instead, they share the VM invalidation
		 * engine with the SDMA gfx ring. This change ensures efficient
		 * resource management and avoids the issue of insufficient VM
		 * invalidation engines.
		 */
		shared_ring = amdgpu_sdma_get_shared_ring(adev, ring);
		if (shared_ring) {
			shared_ring->vm_inv_eng = ring->vm_inv_eng;
			dev_info(adev->dev, "ring %s shares VM invalidation engine %u with ring %s on hub %u\n",
					ring->name, ring->vm_inv_eng, shared_ring->name, ring->vm_hub);
			continue;
		}
	}

	return 0;
}

void amdgpu_gmc_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
			      uint32_t vmhub, uint32_t flush_type)
{
	struct amdgpu_ring *ring;
	struct amdgpu_vmhub *hub = &adev->vmhub[vmhub];
	struct dma_fence *fence;
	struct amdgpu_job *job;
	int r;

	ring = to_amdgpu_ring(adev->mman.buffer_funcs_scheds[0]);

	if (!hub->sdma_invalidation_workaround || vmid ||
	    !adev->mman.buffer_funcs_enabled || !adev->ib_pool_ready ||
	    !ring->sched.ready) {
		/*
		 * A GPU reset should flush all TLBs anyway, so no need to do
		 * this while one is ongoing.
		 */
		if (!down_read_trylock(&adev->reset_domain->sem))
			return;

		if (adev->gmc.flush_tlb_needs_extra_type_2)
			adev->gmc.gmc_funcs->flush_gpu_tlb(adev, vmid,
							   vmhub, 2);

		if (adev->gmc.flush_tlb_needs_extra_type_0 && flush_type == 2)
			adev->gmc.gmc_funcs->flush_gpu_tlb(adev, vmid,
							   vmhub, 0);

		adev->gmc.gmc_funcs->flush_gpu_tlb(adev, vmid, vmhub,
						   flush_type);
		up_read(&adev->reset_domain->sem);
		return;
	}

	/* The SDMA on Navi 1x has a bug which can theoretically result in memory
	 * corruption if an invalidation happens at the same time as an VA
	 * translation. Avoid this by doing the invalidation from the SDMA
	 * itself at least for GART.
	 */
	mutex_lock(&adev->mman.default_entity.lock);
	r = amdgpu_job_alloc_with_ib(ring->adev, &adev->mman.default_entity.base,
				     AMDGPU_FENCE_OWNER_UNDEFINED,
				     16 * 4, AMDGPU_IB_POOL_IMMEDIATE,
				     AMDGPU_KERNEL_JOB_ID_FLUSH_GPU_TLB,
				     &job);
	if (r)
		goto error_alloc;

	job->vm_pd_addr = amdgpu_gmc_pd_addr(adev->gart.bo);
	job->vm_needs_flush = true;
	job->ibs->ptr[job->ibs->length_dw++] = ring->funcs->nop;
	amdgpu_ring_pad_ib(ring, &job->ibs[0]);
	fence = amdgpu_job_submit(job);
	mutex_unlock(&adev->mman.default_entity.lock);

	dma_fence_wait(fence, false);
	dma_fence_put(fence);

	return;

error_alloc:
	mutex_unlock(&adev->mman.default_entity.lock);
	dev_err(adev->dev, "Error flushing GPU TLB using the SDMA (%d)!\n", r);
}

int amdgpu_gmc_flush_gpu_tlb_pasid(struct amdgpu_device *adev, uint16_t pasid,
				   uint32_t flush_type, bool all_hub,
				   uint32_t inst)
{
	struct amdgpu_ring *ring = &adev->gfx.kiq[inst].ring;
	struct amdgpu_kiq *kiq = &adev->gfx.kiq[inst];
	unsigned int ndw;
	int r, cnt = 0;
	uint32_t seq;

	/*
	 * A GPU reset should flush all TLBs anyway, so no need to do
	 * this while one is ongoing.
	 */
	if (!down_read_trylock(&adev->reset_domain->sem))
		return 0;

	if (!adev->gmc.flush_pasid_uses_kiq || !ring->sched.ready) {

		if (!adev->gmc.gmc_funcs->flush_gpu_tlb_pasid) {
			r = 0;
			goto error_unlock_reset;
		}

		if (adev->gmc.flush_tlb_needs_extra_type_2)
			adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
								 2, all_hub,
								 inst);

		if (adev->gmc.flush_tlb_needs_extra_type_0 && flush_type == 2)
			adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
								 0, all_hub,
								 inst);

		adev->gmc.gmc_funcs->flush_gpu_tlb_pasid(adev, pasid,
							 flush_type, all_hub,
							 inst);
		r = 0;
	} else {
		/* 2 dwords flush + 8 dwords fence */
		ndw = kiq->pmf->invalidate_tlbs_size + 8;

		if (adev->gmc.flush_tlb_needs_extra_type_2)
			ndw += kiq->pmf->invalidate_tlbs_size;

		if (adev->gmc.flush_tlb_needs_extra_type_0)
			ndw += kiq->pmf->invalidate_tlbs_size;

		spin_lock(&adev->gfx.kiq[inst].ring_lock);
		r = amdgpu_ring_alloc(ring, ndw);
		if (r) {
			spin_unlock(&adev->gfx.kiq[inst].ring_lock);
			goto error_unlock_reset;
		}
		if (adev->gmc.flush_tlb_needs_extra_type_2)
			kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 2, all_hub);

		if (flush_type == 2 && adev->gmc.flush_tlb_needs_extra_type_0)
			kiq->pmf->kiq_invalidate_tlbs(ring, pasid, 0, all_hub);

		kiq->pmf->kiq_invalidate_tlbs(ring, pasid, flush_type, all_hub);
		r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
		if (r) {
			amdgpu_ring_undo(ring);
			spin_unlock(&adev->gfx.kiq[inst].ring_lock);
			goto error_unlock_reset;
		}

		amdgpu_ring_commit(ring);
		spin_unlock(&adev->gfx.kiq[inst].ring_lock);

		r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);

		might_sleep();
		while (r < 1 && cnt++ < MAX_KIQ_REG_TRY &&
		       !amdgpu_reset_pending(adev->reset_domain)) {
			msleep(MAX_KIQ_REG_BAILOUT_INTERVAL);
			r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
		}

		if (cnt > MAX_KIQ_REG_TRY) {
			dev_err(adev->dev, "timeout waiting for kiq fence\n");
			r = -ETIME;
		} else
			r = 0;
	}

error_unlock_reset:
	up_read(&adev->reset_domain->sem);
	return r;
}

void amdgpu_gmc_fw_reg_write_reg_wait(struct amdgpu_device *adev,
				      uint32_t reg0, uint32_t reg1,
				      uint32_t ref, uint32_t mask,
				      uint32_t xcc_inst)
{
	struct amdgpu_kiq *kiq = &adev->gfx.kiq[xcc_inst];
	struct amdgpu_ring *ring = &kiq->ring;
	signed long r, cnt = 0;
	unsigned long flags;
	uint32_t seq;

	if (adev->mes.ring[MES_PIPE_INST(xcc_inst, 0)].sched.ready) {
		amdgpu_mes_reg_write_reg_wait(adev, reg0, reg1,
					      ref, mask, xcc_inst);
		return;
	}

	spin_lock_irqsave(&kiq->ring_lock, flags);
	amdgpu_ring_alloc(ring, 32);
	amdgpu_ring_emit_reg_write_reg_wait(ring, reg0, reg1,
					    ref, mask);
	r = amdgpu_fence_emit_polling(ring, &seq, MAX_KIQ_REG_WAIT);
	if (r)
		goto failed_undo;

	amdgpu_ring_commit(ring);
	spin_unlock_irqrestore(&kiq->ring_lock, flags);

	r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);

	/* don't wait anymore for IRQ context */
	if (r < 1 && in_interrupt())
		goto failed_kiq;

	might_sleep();
	while (r < 1 && cnt++ < MAX_KIQ_REG_TRY &&
	       !amdgpu_reset_pending(adev->reset_domain)) {

		msleep(MAX_KIQ_REG_BAILOUT_INTERVAL);
		r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
	}

	if (cnt > MAX_KIQ_REG_TRY)
		goto failed_kiq;

	return;

failed_undo:
	amdgpu_ring_undo(ring);
	spin_unlock_irqrestore(&kiq->ring_lock, flags);
failed_kiq:
	dev_err(adev->dev, "failed to write reg %x wait reg %x\n", reg0, reg1);
}

/**
 * amdgpu_gmc_tmz_set -- check and set if a device supports TMZ
 * @adev: amdgpu_device pointer
 *
 * Check and set if an the device @adev supports Trusted Memory
 * Zones (TMZ).
 */
void amdgpu_gmc_tmz_set(struct amdgpu_device *adev)
{
	switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
	/* RAVEN */
	case IP_VERSION(9, 2, 2):
	case IP_VERSION(9, 1, 0):
	/* RENOIR looks like RAVEN */
	case IP_VERSION(9, 3, 0):
	/* GC 10.3.7 */
	case IP_VERSION(10, 3, 7):
	/* GC 11.0.1 */
	case IP_VERSION(11, 0, 1):
		if (amdgpu_tmz == 0) {
			adev->gmc.tmz_enabled = false;
			dev_info(adev->dev,
				 "Trusted Memory Zone (TMZ) feature disabled (cmd line)\n");
		} else {
			adev->gmc.tmz_enabled = true;
			dev_info(adev->dev,
				 "Trusted Memory Zone (TMZ) feature enabled\n");
		}
		break;
	case IP_VERSION(10, 1, 10):
	case IP_VERSION(10, 1, 1):
	case IP_VERSION(10, 1, 2):
	case IP_VERSION(10, 1, 3):
	case IP_VERSION(10, 3, 0):
	case IP_VERSION(10, 3, 2):
	case IP_VERSION(10, 3, 4):
	case IP_VERSION(10, 3, 5):
	case IP_VERSION(10, 3, 6):
	/* VANGOGH */
	case IP_VERSION(10, 3, 1):
	/* YELLOW_CARP*/
	case IP_VERSION(10, 3, 3):
	case IP_VERSION(11, 0, 4):
	case IP_VERSION(11, 5, 0):
	case IP_VERSION(11, 5, 1):
	case IP_VERSION(11, 5, 2):
	case IP_VERSION(11, 5, 3):
	case IP_VERSION(11, 5, 4):
	case IP_VERSION(11, 5, 6):
	case IP_VERSION(11, 7, 0):
	case IP_VERSION(11, 7, 1):
		/* Don't enable it by default yet.
		 */
		if (amdgpu_tmz < 1) {
			adev->gmc.tmz_enabled = false;
			dev_info(adev->dev,
				 "Trusted Memory Zone (TMZ) feature disabled as experimental (default)\n");
		} else {
			adev->gmc.tmz_enabled = true;
			dev_info(adev->dev,
				 "Trusted Memory Zone (TMZ) feature enabled as experimental (cmd line)\n");
		}
		break;
	default:
		adev->gmc.tmz_enabled = false;
		dev_info(adev->dev,
			 "Trusted Memory Zone (TMZ) feature not supported\n");
		break;
	}
}

/**
 * amdgpu_gmc_noretry_set -- set per asic noretry defaults
 * @adev: amdgpu_device pointer
 *
 * Set a per asic default for the no-retry parameter.
 *
 */
void amdgpu_gmc_noretry_set(struct amdgpu_device *adev)
{
	struct amdgpu_gmc *gmc = &adev->gmc;
	uint32_t gc_ver = amdgpu_ip_version(adev, GC_HWIP, 0);
	bool noretry_default = (gc_ver == IP_VERSION(9, 0, 1) ||
				gc_ver == IP_VERSION(9, 4, 0) ||
				gc_ver == IP_VERSION(9, 4, 1) ||
				gc_ver == IP_VERSION(9, 4, 2) ||
				gc_ver == IP_VERSION(9, 4, 3) ||
				gc_ver == IP_VERSION(9, 4, 4) ||
				gc_ver == IP_VERSION(9, 5, 0) ||
				gc_ver >= IP_VERSION(10, 1, 0));

	/* For GFX12.1 B0, set xnack (retry) on as default */
	if (gc_ver == IP_VERSION(12, 1, 0) && (adev->rev_id & 0xf) == 0x1)
		noretry_default = false;
	if (!amdgpu_sriov_xnack_support(adev))
		gmc->noretry = 1;
	else
		gmc->noretry = (amdgpu_noretry == -1) ? noretry_default : amdgpu_noretry;
}

void amdgpu_gmc_set_vm_fault_masks(struct amdgpu_device *adev, int hub_type,
				   bool enable)
{
	struct amdgpu_vmhub *hub;
	u32 tmp, reg, i;

	hub = &adev->vmhub[hub_type];
	for (i = 0; i < 16; i++) {
		reg = hub->vm_context0_cntl + hub->ctx_distance * i;

		tmp = (hub_type == AMDGPU_GFXHUB(0)) ?
			RREG32_SOC15_IP(GC, reg) :
			RREG32_SOC15_IP(MMHUB, reg);

		if (enable)
			tmp |= hub->vm_cntx_cntl_vm_fault;
		else
			tmp &= ~hub->vm_cntx_cntl_vm_fault;

		(hub_type == AMDGPU_GFXHUB(0)) ?
			WREG32_SOC15_IP(GC, reg, tmp) :
			WREG32_SOC15_IP(MMHUB, reg, tmp);
	}
}

void amdgpu_gmc_init_vga_resv_regions(struct amdgpu_device *adev)
{
	unsigned size;

	if (adev->gmc.is_app_apu)
		return;

	/*
	 * Some ASICs need to reserve a region of video memory to avoid access
	 * from driver
	 */
	/*
	 * TODO:
	 * Currently there is a bug where some memory client outside
	 * of the driver writes to first 8M of VRAM on S3 resume,
	 * this overrides GART which by default gets placed in first 8M and
	 * causes VM_FAULTS once GTT is accessed.
	 * Keep the stolen memory reservation until the while this is not solved.
	 */
	switch (adev->asic_type) {
	case CHIP_VEGA10:
		adev->mman.keep_stolen_vga_memory = true;
		/*
		 * VEGA10 SRIOV VF with MS_HYPERV host needs some firmware reserved area.
		 */
#ifdef CONFIG_X86
		if (amdgpu_sriov_vf(adev) && hypervisor_is_type(X86_HYPER_MS_HYPERV)) {
			amdgpu_ttm_init_vram_resv(adev, AMDGPU_RESV_STOLEN_RESERVED,
						  0x500000, 0x200000, false);
		}
#endif
		break;
	case CHIP_RAVEN:
	case CHIP_RENOIR:
		adev->mman.keep_stolen_vga_memory = true;
		break;
	case CHIP_POLARIS10:
	case CHIP_POLARIS11:
	case CHIP_POLARIS12:
		/* MacBookPros with switchable graphics put VRAM at 0 when
		 * the iGPU is enabled which results in cursor issues if
		 * the cursor ends up at 0.  Reserve vram at 0 in that case.
		 */
		if (adev->gmc.vram_start == 0)
			adev->mman.keep_stolen_vga_memory = true;
		break;
	default:
		adev->mman.keep_stolen_vga_memory = false;
		break;
	}

	if (amdgpu_sriov_vf(adev) ||
	    !amdgpu_device_has_display_hardware(adev)) {
		size = 0;
	} else {
		size = amdgpu_gmc_get_vbios_fb_size(adev);

		if (adev->mman.keep_stolen_vga_memory)
			size = max(size, (unsigned)AMDGPU_VBIOS_VGA_ALLOCATION);
	}

	/* set to 0 if the pre-OS buffer uses up most of vram */
	if ((adev->gmc.real_vram_size - size) < (8 * 1024 * 1024))
		size = 0;

	if (size > AMDGPU_VBIOS_VGA_ALLOCATION) {
		amdgpu_ttm_init_vram_resv(adev, AMDGPU_RESV_STOLEN_VGA,
					  0, AMDGPU_VBIOS_VGA_ALLOCATION, false);
		amdgpu_ttm_init_vram_resv(adev, AMDGPU_RESV_STOLEN_EXTENDED,
					  AMDGPU_VBIOS_VGA_ALLOCATION,
					  size - AMDGPU_VBIOS_VGA_ALLOCATION, false);
	} else {
		amdgpu_ttm_init_vram_resv(adev, AMDGPU_RESV_STOLEN_VGA,
					  0, size, false);
	}
}

/**
 * amdgpu_gmc_init_pdb0 - initialize PDB0
 *
 * @adev: amdgpu_device pointer
 *
 * This function is only used when GART page table is used
 * for FB address translatioin. In such a case, we construct
 * a 2-level system VM page table: PDB0->PTB, to cover both
 * VRAM of the hive and system memory.
 *
 * PDB0 is static, initialized once on driver initialization.
 * The first n entries of PDB0 are used as PTE by setting
 * P bit to 1, pointing to VRAM. The n+1'th entry points
 * to a big PTB covering system memory.
 *
 */
void amdgpu_gmc_init_pdb0(struct amdgpu_device *adev)
{
	int i;
	uint64_t flags = adev->gart.gart_pte_flags; //TODO it is UC. explore NC/RW?
	/* Each PDE0 (used as PTE) covers (2^vmid0_page_table_block_size)*2M
	 */
	u64 vram_size = adev->gmc.xgmi.node_segment_size * adev->gmc.xgmi.num_physical_nodes;
	u64 pde0_page_size = (1ULL<<adev->gmc.vmid0_page_table_block_size)<<21;
	u64 vram_addr, vram_end;
	u64 gart_ptb_gpu_pa = amdgpu_gmc_vram_pa(adev, adev->gart.bo);
	int idx;

	if (!drm_dev_enter(adev_to_drm(adev), &idx))
		return;

	flags |= AMDGPU_PTE_VALID | AMDGPU_PTE_READABLE;
	flags |= AMDGPU_PTE_WRITEABLE;
	flags |= AMDGPU_PTE_SNOOPED;
	flags |= AMDGPU_PTE_FRAG((adev->gmc.vmid0_page_table_block_size + 9*1));
	flags |= AMDGPU_PDE_PTE_FLAG(adev);

	vram_addr = adev->vm_manager.vram_base_offset;
	if (!amdgpu_virt_xgmi_migrate_enabled(adev))
		vram_addr -= adev->gmc.xgmi.physical_node_id * adev->gmc.xgmi.node_segment_size;
	vram_end = vram_addr + vram_size;

	/* The first n PDE0 entries are used as PTE,
	 * pointing to vram
	 */
	for (i = 0; vram_addr < vram_end; i++, vram_addr += pde0_page_size)
		amdgpu_gmc_set_pte_pde(adev, adev->gmc.ptr_pdb0, i, vram_addr, flags);

	/* The n+1'th PDE0 entry points to a huge
	 * PTB who has more than 512 entries each
	 * pointing to a 4K system page
	 */
	flags = AMDGPU_PTE_VALID;
	flags |= AMDGPU_PTE_SNOOPED | AMDGPU_PDE_BFS_FLAG(adev, 0);
	/* Requires gart_ptb_gpu_pa to be 4K aligned */
	amdgpu_gmc_set_pte_pde(adev, adev->gmc.ptr_pdb0, i, gart_ptb_gpu_pa, flags);
	drm_dev_exit(idx);
}

/**
 * amdgpu_gmc_vram_mc2pa - calculate vram buffer's physical address from MC
 * address
 *
 * @adev: amdgpu_device pointer
 * @mc_addr: MC address of buffer
 */
uint64_t amdgpu_gmc_vram_mc2pa(struct amdgpu_device *adev, uint64_t mc_addr)
{
	return mc_addr - adev->gmc.vram_start + adev->vm_manager.vram_base_offset;
}

/**
 * amdgpu_gmc_vram_pa - calculate vram buffer object's physical address from
 * GPU's view
 *
 * @adev: amdgpu_device pointer
 * @bo: amdgpu buffer object
 */
uint64_t amdgpu_gmc_vram_pa(struct amdgpu_device *adev, struct amdgpu_bo *bo)
{
	return amdgpu_gmc_vram_mc2pa(adev, amdgpu_bo_gpu_offset(bo));
}

int amdgpu_gmc_vram_checking(struct amdgpu_device *adev)
{
	struct amdgpu_bo *vram_bo = NULL;
	uint64_t vram_gpu = 0;
	void *vram_ptr = NULL;

	int ret, size = 0x100000;
	uint8_t cptr[10];

	ret = amdgpu_bo_create_kernel(adev, size, PAGE_SIZE,
				AMDGPU_GEM_DOMAIN_VRAM,
				&vram_bo,
				&vram_gpu,
				&vram_ptr);
	if (ret)
		return ret;

	memset(vram_ptr, 0x86, size);
	memset(cptr, 0x86, 10);

	/**
	 * Check the start, the mid, and the end of the memory if the content of
	 * each byte is the pattern "0x86". If yes, we suppose the vram bo is
	 * workable.
	 *
	 * Note: If check the each byte of whole 1M bo, it will cost too many
	 * seconds, so here, we just pick up three parts for emulation.
	 */
	ret = memcmp(vram_ptr, cptr, 10);
	if (ret) {
		ret = -EIO;
		goto release_buffer;
	}

	ret = memcmp(vram_ptr + (size / 2), cptr, 10);
	if (ret) {
		ret = -EIO;
		goto release_buffer;
	}

	ret = memcmp(vram_ptr + size - 10, cptr, 10);
	if (ret) {
		ret = -EIO;
		goto release_buffer;
	}

release_buffer:
	amdgpu_bo_free_kernel(&vram_bo, &vram_gpu,
			&vram_ptr);

	return ret;
}

static const char *nps_desc[] = {
	[AMDGPU_NPS1_PARTITION_MODE] = "NPS1",
	[AMDGPU_NPS2_PARTITION_MODE] = "NPS2",
	[AMDGPU_NPS3_PARTITION_MODE] = "NPS3",
	[AMDGPU_NPS4_PARTITION_MODE] = "NPS4",
	[AMDGPU_NPS6_PARTITION_MODE] = "NPS6",
	[AMDGPU_NPS8_PARTITION_MODE] = "NPS8",
};

static ssize_t available_memory_partition_show(struct device *dev,
					       struct device_attribute *addr,
					       char *buf)
{
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = drm_to_adev(ddev);
	int size = 0, mode;
	char *sep = "";

	for_each_inst(mode, adev->gmc.supported_nps_modes) {
		size += sysfs_emit_at(buf, size, "%s%s", sep, nps_desc[mode]);
		sep = ", ";
	}
	size += sysfs_emit_at(buf, size, "\n");

	return size;
}

static ssize_t current_memory_partition_store(struct device *dev,
					      struct device_attribute *attr,
					      const char *buf, size_t count)
{
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = drm_to_adev(ddev);
	enum amdgpu_memory_partition mode;
	struct amdgpu_hive_info *hive;
	int i;

	mode = UNKNOWN_MEMORY_PARTITION_MODE;
	for_each_inst(i, adev->gmc.supported_nps_modes) {
		if (!strncasecmp(nps_desc[i], buf, strlen(nps_desc[i]))) {
			mode = i;
			break;
		}
	}

	if (mode == UNKNOWN_MEMORY_PARTITION_MODE)
		return -EINVAL;

	if (mode == adev->gmc.gmc_funcs->query_mem_partition_mode(adev)) {
		dev_info(
			adev->dev,
			"requested NPS mode is same as current NPS mode, skipping\n");
		return count;
	}

	/* If device is part of hive, all devices in the hive should request the
	 * same mode. Hence store the requested mode in hive.
	 */
	hive = amdgpu_get_xgmi_hive(adev);
	if (hive) {
		atomic_set(&hive->requested_nps_mode, mode);
		amdgpu_put_xgmi_hive(hive);
	} else {
		adev->gmc.requested_nps_mode = mode;
	}

	dev_info(
		adev->dev,
		"NPS mode change requested, please remove and reload the driver\n");

	return count;
}

static ssize_t current_memory_partition_show(
	struct device *dev, struct device_attribute *addr, char *buf)
{
	struct drm_device *ddev = dev_get_drvdata(dev);
	struct amdgpu_device *adev = drm_to_adev(ddev);
	enum amdgpu_memory_partition mode;

	/* Only minimal precaution taken to reject requests while in reset */
	if (amdgpu_in_reset(adev))
		return -EPERM;

	mode = adev->gmc.gmc_funcs->query_mem_partition_mode(adev);
	if ((mode >= ARRAY_SIZE(nps_desc)) ||
	    (BIT(mode) & AMDGPU_ALL_NPS_MASK) != BIT(mode))
		return sysfs_emit(buf, "UNKNOWN\n");

	return sysfs_emit(buf, "%s\n", nps_desc[mode]);
}

static DEVICE_ATTR_RW(current_memory_partition);
static DEVICE_ATTR_RO(available_memory_partition);

int amdgpu_gmc_sysfs_init(struct amdgpu_device *adev)
{
	bool nps_switch_support;
	int r = 0;

	if (!adev->gmc.gmc_funcs->query_mem_partition_mode)
		return 0;

	nps_switch_support = (hweight32(adev->gmc.supported_nps_modes &
					AMDGPU_ALL_NPS_MASK) > 1);
	if (!nps_switch_support)
		dev_attr_current_memory_partition.attr.mode &=
			~(S_IWUSR | S_IWGRP | S_IWOTH);
	else
		r = device_create_file(adev->dev,
				       &dev_attr_available_memory_partition);

	if (r)
		return r;

	return device_create_file(adev->dev,
				  &dev_attr_current_memory_partition);
}

void amdgpu_gmc_sysfs_fini(struct amdgpu_device *adev)
{
	if (!adev->gmc.gmc_funcs->query_mem_partition_mode)
		return;

	device_remove_file(adev->dev, &dev_attr_current_memory_partition);
	device_remove_file(adev->dev, &dev_attr_available_memory_partition);
}

int amdgpu_gmc_get_nps_memranges(struct amdgpu_device *adev,
				 struct amdgpu_mem_partition_info *mem_ranges,
				 uint8_t *exp_ranges)
{
	struct amdgpu_gmc_memrange ranges[AMDGPU_MAX_MEM_RANGES];
	int range_cnt, ret, i, j;
	uint32_t nps_type;
	bool refresh;

	if (!mem_ranges || !exp_ranges)
		return -EINVAL;
	range_cnt = AMDGPU_MAX_MEM_RANGES;
	refresh = (adev->init_lvl->level != AMDGPU_INIT_LEVEL_MINIMAL_XGMI) &&
		  (adev->gmc.reset_flags & AMDGPU_GMC_INIT_RESET_NPS);
	ret = amdgpu_discovery_get_nps_info(adev, &nps_type, ranges, &range_cnt,
					    refresh);

	if (ret)
		return ret;

	/* TODO: For now, expect ranges and partition count to be the same.
	 * Adjust if there are holes expected in any NPS domain.
	 */
	if (*exp_ranges && (range_cnt != *exp_ranges)) {
		dev_warn(
			adev->dev,
			"NPS config mismatch - expected ranges: %d discovery - nps mode: %d, nps ranges: %d",
			*exp_ranges, nps_type, range_cnt);
		ret = -EINVAL;
		goto err;
	}

	for (i = 0; i < range_cnt; ++i) {
		if (ranges[i].base_address >= ranges[i].limit_address) {
			dev_warn(
				adev->dev,
				"Invalid NPS range - nps mode: %d, range[%d]: base: %llx limit: %llx",
				nps_type, i, ranges[i].base_address,
				ranges[i].limit_address);
			ret = -EINVAL;
			goto err;
		}

		/* Check for overlaps, not expecting any now */
		for (j = i - 1; j >= 0; j--) {
			if (max(ranges[j].base_address,
				ranges[i].base_address) <=
			    min(ranges[j].limit_address,
				ranges[i].limit_address)) {
				dev_warn(
					adev->dev,
					"overlapping ranges detected [ %llx - %llx ] | [%llx - %llx]",
					ranges[j].base_address,
					ranges[j].limit_address,
					ranges[i].base_address,
					ranges[i].limit_address);
				ret = -EINVAL;
				goto err;
			}
		}

		mem_ranges[i].range.fpfn =
			(ranges[i].base_address -
			 adev->vm_manager.vram_base_offset) >>
			AMDGPU_GPU_PAGE_SHIFT;
		mem_ranges[i].range.lpfn =
			(ranges[i].limit_address -
			 adev->vm_manager.vram_base_offset) >>
			AMDGPU_GPU_PAGE_SHIFT;
		mem_ranges[i].size =
			ranges[i].limit_address - ranges[i].base_address + 1;
	}

	if (!*exp_ranges)
		*exp_ranges = range_cnt;
err:
	return ret;
}

int amdgpu_gmc_request_memory_partition(struct amdgpu_device *adev,
					int nps_mode)
{
	/* Not supported on VF devices and APUs */
	if (amdgpu_sriov_vf(adev) || (adev->flags & AMD_IS_APU))
		return -EOPNOTSUPP;

	if (!adev->psp.funcs) {
		dev_err(adev->dev,
			"PSP interface not available for nps mode change request");
		return -EINVAL;
	}

	return psp_memory_partition(&adev->psp, nps_mode);
}

static inline bool amdgpu_gmc_need_nps_switch_req(struct amdgpu_device *adev,
						  int req_nps_mode,
						  int cur_nps_mode)
{
	return (((BIT(req_nps_mode) & adev->gmc.supported_nps_modes) ==
			BIT(req_nps_mode)) &&
		req_nps_mode != cur_nps_mode);
}

void amdgpu_gmc_prepare_nps_mode_change(struct amdgpu_device *adev)
{
	int req_nps_mode, cur_nps_mode, r;
	struct amdgpu_hive_info *hive;

	if (amdgpu_sriov_vf(adev) || !adev->gmc.supported_nps_modes ||
	    !adev->gmc.gmc_funcs->request_mem_partition_mode)
		return;

	cur_nps_mode = adev->gmc.gmc_funcs->query_mem_partition_mode(adev);
	hive = amdgpu_get_xgmi_hive(adev);
	if (hive) {
		req_nps_mode = atomic_read(&hive->requested_nps_mode);
		if (!amdgpu_gmc_need_nps_switch_req(adev, req_nps_mode,
						    cur_nps_mode)) {
			amdgpu_put_xgmi_hive(hive);
			return;
		}
		r = amdgpu_xgmi_request_nps_change(adev, hive, req_nps_mode);
		amdgpu_put_xgmi_hive(hive);
		goto out;
	}

	req_nps_mode = adev->gmc.requested_nps_mode;
	if (!amdgpu_gmc_need_nps_switch_req(adev, req_nps_mode, cur_nps_mode))
		return;

	/* even if this fails, we should let driver unload w/o blocking */
	r = adev->gmc.gmc_funcs->request_mem_partition_mode(adev, req_nps_mode);
out:
	if (r)
		dev_err(adev->dev, "NPS mode change request failed\n");
	else
		dev_info(
			adev->dev,
			"NPS mode change request done, reload driver to complete the change\n");
}

bool amdgpu_gmc_need_reset_on_init(struct amdgpu_device *adev)
{
	if (adev->gmc.gmc_funcs->need_reset_on_init)
		return adev->gmc.gmc_funcs->need_reset_on_init(adev);

	return false;
}

enum amdgpu_memory_partition
amdgpu_gmc_get_vf_memory_partition(struct amdgpu_device *adev)
{
	switch (adev->gmc.num_mem_partitions) {
	case 0:
		return UNKNOWN_MEMORY_PARTITION_MODE;
	case 1:
		return AMDGPU_NPS1_PARTITION_MODE;
	case 2:
		return AMDGPU_NPS2_PARTITION_MODE;
	case 4:
		return AMDGPU_NPS4_PARTITION_MODE;
	case 8:
		return AMDGPU_NPS8_PARTITION_MODE;
	default:
		return AMDGPU_NPS1_PARTITION_MODE;
	}
}

enum amdgpu_memory_partition
amdgpu_gmc_get_memory_partition(struct amdgpu_device *adev, u32 *supp_modes)
{
	enum amdgpu_memory_partition mode = UNKNOWN_MEMORY_PARTITION_MODE;

	if (adev->nbio.funcs &&
	    adev->nbio.funcs->get_memory_partition_mode)
		mode = adev->nbio.funcs->get_memory_partition_mode(adev,
								   supp_modes);
	else
		dev_warn(adev->dev, "memory partition mode query is not supported\n");

	return mode;
}

enum amdgpu_memory_partition
amdgpu_gmc_query_memory_partition(struct amdgpu_device *adev)
{
	if (amdgpu_sriov_vf(adev))
		return amdgpu_gmc_get_vf_memory_partition(adev);
	else
		return amdgpu_gmc_get_memory_partition(adev, NULL);
}

static bool amdgpu_gmc_validate_partition_info(struct amdgpu_device *adev)
{
	enum amdgpu_memory_partition mode;
	u32 supp_modes;
	bool valid;

	mode = amdgpu_gmc_get_memory_partition(adev, &supp_modes);

	/* Mode detected by hardware not present in supported modes */
	if ((mode != UNKNOWN_MEMORY_PARTITION_MODE) &&
	    !(BIT(mode - 1) & supp_modes))
		return false;

	switch (mode) {
	case UNKNOWN_MEMORY_PARTITION_MODE:
	case AMDGPU_NPS1_PARTITION_MODE:
		valid = (adev->gmc.num_mem_partitions == 1);
		break;
	case AMDGPU_NPS2_PARTITION_MODE:
		valid = (adev->gmc.num_mem_partitions == 2);
		break;
	case AMDGPU_NPS4_PARTITION_MODE:
		valid = (adev->gmc.num_mem_partitions == 3 ||
			 adev->gmc.num_mem_partitions == 4);
		break;
	case AMDGPU_NPS8_PARTITION_MODE:
		valid = (adev->gmc.num_mem_partitions == 8);
		break;
	default:
		valid = false;
	}

	return valid;
}

static bool amdgpu_gmc_is_node_present(int *node_ids, int num_ids, int nid)
{
	int i;

	/* Check if node with id 'nid' is present in 'node_ids' array */
	for (i = 0; i < num_ids; ++i)
		if (node_ids[i] == nid)
			return true;

	return false;
}

static void
amdgpu_gmc_init_acpi_mem_ranges(struct amdgpu_device *adev,
				struct amdgpu_mem_partition_info *mem_ranges)
{
	struct amdgpu_numa_info numa_info;
	int node_ids[AMDGPU_MAX_MEM_RANGES];
	int num_ranges = 0, ret;
	int num_xcc, xcc_id;
	uint32_t xcc_mask;

	num_xcc = NUM_XCC(adev->gfx.xcc_mask);
	xcc_mask = (1U << num_xcc) - 1;

	for_each_inst(xcc_id, xcc_mask)	{
		ret = amdgpu_acpi_get_mem_info(adev, xcc_id, &numa_info);
		if (ret)
			continue;

		if (numa_info.nid == NUMA_NO_NODE) {
			mem_ranges[0].size = numa_info.size;
			mem_ranges[0].numa.node = numa_info.nid;
			num_ranges = 1;
			break;
		}

		if (amdgpu_gmc_is_node_present(node_ids, num_ranges,
					     numa_info.nid))
			continue;

		node_ids[num_ranges] = numa_info.nid;
		mem_ranges[num_ranges].numa.node = numa_info.nid;
		mem_ranges[num_ranges].size = numa_info.size;
		++num_ranges;
	}

	adev->gmc.num_mem_partitions = num_ranges;
}

void amdgpu_gmc_init_sw_mem_ranges(struct amdgpu_device *adev,
				   struct amdgpu_mem_partition_info *mem_ranges)
{
	enum amdgpu_memory_partition mode;
	u32 start_addr = 0, size;
	int i, r, l;

	mode = amdgpu_gmc_query_memory_partition(adev);

	switch (mode) {
	case UNKNOWN_MEMORY_PARTITION_MODE:
		adev->gmc.num_mem_partitions = 0;
		break;
	case AMDGPU_NPS1_PARTITION_MODE:
		adev->gmc.num_mem_partitions = 1;
		break;
	case AMDGPU_NPS2_PARTITION_MODE:
		adev->gmc.num_mem_partitions = 2;
		break;
	case AMDGPU_NPS4_PARTITION_MODE:
		if (adev->flags & AMD_IS_APU)
			adev->gmc.num_mem_partitions = 3;
		else
			adev->gmc.num_mem_partitions = 4;
		break;
	case AMDGPU_NPS8_PARTITION_MODE:
		adev->gmc.num_mem_partitions = 8;
		break;
	default:
		adev->gmc.num_mem_partitions = 1;
		break;
	}

	/* Use NPS range info, if populated */
	r = amdgpu_gmc_get_nps_memranges(adev, mem_ranges,
					 &adev->gmc.num_mem_partitions);
	if (!r) {
		l = 0;
		for (i = 1; i < adev->gmc.num_mem_partitions; ++i) {
			if (mem_ranges[i].range.lpfn >
			    mem_ranges[i - 1].range.lpfn)
				l = i;
		}

	} else {
		if (!adev->gmc.num_mem_partitions) {
			dev_warn(adev->dev,
				 "Not able to detect NPS mode, fall back to NPS1\n");
			adev->gmc.num_mem_partitions = 1;
		}
		/* Fallback to sw based calculation */
		size = (adev->gmc.real_vram_size + SZ_16M) >> AMDGPU_GPU_PAGE_SHIFT;
		size /= adev->gmc.num_mem_partitions;

		for (i = 0; i < adev->gmc.num_mem_partitions; ++i) {
			mem_ranges[i].range.fpfn = start_addr;
			mem_ranges[i].size =
				((u64)size << AMDGPU_GPU_PAGE_SHIFT);
			mem_ranges[i].range.lpfn = start_addr + size - 1;
			start_addr += size;
		}

		l = adev->gmc.num_mem_partitions - 1;
	}

	/* Adjust the last one */
	mem_ranges[l].range.lpfn =
		(adev->gmc.real_vram_size >> AMDGPU_GPU_PAGE_SHIFT) - 1;
	mem_ranges[l].size =
		adev->gmc.real_vram_size -
		((u64)mem_ranges[l].range.fpfn << AMDGPU_GPU_PAGE_SHIFT);
}

int amdgpu_gmc_init_mem_ranges(struct amdgpu_device *adev)
{
	bool valid;

	adev->gmc.mem_partitions = kzalloc_objs(struct amdgpu_mem_partition_info,
						AMDGPU_MAX_MEM_RANGES);
	if (!adev->gmc.mem_partitions)
		return -ENOMEM;

	if (adev->gmc.is_app_apu)
		amdgpu_gmc_init_acpi_mem_ranges(adev, adev->gmc.mem_partitions);
	else
		amdgpu_gmc_init_sw_mem_ranges(adev, adev->gmc.mem_partitions);

	if (amdgpu_sriov_vf(adev))
		valid = true;
	else
		valid = amdgpu_gmc_validate_partition_info(adev);
	if (!valid)
		dev_warn(adev->dev,
			 "Mem ranges not matching with hardware config\n");

	if (!adev->gmc.num_mem_partitions) {
		dev_err(adev->dev, "num_mem_partitions is zero\n");
		kfree(adev->gmc.mem_partitions);
		adev->gmc.mem_partitions = NULL;
		return -EINVAL;
	}

	return 0;
}

int amdgpu_gmc_get_vram_info(struct amdgpu_device *adev,
		int *vram_width, int *vram_type, int *vram_vendor)
{
	int ret = 0;

	if (adev->flags & AMD_IS_APU)
		return amdgpu_atomfirmware_get_integrated_system_info(adev,
							vram_width, vram_type, vram_vendor);
	switch (amdgpu_ip_version(adev, GC_HWIP, 0)) {
	case IP_VERSION(12, 0, 0):
	case IP_VERSION(12, 0, 1):
		return amdgpu_atomfirmware_get_umc_info(adev,
								vram_width, vram_type, vram_vendor);
	case IP_VERSION(9, 5, 0):
	case IP_VERSION(9, 4, 4):
	case IP_VERSION(9, 4, 3):
		ret = amdgpu_atomfirmware_get_umc_info(adev,
								vram_width, vram_type, vram_vendor);
		if (vram_width && !ret)
			*vram_width *= hweight32(adev->aid_mask);
		return ret;
	default:
		return amdgpu_atomfirmware_get_vram_info(adev,
								vram_width, vram_type, vram_vendor);
	}
	return 0;
}
