// SPDX-License-Identifier: MIT
/*
 * Copyright © 2019 Intel Corporation
 */

#include "i915_drv.h"
#include "i915_pci.h"
#include "i915_reg.h"
#include "intel_memory_region.h"
#include "intel_pci_config.h"
#include "intel_region_lmem.h"
#include "intel_region_ttm.h"
#include "gem/i915_gem_lmem.h"
#include "gem/i915_gem_region.h"
#include "gem/i915_gem_ttm.h"
#include "gt/intel_gt.h"
#include "gt/intel_gt_mcr.h"
#include "gt/intel_gt_regs.h"

#ifdef CONFIG_64BIT
static void _release_bars(struct pci_dev *pdev)
{
	int resno;

	for (resno = PCI_STD_RESOURCES; resno < PCI_STD_RESOURCE_END; resno++) {
		if (pci_resource_len(pdev, resno))
			pci_release_resource(pdev, resno);
	}
}

static void
_resize_bar(struct drm_i915_private *i915, int resno, resource_size_t size)
{
	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
	int bar_size = pci_rebar_bytes_to_size(size);
	int ret;

	_release_bars(pdev);

	ret = pci_resize_resource(pdev, resno, bar_size);
	if (ret) {
		drm_info(&i915->drm, "Failed to resize BAR%d to %dM (%pe)\n",
			 resno, 1 << bar_size, ERR_PTR(ret));
		return;
	}

	drm_info(&i915->drm, "BAR%d resized to %dM\n", resno, 1 << bar_size);
}

static void i915_resize_lmem_bar(struct drm_i915_private *i915, resource_size_t lmem_size)
{
	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
	struct pci_bus *root = pdev->bus;
	struct resource *root_res;
	resource_size_t rebar_size;
	resource_size_t current_size;
	intel_wakeref_t wakeref;
	u32 pci_cmd;
	int i;

	current_size = roundup_pow_of_two(pci_resource_len(pdev, GEN12_LMEM_BAR));

	if (i915->params.lmem_bar_size) {
		u32 bar_sizes;

		rebar_size = i915->params.lmem_bar_size *
			(resource_size_t)SZ_1M;
		bar_sizes = pci_rebar_get_possible_sizes(pdev, GEN12_LMEM_BAR);

		if (rebar_size == current_size)
			return;

		if (!(bar_sizes & BIT(pci_rebar_bytes_to_size(rebar_size))) ||
		    rebar_size >= roundup_pow_of_two(lmem_size)) {
			rebar_size = lmem_size;

			drm_info(&i915->drm,
				 "Given bar size is not within supported size, setting it to default: %llu\n",
				 (u64)lmem_size >> 20);
		}
	} else {
		rebar_size = current_size;

		if (rebar_size != roundup_pow_of_two(lmem_size))
			rebar_size = lmem_size;
		else
			return;
	}

	/* Find out if root bus contains 64bit memory addressing */
	while (root->parent)
		root = root->parent;

	pci_bus_for_each_resource(root, root_res, i) {
		if (root_res && root_res->flags & (IORESOURCE_MEM | IORESOURCE_MEM_64) &&
		    root_res->start > 0x100000000ull)
			break;
	}

	/* pci_resize_resource will fail anyways */
	if (!root_res) {
		drm_info(&i915->drm, "Can't resize LMEM BAR - platform support is missing\n");
		return;
	}

	/*
	 * Releasing forcewake during BAR resizing results in later forcewake
	 * ack timeouts and former can happen any time - it is asynchronous.
	 * Grabbing all forcewakes prevents it.
	 */
	with_intel_runtime_pm(i915->uncore.rpm, wakeref) {
		intel_uncore_forcewake_get(&i915->uncore, FORCEWAKE_ALL);

		/* First disable PCI memory decoding references */
		pci_read_config_dword(pdev, PCI_COMMAND, &pci_cmd);
		pci_write_config_dword(pdev, PCI_COMMAND,
				       pci_cmd & ~PCI_COMMAND_MEMORY);

		_resize_bar(i915, GEN12_LMEM_BAR, rebar_size);

		pci_assign_unassigned_bus_resources(pdev->bus);
		pci_write_config_dword(pdev, PCI_COMMAND, pci_cmd);
		intel_uncore_forcewake_put(&i915->uncore, FORCEWAKE_ALL);
	}
}
#else
static void i915_resize_lmem_bar(struct drm_i915_private *i915, resource_size_t lmem_size) {}
#endif

static int
region_lmem_release(struct intel_memory_region *mem)
{
	int ret;

	ret = intel_region_ttm_fini(mem);
	io_mapping_fini(&mem->iomap);

	return ret;
}

static int
region_lmem_init(struct intel_memory_region *mem)
{
	int ret;

	if (!io_mapping_init_wc(&mem->iomap,
				mem->io.start,
				resource_size(&mem->io)))
		return -EIO;

	ret = intel_region_ttm_init(mem);
	if (ret)
		goto out_no_buddy;

	return 0;

out_no_buddy:
	io_mapping_fini(&mem->iomap);

	return ret;
}

static const struct intel_memory_region_ops intel_region_lmem_ops = {
	.init = region_lmem_init,
	.release = region_lmem_release,
	.init_object = __i915_gem_ttm_object_init,
};

static bool get_legacy_lowmem_region(struct intel_uncore *uncore,
				     u64 *start, u32 *size)
{
	if (!IS_DG1(uncore->i915))
		return false;

	*start = 0;
	*size = SZ_1M;

	drm_dbg(&uncore->i915->drm, "LMEM: reserved legacy low-memory [0x%llx-0x%llx]\n",
		*start, *start + *size);

	return true;
}

static int reserve_lowmem_region(struct intel_uncore *uncore,
				 struct intel_memory_region *mem)
{
	u64 reserve_start;
	u32 reserve_size;
	int ret;

	if (!get_legacy_lowmem_region(uncore, &reserve_start, &reserve_size))
		return 0;

	ret = intel_memory_region_reserve(mem, reserve_start, reserve_size);
	if (ret)
		drm_err(&uncore->i915->drm, "LMEM: reserving low memory region failed\n");

	return ret;
}

static struct intel_memory_region *setup_lmem(struct intel_gt *gt)
{
	struct drm_i915_private *i915 = gt->i915;
	struct intel_uncore *uncore = gt->uncore;
	struct pci_dev *pdev = to_pci_dev(i915->drm.dev);
	struct intel_memory_region *mem;
	resource_size_t min_page_size;
	resource_size_t io_start;
	resource_size_t io_size;
	resource_size_t lmem_size;
	int err;

	if (!IS_DGFX(i915))
		return ERR_PTR(-ENODEV);

	if (!i915_pci_resource_valid(pdev, GEN12_LMEM_BAR))
		return ERR_PTR(-ENXIO);

	if (HAS_FLAT_CCS(i915)) {
		resource_size_t lmem_range;
		u64 tile_stolen, flat_ccs_base;

		lmem_range = intel_gt_mcr_read_any(to_gt(i915), XEHP_TILE0_ADDR_RANGE) & 0xFFFF;
		lmem_size = lmem_range >> XEHP_TILE_LMEM_RANGE_SHIFT;
		lmem_size *= SZ_1G;

		flat_ccs_base = intel_gt_mcr_read_any(gt, XEHP_FLAT_CCS_BASE_ADDR);
		flat_ccs_base = (flat_ccs_base >> XEHP_CCS_BASE_SHIFT) * SZ_64K;

		if (GEM_WARN_ON(lmem_size < flat_ccs_base))
			return ERR_PTR(-EIO);

		tile_stolen = lmem_size - flat_ccs_base;

		/* If the FLAT_CCS_BASE_ADDR register is not populated, flag an error */
		if (tile_stolen == lmem_size)
			drm_err(&i915->drm,
				"CCS_BASE_ADDR register did not have expected value\n");

		lmem_size -= tile_stolen;
	} else {
		/* Stolen starts from GSMBASE without CCS */
		lmem_size = intel_uncore_read64(&i915->uncore, GEN6_GSMBASE);
	}

	i915_resize_lmem_bar(i915, lmem_size);

	if (i915->params.lmem_size > 0) {
		lmem_size = min_t(resource_size_t, lmem_size,
				  mul_u32_u32(i915->params.lmem_size, SZ_1M));
	}

	io_start = pci_resource_start(pdev, GEN12_LMEM_BAR);
	io_size = min(pci_resource_len(pdev, GEN12_LMEM_BAR), lmem_size);
	if (!io_size)
		return ERR_PTR(-EIO);

	min_page_size = HAS_64K_PAGES(i915) ? I915_GTT_PAGE_SIZE_64K :
						I915_GTT_PAGE_SIZE_4K;
	mem = intel_memory_region_create(i915,
					 0,
					 lmem_size,
					 min_page_size,
					 io_start,
					 io_size,
					 INTEL_MEMORY_LOCAL,
					 0,
					 &intel_region_lmem_ops);
	if (IS_ERR(mem))
		return mem;

	err = reserve_lowmem_region(uncore, mem);
	if (err)
		goto err_region_put;

	if (io_size < lmem_size)
		drm_info(&i915->drm, "Using a reduced BAR size of %lluMiB. Consider enabling 'Resizable BAR' or similar, if available in the BIOS.\n",
			 (u64)io_size >> 20);

	return mem;

err_region_put:
	intel_memory_region_destroy(mem);
	return ERR_PTR(err);
}

struct intel_memory_region *intel_gt_setup_lmem(struct intel_gt *gt)
{
	return setup_lmem(gt);
}
