// SPDX-License-Identifier: GPL-2.0

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

#include "../habanalabs.h"
#include "../../include/hw_ip/pci/pci_general.h"

#include <linux/pci.h>

#define HL_PLDM_PCI_ELBI_TIMEOUT_MSEC	(HL_PCI_ELBI_TIMEOUT_MSEC * 100)

#define IATU_REGION_CTRL_REGION_EN_MASK		BIT(31)
#define IATU_REGION_CTRL_MATCH_MODE_MASK	BIT(30)
#define IATU_REGION_CTRL_NUM_MATCH_EN_MASK	BIT(19)
#define IATU_REGION_CTRL_BAR_NUM_MASK		GENMASK(10, 8)

/**
 * hl_pci_bars_map() - Map PCI BARs.
 * @hdev: Pointer to hl_device structure.
 * @name: Array of BAR names.
 * @is_wc: Array with flag per BAR whether a write-combined mapping is needed.
 *
 * Request PCI regions and map them to kernel virtual addresses.
 *
 * Return: 0 on success, non-zero for failure.
 */
int hl_pci_bars_map(struct hl_device *hdev, const char * const name[3],
			bool is_wc[3])
{
	struct pci_dev *pdev = hdev->pdev;
	int rc, i, bar;

	rc = pci_request_regions(pdev, HL_NAME);
	if (rc) {
		dev_err(hdev->dev, "Cannot obtain PCI resources\n");
		return rc;
	}

	for (i = 0 ; i < 3 ; i++) {
		bar = i * 2; /* 64-bit BARs */
		hdev->pcie_bar[bar] = is_wc[i] ?
				pci_ioremap_wc_bar(pdev, bar) :
				pci_ioremap_bar(pdev, bar);
		if (!hdev->pcie_bar[bar]) {
			dev_err(hdev->dev, "pci_ioremap%s_bar failed for %s\n",
					is_wc[i] ? "_wc" : "", name[i]);
			rc = -ENODEV;
			goto err;
		}
	}

	return 0;

err:
	for (i = 2 ; i >= 0 ; i--) {
		bar = i * 2; /* 64-bit BARs */
		if (hdev->pcie_bar[bar])
			iounmap(hdev->pcie_bar[bar]);
	}

	pci_release_regions(pdev);

	return rc;
}

/**
 * hl_pci_bars_unmap() - Unmap PCI BARS.
 * @hdev: Pointer to hl_device structure.
 *
 * Release all PCI BARs and unmap their virtual addresses.
 */
static void hl_pci_bars_unmap(struct hl_device *hdev)
{
	struct pci_dev *pdev = hdev->pdev;
	int i, bar;

	for (i = 2 ; i >= 0 ; i--) {
		bar = i * 2; /* 64-bit BARs */
		iounmap(hdev->pcie_bar[bar]);
	}

	pci_release_regions(pdev);
}

int hl_pci_elbi_read(struct hl_device *hdev, u64 addr, u32 *data)
{
	struct pci_dev *pdev = hdev->pdev;
	ktime_t timeout;
	u64 msec;
	u32 val;

	if (hdev->pldm)
		msec = HL_PLDM_PCI_ELBI_TIMEOUT_MSEC;
	else
		msec = HL_PCI_ELBI_TIMEOUT_MSEC;

	/* Clear previous status */
	pci_write_config_dword(pdev, mmPCI_CONFIG_ELBI_STS, 0);

	pci_write_config_dword(pdev, mmPCI_CONFIG_ELBI_ADDR, (u32) addr);
	pci_write_config_dword(pdev, mmPCI_CONFIG_ELBI_CTRL, 0);

	timeout = ktime_add_ms(ktime_get(), msec);
	for (;;) {
		pci_read_config_dword(pdev, mmPCI_CONFIG_ELBI_STS, &val);
		if (val & PCI_CONFIG_ELBI_STS_MASK)
			break;
		if (ktime_compare(ktime_get(), timeout) > 0) {
			pci_read_config_dword(pdev, mmPCI_CONFIG_ELBI_STS,
						&val);
			break;
		}

		usleep_range(300, 500);
	}

	if ((val & PCI_CONFIG_ELBI_STS_MASK) == PCI_CONFIG_ELBI_STS_DONE) {
		pci_read_config_dword(pdev, mmPCI_CONFIG_ELBI_DATA, data);

		return 0;
	}

	if (val & PCI_CONFIG_ELBI_STS_ERR) {
		dev_err(hdev->dev, "Error reading from ELBI\n");
		return -EIO;
	}

	if (!(val & PCI_CONFIG_ELBI_STS_MASK)) {
		dev_err(hdev->dev, "ELBI read didn't finish in time\n");
		return -EIO;
	}

	dev_err(hdev->dev, "ELBI read has undefined bits in status\n");
	return -EIO;
}

/**
 * hl_pci_elbi_write() - Write through the ELBI interface.
 * @hdev: Pointer to hl_device structure.
 * @addr: Address to write to
 * @data: Data to write
 *
 * Return: 0 on success, negative value for failure.
 */
static int hl_pci_elbi_write(struct hl_device *hdev, u64 addr, u32 data)
{
	struct pci_dev *pdev = hdev->pdev;
	ktime_t timeout;
	u64 msec;
	u32 val;

	if (hdev->pldm)
		msec = HL_PLDM_PCI_ELBI_TIMEOUT_MSEC;
	else
		msec = HL_PCI_ELBI_TIMEOUT_MSEC;

	/* Clear previous status */
	pci_write_config_dword(pdev, mmPCI_CONFIG_ELBI_STS, 0);

	pci_write_config_dword(pdev, mmPCI_CONFIG_ELBI_ADDR, (u32) addr);
	pci_write_config_dword(pdev, mmPCI_CONFIG_ELBI_DATA, data);
	pci_write_config_dword(pdev, mmPCI_CONFIG_ELBI_CTRL,
				PCI_CONFIG_ELBI_CTRL_WRITE);

	timeout = ktime_add_ms(ktime_get(), msec);
	for (;;) {
		pci_read_config_dword(pdev, mmPCI_CONFIG_ELBI_STS, &val);
		if (val & PCI_CONFIG_ELBI_STS_MASK)
			break;
		if (ktime_compare(ktime_get(), timeout) > 0) {
			pci_read_config_dword(pdev, mmPCI_CONFIG_ELBI_STS,
						&val);
			break;
		}

		usleep_range(300, 500);
	}

	if ((val & PCI_CONFIG_ELBI_STS_MASK) == PCI_CONFIG_ELBI_STS_DONE)
		return 0;

	if (val & PCI_CONFIG_ELBI_STS_ERR)
		return -EIO;

	if (!(val & PCI_CONFIG_ELBI_STS_MASK)) {
		dev_err(hdev->dev, "ELBI write didn't finish in time\n");
		return -EIO;
	}

	dev_err(hdev->dev, "ELBI write has undefined bits in status\n");
	return -EIO;
}

/**
 * hl_pci_iatu_write() - iatu write routine.
 * @hdev: Pointer to hl_device structure.
 * @addr: Address to write to
 * @data: Data to write
 *
 * Return: 0 on success, negative value for failure.
 */
int hl_pci_iatu_write(struct hl_device *hdev, u32 addr, u32 data)
{
	struct asic_fixed_properties *prop = &hdev->asic_prop;
	u32 dbi_offset;
	int rc;

	dbi_offset = addr & 0xFFF;

	/* Ignore result of writing to pcie_aux_dbi_reg_addr as it could fail
	 * in case the firmware security is enabled
	 */
	hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr, 0x00300000);

	rc = hl_pci_elbi_write(hdev, prop->pcie_dbi_base_address + dbi_offset,
				data);

	if (rc)
		return -EIO;

	return 0;
}

/**
 * hl_pci_set_inbound_region() - Configure inbound region
 * @hdev: Pointer to hl_device structure.
 * @region: Inbound region number.
 * @pci_region: Inbound region parameters.
 *
 * Configure the iATU inbound region.
 *
 * Return: 0 on success, negative value for failure.
 */
int hl_pci_set_inbound_region(struct hl_device *hdev, u8 region,
		struct hl_inbound_pci_region *pci_region)
{
	struct asic_fixed_properties *prop = &hdev->asic_prop;
	u64 bar_phys_base, region_base, region_end_address;
	u32 offset, ctrl_reg_val;
	int rc = 0;

	/* region offset */
	offset = (0x200 * region) + 0x100;

	if (pci_region->mode == PCI_ADDRESS_MATCH_MODE) {
		bar_phys_base = hdev->pcie_bar_phys[pci_region->bar];
		region_base = bar_phys_base + pci_region->offset_in_bar;
		region_end_address = region_base + pci_region->size - 1;

		rc |= hl_pci_iatu_write(hdev, offset + 0x8,
				lower_32_bits(region_base));
		rc |= hl_pci_iatu_write(hdev, offset + 0xC,
				upper_32_bits(region_base));
		rc |= hl_pci_iatu_write(hdev, offset + 0x10,
				lower_32_bits(region_end_address));
	}

	/* Point to the specified address */
	rc |= hl_pci_iatu_write(hdev, offset + 0x14, lower_32_bits(pci_region->addr));
	rc |= hl_pci_iatu_write(hdev, offset + 0x18, upper_32_bits(pci_region->addr));

	/* Set bar type as memory */
	rc |= hl_pci_iatu_write(hdev, offset + 0x0, 0);

	/* Enable + bar/address match + match enable + bar number */
	ctrl_reg_val = FIELD_PREP(IATU_REGION_CTRL_REGION_EN_MASK, 1);
	ctrl_reg_val |= FIELD_PREP(IATU_REGION_CTRL_MATCH_MODE_MASK, pci_region->mode);
	ctrl_reg_val |= FIELD_PREP(IATU_REGION_CTRL_NUM_MATCH_EN_MASK, 1);

	if (pci_region->mode == PCI_BAR_MATCH_MODE)
		ctrl_reg_val |= FIELD_PREP(IATU_REGION_CTRL_BAR_NUM_MASK, pci_region->bar);

	rc |= hl_pci_iatu_write(hdev, offset + 0x4, ctrl_reg_val);

	/* Return the DBI window to the default location
	 * Ignore result of writing to pcie_aux_dbi_reg_addr as it could fail
	 * in case the firmware security is enabled
	 */
	hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr, 0);

	if (rc)
		dev_err(hdev->dev, "failed to map bar %u to 0x%08llx\n",
				pci_region->bar, pci_region->addr);

	return rc;
}

/**
 * hl_pci_set_outbound_region() - Configure outbound region 0
 * @hdev: Pointer to hl_device structure.
 * @pci_region: Outbound region parameters.
 *
 * Configure the iATU outbound region 0.
 *
 * Return: 0 on success, negative value for failure.
 */
int hl_pci_set_outbound_region(struct hl_device *hdev,
		struct hl_outbound_pci_region *pci_region)
{
	struct asic_fixed_properties *prop = &hdev->asic_prop;
	u64 outbound_region_end_address;
	int rc = 0;

	/* Outbound Region 0 */
	outbound_region_end_address =
			pci_region->addr + pci_region->size - 1;
	rc |= hl_pci_iatu_write(hdev, 0x008,
				lower_32_bits(pci_region->addr));
	rc |= hl_pci_iatu_write(hdev, 0x00C,
				upper_32_bits(pci_region->addr));
	rc |= hl_pci_iatu_write(hdev, 0x010,
				lower_32_bits(outbound_region_end_address));
	rc |= hl_pci_iatu_write(hdev, 0x014, 0);

	rc |= hl_pci_iatu_write(hdev, 0x018, 0);

	rc |= hl_pci_iatu_write(hdev, 0x020,
				upper_32_bits(outbound_region_end_address));
	/* Increase region size */
	rc |= hl_pci_iatu_write(hdev, 0x000, 0x00002000);
	/* Enable */
	rc |= hl_pci_iatu_write(hdev, 0x004, 0x80000000);

	/* Return the DBI window to the default location
	 * Ignore result of writing to pcie_aux_dbi_reg_addr as it could fail
	 * in case the firmware security is enabled
	 */
	hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr, 0);

	return rc;
}

/**
 * hl_get_pci_memory_region() - get PCI region for given address
 * @hdev: Pointer to hl_device structure.
 * @addr: device address
 *
 * @return region index on success, otherwise PCI_REGION_NUMBER (invalid
 *         region index)
 */
enum pci_region hl_get_pci_memory_region(struct hl_device *hdev, u64 addr)
{
	int i;

	for  (i = 0 ; i < PCI_REGION_NUMBER ; i++) {
		struct pci_mem_region *region = &hdev->pci_mem_region[i];

		if (!region->used)
			continue;

		if ((addr >= region->region_base) &&
			(addr < region->region_base + region->region_size))
			return i;
	}

	return PCI_REGION_NUMBER;
}

/**
 * hl_pci_init() - PCI initialization code.
 * @hdev: Pointer to hl_device structure.
 *
 * Set DMA masks, initialize the PCI controller and map the PCI BARs.
 *
 * Return: 0 on success, non-zero for failure.
 */
int hl_pci_init(struct hl_device *hdev)
{
	struct asic_fixed_properties *prop = &hdev->asic_prop;
	struct pci_dev *pdev = hdev->pdev;
	int rc;

	rc = pci_enable_device_mem(pdev);
	if (rc) {
		dev_err(hdev->dev, "can't enable PCI device\n");
		return rc;
	}

	pci_set_master(pdev);

	rc = hdev->asic_funcs->pci_bars_map(hdev);
	if (rc) {
		dev_err(hdev->dev, "Failed to map PCI BAR addresses\n");
		goto disable_device;
	}

	rc = hdev->asic_funcs->init_iatu(hdev);
	if (rc) {
		dev_err(hdev->dev, "PCI controller was not initialized successfully\n");
		goto unmap_pci_bars;
	}

	/* Driver must sleep in order for FW to finish the iATU configuration */
	if (hdev->asic_prop.iatu_done_by_fw)
		usleep_range(2000, 3000);

	rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(prop->dma_mask));
	if (rc) {
		dev_err(hdev->dev,
			"Failed to set dma mask to %d bits, error %d\n",
			prop->dma_mask, rc);
		goto unmap_pci_bars;
	}

	dma_set_max_seg_size(&pdev->dev, U32_MAX);

	return 0;

unmap_pci_bars:
	hl_pci_bars_unmap(hdev);
disable_device:
	pci_clear_master(pdev);
	pci_disable_device(pdev);

	return rc;
}

/**
 * hl_pci_fini() - PCI finalization code.
 * @hdev: Pointer to hl_device structure
 *
 * Unmap PCI bars and disable PCI device.
 */
void hl_pci_fini(struct hl_device *hdev)
{
	hl_pci_bars_unmap(hdev);

	pci_clear_master(hdev->pdev);
	pci_disable_device(hdev->pdev);
}
