[U-Boot] [PATCH 15/23] pci: tegra: Add Tegra PCIe driver

Stephen Warren swarren at wwwdotorg.org
Wed Aug 20 21:04:22 CEST 2014


On 08/18/2014 01:16 AM, Thierry Reding wrote:
> From: Thierry Reding <treding at nvidia.com>
>
> Add support for the PCIe controller found on some generations of Tegra.
> Tegra20 has 2 root ports with a total of 4 lanes, Tegra30 has 3 root
> ports with a total of 6 lanes and Tegra124 has 2 root ports with a total
> of 5 lanes.

> diff --git a/drivers/pci/pci_tegra.c b/drivers/pci/pci_tegra.c

> + * Copyright (c) 2010, CompuLab, Ltd.
> + * Author: Mike Rapoport <mike at compulab.co.il>
> + *
> + * Based on NVIDIA PCIe driver
> + * Copyright (c) 2008-2009, NVIDIA Corporation.

Presumably also at least (c) 2013-2014 NVIDIA too?

Do you have Mike's S-o-b for the initial work?

> +static int tegra_pcie_read_conf(struct pci_controller *hose, pci_dev_t bdf,
> +				int where, u32 *value)
> +{
> +	struct tegra_pcie *pcie = to_tegra_pcie(hose);
> +	unsigned long address;
> +	int err;
> +
> +	err = tegra_pcie_conf_address(pcie, bdf, where, &address);
> +	if (err < 0) {
> +		*value = 0xffffffff;
> +		return 1;
> +	}

In the kernel, don't we have to play games to dynamically map/unmap 
memory regions and/or map pages in a non-linear fashion since the config 
space is so large, and bus/device ID -> address mapping is odd? I don't 
see that here.

> +static bool tegra_pcie_port_check_link(struct tegra_pcie_port *port)
> +{
> +	unsigned int retries = 3;
> +	unsigned long value;
> +
> +	value = rp_readl(port, RP_PRIV_MISC);
> +	value &= ~RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT;
> +	value |= RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT;
> +	rp_writel(port, value, RP_PRIV_MISC);
> +
> +	do {
> +		unsigned int timeout = 200;
> +
> +		do {
> +			value = rp_readl(port, RP_VEND_XP);
> +			if (value & RP_VEND_XP_DL_UP)
> +				break;

On my board, this almost never succeeds for Jetson TK1's built-in NIC, 
although it works fine for the mini-PCIe slot. On the other two boards I 
borrowed, this succeeds almost always. I'd prefer if we could get to the 
bottom of this before we actually apply this, although the bug is 
proving quite perplexing. The mainline kernel PCIe patches have the same 
issue.

> +static int process_nodes(const void *fdt, int nodes[], unsigned int count)

> +#ifdef CONFIG_PCI_SCAN_SHOW
> +		printf("PCI: Enumerating devices...\n");
> +		printf("---------------------------------------\n");
> +		printf("  Device        ID          Description\n");
> +		printf("  ------        --          -----------\n");
> +#endif
> +
> +		pcie->hose.last_busno = pci_hose_scan(&pcie->hose);

Shouldn't that ifdef'd block be part of pci_hose_scan()?


More information about the U-Boot mailing list