drivers/pci/controller/dwc/pcie-al.c

Source file repositories/reference/linux-study-clean/drivers/pci/controller/dwc/pcie-al.c

File Facts

System
Linux kernel
Corpus path
drivers/pci/controller/dwc/pcie-al.c
Extension
.c
Size
9859 bytes
Lines
392
Domain
Representative Device Path
Bucket
PCIe NVMe Storage Path
Inferred role
Representative Device Path: implementation source
Status
source implementation candidate

Why This File Exists

Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.

Dependency Surface

Detected Declarations

Annotated Snippet

struct al_pcie_acpi  {
	void __iomem *dbi_base;
};

static void __iomem *al_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
				     int where)
{
	struct pci_config_window *cfg = bus->sysdata;
	struct al_pcie_acpi *pcie = cfg->priv;
	void __iomem *dbi_base = pcie->dbi_base;

	if (bus->number == cfg->busr.start) {
		/*
		 * The DW PCIe core doesn't filter out transactions to other
		 * devices/functions on the root bus num, so we do this here.
		 */
		if (PCI_SLOT(devfn) > 0)
			return NULL;
		else
			return dbi_base + where;
	}

	return pci_ecam_map_bus(bus, devfn, where);
}

static int al_pcie_init(struct pci_config_window *cfg)
{
	struct device *dev = cfg->parent;
	struct acpi_device *adev = to_acpi_device(dev);
	struct acpi_pci_root *root = acpi_driver_data(adev);
	struct al_pcie_acpi *al_pcie;
	struct resource *res;
	int ret;

	al_pcie = devm_kzalloc(dev, sizeof(*al_pcie), GFP_KERNEL);
	if (!al_pcie)
		return -ENOMEM;

	res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
	if (!res)
		return -ENOMEM;

	ret = acpi_get_rc_resources(dev, "AMZN0001", root->segment, res);
	if (ret) {
		dev_err(dev, "can't get rc dbi base address for SEG %d\n",
			root->segment);
		return ret;
	}

	dev_dbg(dev, "Root port dbi res: %pR\n", res);

	al_pcie->dbi_base = devm_pci_remap_cfg_resource(dev, res);
	if (IS_ERR(al_pcie->dbi_base))
		return PTR_ERR(al_pcie->dbi_base);

	cfg->priv = al_pcie;

	return 0;
}

const struct pci_ecam_ops al_pcie_ops = {
	.init         =  al_pcie_init,
	.pci_ops      = {
		.map_bus    = al_pcie_map_bus,
		.read       = pci_generic_config_read,
		.write      = pci_generic_config_write,
	}
};

#endif /* defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) */

#ifdef CONFIG_PCIE_AL

#include <linux/of_pci.h>
#include "pcie-designware.h"

#define AL_PCIE_REV_ID_2	2
#define AL_PCIE_REV_ID_3	3
#define AL_PCIE_REV_ID_4	4

#define AXI_BASE_OFFSET		0x0

#define DEVICE_ID_OFFSET	0x16c

#define DEVICE_REV_ID			0x0
#define DEVICE_REV_ID_DEV_ID_MASK	GENMASK(31, 16)

#define DEVICE_REV_ID_DEV_ID_X4		0
#define DEVICE_REV_ID_DEV_ID_X8		2
#define DEVICE_REV_ID_DEV_ID_X16	4

Annotation

Implementation Notes