drivers/pci/controller/pcie-rcar-ep.c

Source file repositories/reference/linux-study-clean/drivers/pci/controller/pcie-rcar-ep.c

File Facts

System
Linux kernel
Corpus path
drivers/pci/controller/pcie-rcar-ep.c
Extension
.c
Size
14037 bytes
Lines
562
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 rcar_pcie_endpoint {
	struct rcar_pcie	pcie;
	phys_addr_t		*ob_mapped_addr;
	struct pci_epc_mem_window *ob_window;
	u8			max_functions;
	unsigned int		bar_to_atu[MAX_NR_INBOUND_MAPS];
	unsigned long		*ib_window_map;
	u32			num_ib_windows;
	u32			num_ob_windows;
};

static void rcar_pcie_ep_hw_init(struct rcar_pcie *pcie)
{
	u32 val;

	rcar_pci_write_reg(pcie, 0, PCIETCTLR);

	/* Set endpoint mode */
	rcar_pci_write_reg(pcie, 0, PCIEMSR);

	/* Initialize default capabilities. */
	rcar_rmw32(pcie, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
	rcar_rmw32(pcie, REXPCAP(PCI_EXP_FLAGS),
		   PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ENDPOINT << 4);
	rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), PCI_HEADER_TYPE_MASK,
		   PCI_HEADER_TYPE_NORMAL);

	/* Write out the physical slot number = 0 */
	rcar_rmw32(pcie, REXPCAP(PCI_EXP_SLTCAP), PCI_EXP_SLTCAP_PSN, 0);

	val = rcar_pci_read_reg(pcie, EXPCAP(1));
	/* device supports fixed 128 bytes MPSS */
	val &= ~GENMASK(2, 0);
	rcar_pci_write_reg(pcie, val, EXPCAP(1));

	val = rcar_pci_read_reg(pcie, EXPCAP(2));
	/* read requests size 128 bytes */
	val &= ~GENMASK(14, 12);
	/* payload size 128 bytes */
	val &= ~GENMASK(7, 5);
	rcar_pci_write_reg(pcie, val, EXPCAP(2));

	/* Set target link speed to 5.0 GT/s */
	rcar_rmw32(pcie, EXPCAP(12), PCI_EXP_LNKSTA_CLS,
		   PCI_EXP_LNKSTA_CLS_5_0GB);

	/* Set the completion timer timeout to the maximum 50ms. */
	rcar_rmw32(pcie, TLCTLR + 1, 0x3f, 50);

	/* Terminate list of capabilities (Next Capability Offset=0) */
	rcar_rmw32(pcie, RVCCAP(0), 0xfff00000, 0);

	/* flush modifications */
	wmb();
}

static int rcar_pcie_ep_get_window(struct rcar_pcie_endpoint *ep,
				   phys_addr_t addr)
{
	int i;

	for (i = 0; i < ep->num_ob_windows; i++)
		if (ep->ob_window[i].phys_base == addr)
			return i;

	return -EINVAL;
}

static int rcar_pcie_parse_outbound_ranges(struct rcar_pcie_endpoint *ep,
					   struct platform_device *pdev)
{
	struct rcar_pcie *pcie = &ep->pcie;
	char outbound_name[10];
	struct resource *res;
	unsigned int i = 0;

	ep->num_ob_windows = 0;
	for (i = 0; i < RCAR_PCI_MAX_RESOURCES; i++) {
		sprintf(outbound_name, "memory%u", i);
		res = platform_get_resource_byname(pdev,
						   IORESOURCE_MEM,
						   outbound_name);
		if (!res) {
			dev_err(pcie->dev, "missing outbound window %u\n", i);
			return -EINVAL;
		}
		if (!devm_request_mem_region(&pdev->dev, res->start,
					     resource_size(res),
					     res->name)) {
			dev_err(pcie->dev, "Cannot request memory region %s.\n",

Annotation

Implementation Notes