// SPDX-License-Identifier: GPL-2.0-only
/* Copyright(c) 2020 Intel Corporation. */
#include <linux/io-64-nonatomic-lo-hi.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/pci.h>
#include <cxlmem.h>
#include <cxlpci.h>
#include <pmu.h>

#include "core.h"

/**
 * DOC: cxl registers
 *
 * CXL device capabilities are enumerated by PCI DVSEC (Designated
 * Vendor-specific) and / or descriptors provided by platform firmware.
 * They can be defined as a set like the device and component registers
 * mandated by CXL Section 8.1.12.2 Memory Device PCIe Capabilities and
 * Extended Capabilities, or they can be individual capabilities
 * appended to bridged and endpoint devices.
 *
 * Provide common infrastructure for enumerating and mapping these
 * discrete capabilities.
 */

/**
 * cxl_probe_component_regs() - Detect CXL Component register blocks
 * @dev: Host device of the @base mapping
 * @base: Mapping containing the HDM Decoder Capability Header
 * @map: Map object describing the register block information found
 *
 * See CXL 2.0 8.2.4 Component Register Layout and Definition
 * See CXL 2.0 8.2.5.5 CXL Device Register Interface
 *
 * Probe for component register information and return it in map object.
 */
void cxl_probe_component_regs(struct device *dev, void __iomem *base,
			      struct cxl_component_reg_map *map)
{
	int cap, cap_count;
	u32 cap_array;

	*map = (struct cxl_component_reg_map) { 0 };

	/*
	 * CXL.cache and CXL.mem registers are at offset 0x1000 as defined in
	 * CXL 2.0 8.2.4 Table 141.
	 */
	base += CXL_CM_OFFSET;

	cap_array = readl(base + CXL_CM_CAP_HDR_OFFSET);

	if (FIELD_GET(CXL_CM_CAP_HDR_ID_MASK, cap_array) != CM_CAP_HDR_CAP_ID) {
		dev_err(dev,
			"Couldn't locate the CXL.cache and CXL.mem capability array header.\n");
		return;
	}

	/* It's assumed that future versions will be backward compatible */
	cap_count = FIELD_GET(CXL_CM_CAP_HDR_ARRAY_SIZE_MASK, cap_array);

	for (cap = 1; cap <= cap_count; cap++) {
		void __iomem *register_block;
		struct cxl_reg_map *rmap;
		u16 cap_id, offset;
		u32 length, hdr;

		hdr = readl(base + cap * 0x4);

		cap_id = FIELD_GET(CXL_CM_CAP_HDR_ID_MASK, hdr);
		offset = FIELD_GET(CXL_CM_CAP_PTR_MASK, hdr);
		register_block = base + offset;
		hdr = readl(register_block);

		rmap = NULL;
		switch (cap_id) {
		case CXL_CM_CAP_CAP_ID_HDM: {
			int decoder_cnt;

			dev_dbg(dev, "found HDM decoder capability (0x%x)\n",
				offset);

			decoder_cnt = cxl_hdm_decoder_count(hdr);
			length = 0x20 * decoder_cnt + 0x10;
			rmap = &map->hdm_decoder;
			break;
		}
		case CXL_CM_CAP_CAP_ID_RAS:
			dev_dbg(dev, "found RAS capability (0x%x)\n",
				offset);
			length = CXL_RAS_CAPABILITY_LENGTH;
			rmap = &map->ras;
			break;
		default:
			dev_dbg(dev, "Unknown CM cap ID: %d (0x%x)\n", cap_id,
				offset);
			break;
		}

		if (!rmap)
			continue;
		rmap->valid = true;
		rmap->id = cap_id;
		rmap->offset = CXL_CM_OFFSET + offset;
		rmap->size = length;
	}
}
EXPORT_SYMBOL_NS_GPL(cxl_probe_component_regs, CXL);

/**
 * cxl_probe_device_regs() - Detect CXL Device register blocks
 * @dev: Host device of the @base mapping
 * @base: Mapping of CXL 2.0 8.2.8 CXL Device Register Interface
 * @map: Map object describing the register block information found
 *
 * Probe for device register information and return it in map object.
 */
void cxl_probe_device_regs(struct device *dev, void __iomem *base,
			   struct cxl_device_reg_map *map)
{
	int cap, cap_count;
	u64 cap_array;

	*map = (struct cxl_device_reg_map){ 0 };

	cap_array = readq(base + CXLDEV_CAP_ARRAY_OFFSET);
	if (FIELD_GET(CXLDEV_CAP_ARRAY_ID_MASK, cap_array) !=
	    CXLDEV_CAP_ARRAY_CAP_ID)
		return;

	cap_count = FIELD_GET(CXLDEV_CAP_ARRAY_COUNT_MASK, cap_array);

	for (cap = 1; cap <= cap_count; cap++) {
		struct cxl_reg_map *rmap;
		u32 offset, length;
		u16 cap_id;

		cap_id = FIELD_GET(CXLDEV_CAP_HDR_CAP_ID_MASK,
				   readl(base + cap * 0x10));
		offset = readl(base + cap * 0x10 + 0x4);
		length = readl(base + cap * 0x10 + 0x8);

		rmap = NULL;
		switch (cap_id) {
		case CXLDEV_CAP_CAP_ID_DEVICE_STATUS:
			dev_dbg(dev, "found Status capability (0x%x)\n", offset);
			rmap = &map->status;
			break;
		case CXLDEV_CAP_CAP_ID_PRIMARY_MAILBOX:
			dev_dbg(dev, "found Mailbox capability (0x%x)\n", offset);
			rmap = &map->mbox;
			break;
		case CXLDEV_CAP_CAP_ID_SECONDARY_MAILBOX:
			dev_dbg(dev, "found Secondary Mailbox capability (0x%x)\n", offset);
			break;
		case CXLDEV_CAP_CAP_ID_MEMDEV:
			dev_dbg(dev, "found Memory Device capability (0x%x)\n", offset);
			rmap = &map->memdev;
			break;
		default:
			if (cap_id >= 0x8000)
				dev_dbg(dev, "Vendor cap ID: %#x offset: %#x\n", cap_id, offset);
			else
				dev_dbg(dev, "Unknown cap ID: %#x offset: %#x\n", cap_id, offset);
			break;
		}

		if (!rmap)
			continue;
		rmap->valid = true;
		rmap->id = cap_id;
		rmap->offset = offset;
		rmap->size = length;
	}
}
EXPORT_SYMBOL_NS_GPL(cxl_probe_device_regs, CXL);

void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr,
				   resource_size_t length)
{
	void __iomem *ret_val;
	struct resource *res;

	if (WARN_ON_ONCE(addr == CXL_RESOURCE_NONE))
		return NULL;

	res = devm_request_mem_region(dev, addr, length, dev_name(dev));
	if (!res) {
		resource_size_t end = addr + length - 1;

		dev_err(dev, "Failed to request region %pa-%pa\n", &addr, &end);
		return NULL;
	}

	ret_val = devm_ioremap(dev, addr, length);
	if (!ret_val)
		dev_err(dev, "Failed to map region %pr\n", res);

	return ret_val;
}

int cxl_map_component_regs(const struct cxl_register_map *map,
			   struct cxl_component_regs *regs,
			   unsigned long map_mask)
{
	struct device *host = map->host;
	struct mapinfo {
		const struct cxl_reg_map *rmap;
		void __iomem **addr;
	} mapinfo[] = {
		{ &map->component_map.hdm_decoder, &regs->hdm_decoder },
		{ &map->component_map.ras, &regs->ras },
	};
	int i;

	for (i = 0; i < ARRAY_SIZE(mapinfo); i++) {
		struct mapinfo *mi = &mapinfo[i];
		resource_size_t addr;
		resource_size_t length;

		if (!mi->rmap->valid)
			continue;
		if (!test_bit(mi->rmap->id, &map_mask))
			continue;
		addr = map->resource + mi->rmap->offset;
		length = mi->rmap->size;
		*(mi->addr) = devm_cxl_iomap_block(host, addr, length);
		if (!*(mi->addr))
			return -ENOMEM;
	}

	return 0;
}
EXPORT_SYMBOL_NS_GPL(cxl_map_component_regs, CXL);

int cxl_map_device_regs(const struct cxl_register_map *map,
			struct cxl_device_regs *regs)
{
	struct device *host = map->host;
	resource_size_t phys_addr = map->resource;
	struct mapinfo {
		const struct cxl_reg_map *rmap;
		void __iomem **addr;
	} mapinfo[] = {
		{ &map->device_map.status, &regs->status, },
		{ &map->device_map.mbox, &regs->mbox, },
		{ &map->device_map.memdev, &regs->memdev, },
	};
	int i;

	for (i = 0; i < ARRAY_SIZE(mapinfo); i++) {
		struct mapinfo *mi = &mapinfo[i];
		resource_size_t length;
		resource_size_t addr;

		if (!mi->rmap->valid)
			continue;

		addr = phys_addr + mi->rmap->offset;
		length = mi->rmap->size;
		*(mi->addr) = devm_cxl_iomap_block(host, addr, length);
		if (!*(mi->addr))
			return -ENOMEM;
	}

	return 0;
}
EXPORT_SYMBOL_NS_GPL(cxl_map_device_regs, CXL);

static bool cxl_decode_regblock(struct pci_dev *pdev, u32 reg_lo, u32 reg_hi,
				struct cxl_register_map *map)
{
	u8 reg_type = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BLOCK_ID_MASK, reg_lo);
	int bar = FIELD_GET(CXL_DVSEC_REG_LOCATOR_BIR_MASK, reg_lo);
	u64 offset = ((u64)reg_hi << 32) |
		     (reg_lo & CXL_DVSEC_REG_LOCATOR_BLOCK_OFF_LOW_MASK);

	if (offset > pci_resource_len(pdev, bar)) {
		dev_warn(&pdev->dev,
			 "BAR%d: %pr: too small (offset: %pa, type: %d)\n", bar,
			 &pdev->resource[bar], &offset, reg_type);
		return false;
	}

	map->reg_type = reg_type;
	map->resource = pci_resource_start(pdev, bar) + offset;
	map->max_size = pci_resource_len(pdev, bar) - offset;
	return true;
}

/**
 * cxl_find_regblock_instance() - Locate a register block by type / index
 * @pdev: The CXL PCI device to enumerate.
 * @type: Register Block Indicator id
 * @map: Enumeration output, clobbered on error
 * @index: Index into which particular instance of a regblock wanted in the
 *	   order found in register locator DVSEC.
 *
 * Return: 0 if register block enumerated, negative error code otherwise
 *
 * A CXL DVSEC may point to one or more register blocks, search for them
 * by @type and @index.
 */
int cxl_find_regblock_instance(struct pci_dev *pdev, enum cxl_regloc_type type,
			       struct cxl_register_map *map, int index)
{
	u32 regloc_size, regblocks;
	int instance = 0;
	int regloc, i;

	*map = (struct cxl_register_map) {
		.host = &pdev->dev,
		.resource = CXL_RESOURCE_NONE,
	};

	regloc = pci_find_dvsec_capability(pdev, PCI_VENDOR_ID_CXL,
					   CXL_DVSEC_REG_LOCATOR);
	if (!regloc)
		return -ENXIO;

	pci_read_config_dword(pdev, regloc + PCI_DVSEC_HEADER1, &regloc_size);
	regloc_size = FIELD_GET(PCI_DVSEC_HEADER1_LENGTH_MASK, regloc_size);

	regloc += CXL_DVSEC_REG_LOCATOR_BLOCK1_OFFSET;
	regblocks = (regloc_size - CXL_DVSEC_REG_LOCATOR_BLOCK1_OFFSET) / 8;

	for (i = 0; i < regblocks; i++, regloc += 8) {
		u32 reg_lo, reg_hi;

		pci_read_config_dword(pdev, regloc, &reg_lo);
		pci_read_config_dword(pdev, regloc + 4, &reg_hi);

		if (!cxl_decode_regblock(pdev, reg_lo, reg_hi, map))
			continue;

		if (map->reg_type == type) {
			if (index == instance)
				return 0;
			instance++;
		}
	}

	map->resource = CXL_RESOURCE_NONE;
	return -ENODEV;
}
EXPORT_SYMBOL_NS_GPL(cxl_find_regblock_instance, CXL);

/**
 * cxl_find_regblock() - Locate register blocks by type
 * @pdev: The CXL PCI device to enumerate.
 * @type: Register Block Indicator id
 * @map: Enumeration output, clobbered on error
 *
 * Return: 0 if register block enumerated, negative error code otherwise
 *
 * A CXL DVSEC may point to one or more register blocks, search for them
 * by @type.
 */
int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
		      struct cxl_register_map *map)
{
	return cxl_find_regblock_instance(pdev, type, map, 0);
}
EXPORT_SYMBOL_NS_GPL(cxl_find_regblock, CXL);

/**
 * cxl_count_regblock() - Count instances of a given regblock type.
 * @pdev: The CXL PCI device to enumerate.
 * @type: Register Block Indicator id
 *
 * Some regblocks may be repeated. Count how many instances.
 *
 * Return: count of matching regblocks.
 */
int cxl_count_regblock(struct pci_dev *pdev, enum cxl_regloc_type type)
{
	struct cxl_register_map map;
	int rc, count = 0;

	while (1) {
		rc = cxl_find_regblock_instance(pdev, type, &map, count);
		if (rc)
			return count;
		count++;
	}
}
EXPORT_SYMBOL_NS_GPL(cxl_count_regblock, CXL);

int cxl_map_pmu_regs(struct cxl_register_map *map, struct cxl_pmu_regs *regs)
{
	struct device *dev = map->host;
	resource_size_t phys_addr;

	phys_addr = map->resource;
	regs->pmu = devm_cxl_iomap_block(dev, phys_addr, CXL_PMU_REGMAP_SIZE);
	if (!regs->pmu)
		return -ENOMEM;

	return 0;
}
EXPORT_SYMBOL_NS_GPL(cxl_map_pmu_regs, CXL);

static int cxl_map_regblock(struct cxl_register_map *map)
{
	struct device *host = map->host;

	map->base = ioremap(map->resource, map->max_size);
	if (!map->base) {
		dev_err(host, "failed to map registers\n");
		return -ENOMEM;
	}

	dev_dbg(host, "Mapped CXL Memory Device resource %pa\n", &map->resource);
	return 0;
}

static void cxl_unmap_regblock(struct cxl_register_map *map)
{
	iounmap(map->base);
	map->base = NULL;
}

static int cxl_probe_regs(struct cxl_register_map *map)
{
	struct cxl_component_reg_map *comp_map;
	struct cxl_device_reg_map *dev_map;
	struct device *host = map->host;
	void __iomem *base = map->base;

	switch (map->reg_type) {
	case CXL_REGLOC_RBI_COMPONENT:
		comp_map = &map->component_map;
		cxl_probe_component_regs(host, base, comp_map);
		dev_dbg(host, "Set up component registers\n");
		break;
	case CXL_REGLOC_RBI_MEMDEV:
		dev_map = &map->device_map;
		cxl_probe_device_regs(host, base, dev_map);
		if (!dev_map->status.valid || !dev_map->mbox.valid ||
		    !dev_map->memdev.valid) {
			dev_err(host, "registers not found: %s%s%s\n",
				!dev_map->status.valid ? "status " : "",
				!dev_map->mbox.valid ? "mbox " : "",
				!dev_map->memdev.valid ? "memdev " : "");
			return -ENXIO;
		}

		dev_dbg(host, "Probing device registers...\n");
		break;
	default:
		break;
	}

	return 0;
}

int cxl_setup_regs(struct cxl_register_map *map)
{
	int rc;

	rc = cxl_map_regblock(map);
	if (rc)
		return rc;

	rc = cxl_probe_regs(map);
	cxl_unmap_regblock(map);

	return rc;
}
EXPORT_SYMBOL_NS_GPL(cxl_setup_regs, CXL);

u16 cxl_rcrb_to_aer(struct device *dev, resource_size_t rcrb)
{
	void __iomem *addr;
	u16 offset = 0;
	u32 cap_hdr;

	if (WARN_ON_ONCE(rcrb == CXL_RESOURCE_NONE))
		return 0;

	if (!request_mem_region(rcrb, SZ_4K, dev_name(dev)))
		return 0;

	addr = ioremap(rcrb, SZ_4K);
	if (!addr)
		goto out;

	cap_hdr = readl(addr + offset);
	while (PCI_EXT_CAP_ID(cap_hdr) != PCI_EXT_CAP_ID_ERR) {
		offset = PCI_EXT_CAP_NEXT(cap_hdr);

		/* Offset 0 terminates capability list. */
		if (!offset)
			break;
		cap_hdr = readl(addr + offset);
	}

	if (offset)
		dev_dbg(dev, "found AER extended capability (0x%x)\n", offset);

	iounmap(addr);
out:
	release_mem_region(rcrb, SZ_4K);

	return offset;
}

resource_size_t __rcrb_to_component(struct device *dev, struct cxl_rcrb_info *ri,
				    enum cxl_rcrb which)
{
	resource_size_t component_reg_phys;
	resource_size_t rcrb = ri->base;
	void __iomem *addr;
	u32 bar0, bar1;
	u16 cmd;
	u32 id;

	if (which == CXL_RCRB_UPSTREAM)
		rcrb += SZ_4K;

	/*
	 * RCRB's BAR[0..1] point to component block containing CXL
	 * subsystem component registers. MEMBAR extraction follows
	 * the PCI Base spec here, esp. 64 bit extraction and memory
	 * ranges alignment (6.0, 7.5.1.2.1).
	 */
	if (!request_mem_region(rcrb, SZ_4K, "CXL RCRB"))
		return CXL_RESOURCE_NONE;
	addr = ioremap(rcrb, SZ_4K);
	if (!addr) {
		dev_err(dev, "Failed to map region %pr\n", addr);
		release_mem_region(rcrb, SZ_4K);
		return CXL_RESOURCE_NONE;
	}

	id = readl(addr + PCI_VENDOR_ID);
	cmd = readw(addr + PCI_COMMAND);
	bar0 = readl(addr + PCI_BASE_ADDRESS_0);
	bar1 = readl(addr + PCI_BASE_ADDRESS_1);
	iounmap(addr);
	release_mem_region(rcrb, SZ_4K);

	/*
	 * Sanity check, see CXL 3.0 Figure 9-8 CXL Device that Does Not
	 * Remap Upstream Port and Component Registers
	 */
	if (id == U32_MAX) {
		if (which == CXL_RCRB_DOWNSTREAM)
			dev_err(dev, "Failed to access Downstream Port RCRB\n");
		return CXL_RESOURCE_NONE;
	}
	if (!(cmd & PCI_COMMAND_MEMORY))
		return CXL_RESOURCE_NONE;
	/* The RCRB is a Memory Window, and the MEM_TYPE_1M bit is obsolete */
	if (bar0 & (PCI_BASE_ADDRESS_MEM_TYPE_1M | PCI_BASE_ADDRESS_SPACE_IO))
		return CXL_RESOURCE_NONE;

	component_reg_phys = bar0 & PCI_BASE_ADDRESS_MEM_MASK;
	if (bar0 & PCI_BASE_ADDRESS_MEM_TYPE_64)
		component_reg_phys |= ((u64)bar1) << 32;

	if (!component_reg_phys)
		return CXL_RESOURCE_NONE;

	/* MEMBAR is block size (64k) aligned. */
	if (!IS_ALIGNED(component_reg_phys, CXL_COMPONENT_REG_BLOCK_SIZE))
		return CXL_RESOURCE_NONE;

	return component_reg_phys;
}

resource_size_t cxl_rcd_component_reg_phys(struct device *dev,
					   struct cxl_dport *dport)
{
	if (!dport->rch)
		return CXL_RESOURCE_NONE;
	return __rcrb_to_component(dev, &dport->rcrb, CXL_RCRB_UPSTREAM);
}
EXPORT_SYMBOL_NS_GPL(cxl_rcd_component_reg_phys, CXL);
