/*
 * Copyright (c) 2021, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *
 * The RPi4 has a single nonstandard PCI config region. It is broken into two
 * pieces, the root port config registers and a window to a single device's
 * config space which can move between devices. There isn't (yet) an
 * authoritative public document on this since the available BCM2711 reference
 * notes that there is a PCIe root port in the memory map but doesn't describe
 * it. Given that it's not ECAM compliant yet reasonably simple, it makes for
 * an excellent example of the PCI SMCCC interface.
 *
 * The PCI SMCCC interface is described in DEN0115 available from:
 * https://developer.arm.com/documentation/den0115/latest
 */

#include <assert.h>
#include <stdint.h>

#include <common/debug.h>
#include <common/runtime_svc.h>
#include <lib/pmf/pmf.h>
#include <lib/runtime_instr.h>
#include <services/pci_svc.h>
#include <services/sdei.h>
#include <services/std_svc.h>
#include <smccc_helpers.h>

#include <lib/mmio.h>

static spinlock_t pci_lock;

#define PCIE_REG_BASE		U(RPI_IO_BASE + 0x01500000)
#define PCIE_MISC_PCIE_STATUS	0x4068
#define PCIE_EXT_CFG_INDEX	0x9000
/* A small window pointing at the ECAM of the device selected by CFG_INDEX */
#define PCIE_EXT_CFG_DATA	0x8000
#define INVALID_PCI_ADDR	0xFFFFFFFF

#define	PCIE_EXT_BUS_SHIFT	20
#define	PCIE_EXT_DEV_SHIFT	15
#define	PCIE_EXT_FUN_SHIFT	12


static uint64_t pci_segment_lib_get_base(uint32_t address, uint32_t offset)
{
	uint64_t	base;
	uint32_t	bus, dev, fun;
	uint32_t	status;

	base = PCIE_REG_BASE;

	offset &= PCI_OFFSET_MASK;  /* Pick off the 4k register offset */

	/* The root port is at the base of the PCIe register space */
	if (address != 0U) {
		/*
		 * The current device must be at CFG_DATA, a 4K window mapped,
		 * via CFG_INDEX, to the device we are accessing. At the same
		 * time we must avoid accesses to certain areas of the cfg
		 * space via CFG_DATA. Detect those accesses and report that
		 * the address is invalid.
		 */
		base += PCIE_EXT_CFG_DATA;
		bus = PCI_ADDR_BUS(address);
		dev = PCI_ADDR_DEV(address);
		fun = PCI_ADDR_FUN(address);
		address = (bus << PCIE_EXT_BUS_SHIFT) |
			  (dev << PCIE_EXT_DEV_SHIFT) |
			  (fun << PCIE_EXT_FUN_SHIFT);

		/* Allow only dev = 0 on root port and bus 1 */
		if ((bus < 2U) && (dev > 0U)) {
			return INVALID_PCI_ADDR;
		}

		/* Assure link up before reading bus 1 */
		status = mmio_read_32(PCIE_REG_BASE + PCIE_MISC_PCIE_STATUS);
		if ((status & 0x30) != 0x30) {
			return INVALID_PCI_ADDR;
		}

		/* Adjust which device the CFG_DATA window is pointing at */
		mmio_write_32(PCIE_REG_BASE + PCIE_EXT_CFG_INDEX, address);
	}
	return base + offset;
}

/**
 * pci_read_config() - Performs a config space read at addr
 * @addr: 32-bit, segment, BDF of requested function encoded per DEN0115
 * @off:  register offset of function described by @addr to read
 * @sz:	  size of read (8,16,32) bits.
 * @val:  returned zero extended value read from config space
 *
 * sz bits of PCI config space is read at addr:offset, and the value
 * is returned in val. Invalid segment/offset values return failure.
 * Reads to valid functions that don't exist return INVALID_PCI_ADDR
 * as is specified by PCI for requests that aren't completed by EPs.
 * The boilerplate in pci_svc.c tends to do basic segment, off
 * and sz validation. This routine should avoid duplicating those
 * checks.
 *
 * This function maps directly to the PCI_READ function in DEN0115
 * where detailed requirements may be found.
 *
 * Return: SMC_PCI_CALL_SUCCESS with val set
 *	   SMC_PCI_CALL_INVAL_PARAM, on parameter error
 */
uint32_t pci_read_config(uint32_t addr, uint32_t off, uint32_t sz, uint32_t *val)
{
	uint32_t ret = SMC_PCI_CALL_SUCCESS;
	uint64_t base;

	spin_lock(&pci_lock);
	base = pci_segment_lib_get_base(addr, off);

	if (base == INVALID_PCI_ADDR) {
		*val = base;
	} else {
		switch (sz) {
		case SMC_PCI_SZ_8BIT:
			*val = mmio_read_8(base);
			break;
		case SMC_PCI_SZ_16BIT:
			*val = mmio_read_16(base);
			break;
		case SMC_PCI_SZ_32BIT:
			*val = mmio_read_32(base);
			break;
		default: /* should be unreachable */
			*val = 0;
			ret = SMC_PCI_CALL_INVAL_PARAM;
		}
	}
	spin_unlock(&pci_lock);
	return ret;
}

/**
 * pci_write_config() - Performs a config space write at addr
 * @addr: 32-bit, segment, BDF of requested function encoded per DEN0115
 * @off:  register offset of function described by @addr to write
 * @sz:	  size of write (8,16,32) bits.
 * @val:  value to be written
 *
 * sz bits of PCI config space is written at addr:offset. Invalid
 * segment/BDF values return failure. Writes to valid functions
 * without valid EPs are ignored, as is specified by PCI.
 * The boilerplate in pci_svc.c tends to do basic segment, off
 * and sz validation, so it shouldn't need to be repeated here.
 *
 * This function maps directly to the PCI_WRITE function in DEN0115
 * where detailed requirements may be found.
 *
 * Return: SMC_PCI_CALL_SUCCESS
 *	   SMC_PCI_CALL_INVAL_PARAM, on parameter error
 */
uint32_t pci_write_config(uint32_t addr, uint32_t off, uint32_t sz, uint32_t val)
{
	uint32_t ret = SMC_PCI_CALL_SUCCESS;
	uint64_t base;

	spin_lock(&pci_lock);
	base = pci_segment_lib_get_base(addr, off);

	if (base != INVALID_PCI_ADDR) {
		switch (sz) {
		case SMC_PCI_SZ_8BIT:
			mmio_write_8(base, val);
			break;
		case SMC_PCI_SZ_16BIT:
			mmio_write_16(base, val);
			break;
		case SMC_PCI_SZ_32BIT:
			mmio_write_32(base, val);
			break;
		default: /* should be unreachable */
			ret = SMC_PCI_CALL_INVAL_PARAM;
		}
	}
	spin_unlock(&pci_lock);
	return ret;
}

/**
 * pci_get_bus_for_seg() - returns the start->end bus range for a segment
 * @seg:  segment being queried
 * @bus_range:	returned bus begin + (end << 8)
 * @nseg: returns next segment in this machine or 0 for end
 *
 * pci_get_bus_for_seg is called to check if a given segment is
 * valid on this machine. If it is valid, then its bus ranges are
 * returned along with the next valid segment on the machine. If
 * this is the last segment, then nseg must be 0.
 *
 * This function maps directly to the PCI_GET_SEG_INFO function
 * in DEN0115 where detailed requirements may be found.
 *
 * Return: SMC_PCI_CALL_SUCCESS, and appropriate bus_range and nseg
 *	   SMC_PCI_CALL_NOT_IMPL, if the segment is invalid
 */
uint32_t pci_get_bus_for_seg(uint32_t seg, uint32_t *bus_range, uint32_t *nseg)
{
	uint32_t ret = SMC_PCI_CALL_SUCCESS;
	*nseg = 0U; /* only a single segment */
	if (seg == 0U) {
		*bus_range = 0xFF00; /* start 0, end 255 */
	} else {
		*bus_range = 0U;
		ret = SMC_PCI_CALL_NOT_IMPL;
	}
	return ret;
}
