dm: tegra: pci: Convert tegra boards to driver model for PCI

Adjust the Tegra PCI driver to support driver model and move all boards over
at the same time. This can make use of some generic driver model code, such
as the range-decoding logic.

Signed-off-by: Simon Glass <sjg@chromium.org>
Tested-by: Stephen Warren <swarren@nvidia.com>
master
Simon Glass 9 years ago
parent f9260336d0
commit e81ca88451
  1. 1
      arch/arm/mach-tegra/Kconfig
  2. 4
      arch/arm/mach-tegra/board2.c
  3. 477
      drivers/pci/pci_tegra.c
  4. 4
      include/fdtdec.h
  5. 4
      lib/fdtdec.c

@ -6,6 +6,7 @@ config TEGRA_COMMON
select DM_GPIO select DM_GPIO
select DM_I2C select DM_I2C
select DM_KEYBOARD select DM_KEYBOARD
select DM_PCI
select DM_SERIAL select DM_SERIAL
select DM_SPI select DM_SPI
select DM_SPI_FLASH select DM_SPI_FLASH

@ -377,6 +377,10 @@ void dram_init_banksize(void)
gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
gd->bd->bi_dram[0].size = usable_ram_size_below_4g(); gd->bd->bi_dram[0].size = usable_ram_size_below_4g();
#ifdef CONFIG_PCI
gd->pci_ram_top = gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size;
#endif
#ifdef CONFIG_PHYS_64BIT #ifdef CONFIG_PHYS_64BIT
if (gd->ram_size > SZ_2G) { if (gd->ram_size > SZ_2G) {
gd->bd->bi_dram[1].start = 0x100000000; gd->bd->bi_dram[1].start = 0x100000000;

@ -10,10 +10,10 @@
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
*/ */
#define DEBUG
#define pr_fmt(fmt) "tegra-pcie: " fmt #define pr_fmt(fmt) "tegra-pcie: " fmt
#include <common.h> #include <common.h>
#include <dm.h>
#include <errno.h> #include <errno.h>
#include <fdtdec.h> #include <fdtdec.h>
#include <malloc.h> #include <malloc.h>
@ -177,7 +177,12 @@ DECLARE_GLOBAL_DATA_PTR;
#define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000 #define RP_LINK_CONTROL_STATUS_DL_LINK_ACTIVE 0x20000000
#define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000 #define RP_LINK_CONTROL_STATUS_LINKSTAT_MASK 0x3fff0000
struct tegra_pcie; enum tegra_pci_id {
TEGRA20_PCIE,
TEGRA30_PCIE,
TEGRA124_PCIE,
TEGRA210_PCIE,
};
struct tegra_pcie_port { struct tegra_pcie_port {
struct tegra_pcie *pcie; struct tegra_pcie *pcie;
@ -207,10 +212,6 @@ struct tegra_pcie {
struct fdt_resource afi; struct fdt_resource afi;
struct fdt_resource cs; struct fdt_resource cs;
struct fdt_resource prefetch;
struct fdt_resource mem;
struct fdt_resource io;
struct list_head ports; struct list_head ports;
unsigned long xbar; unsigned long xbar;
@ -218,11 +219,6 @@ struct tegra_pcie {
struct tegra_xusb_phy *phy; struct tegra_xusb_phy *phy;
}; };
static inline struct tegra_pcie *to_tegra_pcie(struct pci_controller *hose)
{
return container_of(hose, struct tegra_pcie, hose);
}
static void afi_writel(struct tegra_pcie *pcie, unsigned long value, static void afi_writel(struct tegra_pcie *pcie, unsigned long value,
unsigned long offset) unsigned long offset)
{ {
@ -284,46 +280,54 @@ static int tegra_pcie_conf_address(struct tegra_pcie *pcie, pci_dev_t bdf,
return 0; return 0;
} }
return -1; return -EFAULT;
} }
static int tegra_pcie_read_conf(struct pci_controller *hose, pci_dev_t bdf, static int pci_tegra_read_config(struct udevice *bus, pci_dev_t bdf,
int where, u32 *value) uint offset, ulong *valuep,
enum pci_size_t size)
{ {
struct tegra_pcie *pcie = to_tegra_pcie(hose); struct tegra_pcie *pcie = dev_get_priv(bus);
unsigned long address; unsigned long address, value;
int err; int err;
err = tegra_pcie_conf_address(pcie, bdf, where, &address); err = tegra_pcie_conf_address(pcie, bdf, offset, &address);
if (err < 0) { if (err < 0) {
*value = 0xffffffff; value = 0xffffffff;
return 1; goto done;
} }
*value = readl(address); value = readl(address);
/* fixup root port class */ /* fixup root port class */
if (PCI_BUS(bdf) == 0) { if (PCI_BUS(bdf) == 0) {
if (where == PCI_CLASS_REVISION) { if (offset == PCI_CLASS_REVISION) {
*value &= ~0x00ff0000; value &= ~0x00ff0000;
*value |= PCI_CLASS_BRIDGE_PCI << 16; value |= PCI_CLASS_BRIDGE_PCI << 16;
} }
} }
done:
*valuep = pci_conv_32_to_size(value, offset, size);
return 0; return 0;
} }
static int tegra_pcie_write_conf(struct pci_controller *hose, pci_dev_t bdf, static int pci_tegra_write_config(struct udevice *bus, pci_dev_t bdf,
int where, u32 value) uint offset, ulong value,
enum pci_size_t size)
{ {
struct tegra_pcie *pcie = to_tegra_pcie(hose); struct tegra_pcie *pcie = dev_get_priv(bus);
unsigned long address; unsigned long address;
ulong old;
int err; int err;
err = tegra_pcie_conf_address(pcie, bdf, where, &address); err = tegra_pcie_conf_address(pcie, bdf, offset, &address);
if (err < 0) if (err < 0)
return 1; return 0;
old = readl(address);
value = pci_conv_size_to_32(old, value, offset, size);
writel(value, address); writel(value, address);
return 0; return 0;
@ -348,12 +352,10 @@ static int tegra_pcie_port_parse_dt(const void *fdt, int node,
} }
static int tegra_pcie_get_xbar_config(const void *fdt, int node, u32 lanes, static int tegra_pcie_get_xbar_config(const void *fdt, int node, u32 lanes,
unsigned long *xbar) enum tegra_pci_id id, unsigned long *xbar)
{ {
enum fdt_compat_id id = fdtdec_lookup(fdt, node);
switch (id) { switch (id) {
case COMPAT_NVIDIA_TEGRA20_PCIE: case TEGRA20_PCIE:
switch (lanes) { switch (lanes) {
case 0x00000004: case 0x00000004:
debug("single-mode configuration\n"); debug("single-mode configuration\n");
@ -366,8 +368,7 @@ static int tegra_pcie_get_xbar_config(const void *fdt, int node, u32 lanes,
return 0; return 0;
} }
break; break;
case TEGRA30_PCIE:
case COMPAT_NVIDIA_TEGRA30_PCIE:
switch (lanes) { switch (lanes) {
case 0x00000204: case 0x00000204:
debug("4x1, 2x1 configuration\n"); debug("4x1, 2x1 configuration\n");
@ -385,9 +386,8 @@ static int tegra_pcie_get_xbar_config(const void *fdt, int node, u32 lanes,
return 0; return 0;
} }
break; break;
case TEGRA124_PCIE:
case COMPAT_NVIDIA_TEGRA124_PCIE: case TEGRA210_PCIE:
case COMPAT_NVIDIA_TEGRA210_PCIE:
switch (lanes) { switch (lanes) {
case 0x0000104: case 0x0000104:
debug("4x1, 1x1 configuration\n"); debug("4x1, 1x1 configuration\n");
@ -400,7 +400,6 @@ static int tegra_pcie_get_xbar_config(const void *fdt, int node, u32 lanes,
return 0; return 0;
} }
break; break;
default: default:
break; break;
} }
@ -408,84 +407,6 @@ static int tegra_pcie_get_xbar_config(const void *fdt, int node, u32 lanes,
return -FDT_ERR_NOTFOUND; return -FDT_ERR_NOTFOUND;
} }
static int tegra_pcie_parse_dt_ranges(const void *fdt, int node,
struct tegra_pcie *pcie)
{
int parent, na_parent, na_pcie, ns_pcie;
const u32 *ptr, *end;
int len;
parent = fdt_parent_offset(fdt, node);
if (parent < 0) {
error("Can't find PCI parent node\n");
return -FDT_ERR_NOTFOUND;
}
na_parent = fdt_address_cells(fdt, parent);
if (na_parent < 1) {
error("bad #address-cells for PCIE parent\n");
return -FDT_ERR_NOTFOUND;
}
na_pcie = fdt_address_cells(fdt, node);
if (na_pcie < 1) {
error("bad #address-cells for PCIE\n");
return -FDT_ERR_NOTFOUND;
}
ns_pcie = fdt_size_cells(fdt, node);
if (ns_pcie < 1) {
error("bad #size-cells for PCIE\n");
return -FDT_ERR_NOTFOUND;
}
ptr = fdt_getprop(fdt, node, "ranges", &len);
if (!ptr) {
error("missing \"ranges\" property");
return -FDT_ERR_NOTFOUND;
}
end = ptr + len / 4;
while (ptr < end) {
struct fdt_resource *res = NULL;
u32 space = fdt32_to_cpu(*ptr);
switch ((space >> 24) & 0x3) {
case 0x01:
res = &pcie->io;
break;
case 0x02: /* 32 bit */
case 0x03: /* 64 bit */
if (space & (1 << 30))
res = &pcie->prefetch;
else
res = &pcie->mem;
break;
}
if (res) {
int start_low = na_pcie + (na_parent - 1);
int size_low = na_pcie + na_parent + (ns_pcie - 1);
res->start = fdt32_to_cpu(ptr[start_low]);
res->end = res->start + fdt32_to_cpu(ptr[size_low]);
}
ptr += na_pcie + na_parent + ns_pcie;
}
debug("PCI regions:\n");
debug(" I/O: %pa-%pa\n", &pcie->io.start, &pcie->io.end);
debug(" non-prefetchable memory: %pa-%pa\n", &pcie->mem.start,
&pcie->mem.end);
debug(" prefetchable memory: %pa-%pa\n", &pcie->prefetch.start,
&pcie->prefetch.end);
return 0;
}
static int tegra_pcie_parse_port_info(const void *fdt, int node, static int tegra_pcie_parse_port_info(const void *fdt, int node,
unsigned int *index, unsigned int *index,
unsigned int *lanes) unsigned int *lanes)
@ -512,7 +433,12 @@ static int tegra_pcie_parse_port_info(const void *fdt, int node,
return 0; return 0;
} }
static int tegra_pcie_parse_dt(const void *fdt, int node, int __weak tegra_pcie_board_init(void)
{
return 0;
}
static int tegra_pcie_parse_dt(const void *fdt, int node, enum tegra_pci_id id,
struct tegra_pcie *pcie) struct tegra_pcie *pcie)
{ {
int err, subnode; int err, subnode;
@ -539,6 +465,8 @@ static int tegra_pcie_parse_dt(const void *fdt, int node,
return err; return err;
} }
tegra_pcie_board_init();
pcie->phy = tegra_xusb_phy_get(TEGRA_XUSB_PADCTL_PCIE); pcie->phy = tegra_xusb_phy_get(TEGRA_XUSB_PADCTL_PCIE);
if (pcie->phy) { if (pcie->phy) {
err = tegra_xusb_phy_prepare(pcie->phy); err = tegra_xusb_phy_prepare(pcie->phy);
@ -548,12 +476,6 @@ static int tegra_pcie_parse_dt(const void *fdt, int node,
} }
} }
err = tegra_pcie_parse_dt_ranges(fdt, node, pcie);
if (err < 0) {
error("failed to parse \"ranges\" property");
return err;
}
fdt_for_each_subnode(fdt, subnode, node) { fdt_for_each_subnode(fdt, subnode, node) {
unsigned int index = 0, num_lanes = 0; unsigned int index = 0, num_lanes = 0;
struct tegra_pcie_port *port; struct tegra_pcie_port *port;
@ -588,7 +510,7 @@ static int tegra_pcie_parse_dt(const void *fdt, int node,
port->pcie = pcie; port->pcie = pcie;
} }
err = tegra_pcie_get_xbar_config(fdt, node, lanes, &pcie->xbar); err = tegra_pcie_get_xbar_config(fdt, node, lanes, id, &pcie->xbar);
if (err < 0) { if (err < 0) {
error("invalid lane configuration"); error("invalid lane configuration");
return err; return err;
@ -597,11 +519,6 @@ static int tegra_pcie_parse_dt(const void *fdt, int node,
return 0; return 0;
} }
int __weak tegra_pcie_board_init(void)
{
return 0;
}
static int tegra_pcie_power_on(struct tegra_pcie *pcie) static int tegra_pcie_power_on(struct tegra_pcie *pcie)
{ {
const struct tegra_pcie_soc *soc = pcie->soc; const struct tegra_pcie_soc *soc = pcie->soc;
@ -788,9 +705,12 @@ static int tegra_pcie_enable_controller(struct tegra_pcie *pcie)
return 0; return 0;
} }
static void tegra_pcie_setup_translations(struct tegra_pcie *pcie) static int tegra_pcie_setup_translations(struct udevice *bus)
{ {
struct tegra_pcie *pcie = dev_get_priv(bus);
unsigned long fpci, axi, size; unsigned long fpci, axi, size;
struct pci_region *io, *mem, *pref;
int count;
/* BAR 0: type 1 extended configuration space */ /* BAR 0: type 1 extended configuration space */
fpci = 0xfe100000; fpci = 0xfe100000;
@ -801,28 +721,32 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ); afi_writel(pcie, size >> 12, AFI_AXI_BAR0_SZ);
afi_writel(pcie, fpci, AFI_FPCI_BAR0); afi_writel(pcie, fpci, AFI_FPCI_BAR0);
count = pci_get_regions(bus, &io, &mem, &pref);
if (count != 3)
return -EINVAL;
/* BAR 1: downstream I/O */ /* BAR 1: downstream I/O */
fpci = 0xfdfc0000; fpci = 0xfdfc0000;
size = fdt_resource_size(&pcie->io); size = io->size;
axi = pcie->io.start; axi = io->phys_start;
afi_writel(pcie, axi, AFI_AXI_BAR1_START); afi_writel(pcie, axi, AFI_AXI_BAR1_START);
afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ); afi_writel(pcie, size >> 12, AFI_AXI_BAR1_SZ);
afi_writel(pcie, fpci, AFI_FPCI_BAR1); afi_writel(pcie, fpci, AFI_FPCI_BAR1);
/* BAR 2: prefetchable memory */ /* BAR 2: prefetchable memory */
fpci = (((pcie->prefetch.start >> 12) & 0x0fffffff) << 4) | 0x1; fpci = (((pref->phys_start >> 12) & 0x0fffffff) << 4) | 0x1;
size = fdt_resource_size(&pcie->prefetch); size = pref->size;
axi = pcie->prefetch.start; axi = pref->phys_start;
afi_writel(pcie, axi, AFI_AXI_BAR2_START); afi_writel(pcie, axi, AFI_AXI_BAR2_START);
afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ); afi_writel(pcie, size >> 12, AFI_AXI_BAR2_SZ);
afi_writel(pcie, fpci, AFI_FPCI_BAR2); afi_writel(pcie, fpci, AFI_FPCI_BAR2);
/* BAR 3: non-prefetchable memory */ /* BAR 3: non-prefetchable memory */
fpci = (((pcie->mem.start >> 12) & 0x0fffffff) << 4) | 0x1; fpci = (((mem->phys_start >> 12) & 0x0fffffff) << 4) | 0x1;
size = fdt_resource_size(&pcie->mem); size = mem->size;
axi = pcie->mem.start; axi = mem->phys_start;
afi_writel(pcie, axi, AFI_AXI_BAR3_START); afi_writel(pcie, axi, AFI_AXI_BAR3_START);
afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ); afi_writel(pcie, size >> 12, AFI_AXI_BAR3_SZ);
@ -848,6 +772,8 @@ static void tegra_pcie_setup_translations(struct tegra_pcie *pcie)
afi_writel(pcie, 0, AFI_MSI_BAR_SZ); afi_writel(pcie, 0, AFI_MSI_BAR_SZ);
afi_writel(pcie, 0, AFI_MSI_AXI_BAR_ST); afi_writel(pcie, 0, AFI_MSI_AXI_BAR_ST);
afi_writel(pcie, 0, AFI_MSI_BAR_SZ); afi_writel(pcie, 0, AFI_MSI_BAR_SZ);
return 0;
} }
static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port) static unsigned long tegra_pcie_port_get_pex_ctrl(struct tegra_pcie_port *port)
@ -1001,209 +927,116 @@ static int tegra_pcie_enable(struct tegra_pcie *pcie)
return 0; return 0;
} }
static const struct tegra_pcie_soc tegra20_pcie_soc = { static const struct tegra_pcie_soc pci_tegra_soc[] = {
.num_ports = 2, [TEGRA20_PCIE] = {
.pads_pll_ctl = PADS_PLL_CTL_TEGRA20, .num_ports = 2,
.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_DIV10, .pads_pll_ctl = PADS_PLL_CTL_TEGRA20,
.has_pex_clkreq_en = false, .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_DIV10,
.has_pex_bias_ctrl = false, .has_pex_clkreq_en = false,
.has_cml_clk = false, .has_pex_bias_ctrl = false,
.has_gen2 = false, .has_cml_clk = false,
.force_pca_enable = false, .has_gen2 = false,
}; },
[TEGRA30_PCIE] = {
static const struct tegra_pcie_soc tegra30_pcie_soc = { .num_ports = 3,
.num_ports = 3, .pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
.pads_pll_ctl = PADS_PLL_CTL_TEGRA30, .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, .has_pex_clkreq_en = true,
.has_pex_clkreq_en = true, .has_pex_bias_ctrl = true,
.has_pex_bias_ctrl = true, .has_cml_clk = true,
.has_cml_clk = true, .has_gen2 = false,
.has_gen2 = false, },
.force_pca_enable = false, [TEGRA124_PCIE] = {
}; .num_ports = 2,
.pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
static const struct tegra_pcie_soc tegra124_pcie_soc = { .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
.num_ports = 2, .has_pex_clkreq_en = true,
.pads_pll_ctl = PADS_PLL_CTL_TEGRA30, .has_pex_bias_ctrl = true,
.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, .has_cml_clk = true,
.has_pex_clkreq_en = true, .has_gen2 = true,
.has_pex_bias_ctrl = true, },
.has_cml_clk = true, [TEGRA210_PCIE] = {
.has_gen2 = true, .num_ports = 2,
.force_pca_enable = false, .pads_pll_ctl = PADS_PLL_CTL_TEGRA30,
}; .tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN,
.has_pex_clkreq_en = true,
static const struct tegra_pcie_soc tegra210_pcie_soc = { .has_pex_bias_ctrl = true,
.num_ports = 2, .has_cml_clk = true,
.pads_pll_ctl = PADS_PLL_CTL_TEGRA30, .has_gen2 = true,
.tx_ref_sel = PADS_PLL_CTL_TXCLKREF_BUF_EN, .force_pca_enable = true,
.has_pex_clkreq_en = true, }
.has_pex_bias_ctrl = true,
.has_cml_clk = true,
.has_gen2 = true,
.force_pca_enable = true,
}; };
static int process_nodes(const void *fdt, int nodes[], unsigned int count) static int pci_tegra_ofdata_to_platdata(struct udevice *dev)
{ {
unsigned int i; struct tegra_pcie *pcie = dev_get_priv(dev);
uint64_t dram_end; enum tegra_pci_id id;
uint32_t pci_dram_size;
/* Clip PCI-accessible DRAM to 32-bits */
dram_end = ((uint64_t)NV_PA_SDRAM_BASE) + gd->ram_size;
if (dram_end > 0x100000000)
dram_end = 0x100000000;
pci_dram_size = dram_end - NV_PA_SDRAM_BASE;
for (i = 0; i < count; i++) {
const struct tegra_pcie_soc *soc;
struct tegra_pcie *pcie;
enum fdt_compat_id id;
int err;
if (!fdtdec_get_is_enabled(fdt, nodes[i]))
continue;
id = fdtdec_lookup(fdt, nodes[i]);
switch (id) {
case COMPAT_NVIDIA_TEGRA20_PCIE:
soc = &tegra20_pcie_soc;
break;
case COMPAT_NVIDIA_TEGRA30_PCIE:
soc = &tegra30_pcie_soc;
break;
case COMPAT_NVIDIA_TEGRA124_PCIE:
soc = &tegra124_pcie_soc;
break;
case COMPAT_NVIDIA_TEGRA210_PCIE:
soc = &tegra210_pcie_soc;
break;
default:
error("unsupported compatible: %s",
fdtdec_get_compatible(id));
continue;
}
pcie = malloc(sizeof(*pcie));
if (!pcie) {
error("failed to allocate controller");
continue;
}
memset(pcie, 0, sizeof(*pcie));
pcie->soc = soc;
INIT_LIST_HEAD(&pcie->ports);
err = tegra_pcie_parse_dt(fdt, nodes[i], pcie);
if (err < 0) {
free(pcie);
continue;
}
err = tegra_pcie_power_on(pcie);
if (err < 0) {
error("failed to power on");
continue;
}
err = tegra_pcie_enable_controller(pcie); id = dev_get_driver_data(dev);
if (err < 0) { pcie->soc = &pci_tegra_soc[id];
error("failed to enable controller");
continue;
}
tegra_pcie_setup_translations(pcie);
err = tegra_pcie_enable(pcie);
if (err < 0) {
error("failed to enable PCIe");
continue;
}
pcie->hose.first_busno = 0; INIT_LIST_HEAD(&pcie->ports);
pcie->hose.current_busno = 0;
pcie->hose.last_busno = 0;
pci_set_region(&pcie->hose.regions[0], NV_PA_SDRAM_BASE, if (tegra_pcie_parse_dt(gd->fdt_blob, dev->of_offset, id, pcie))
NV_PA_SDRAM_BASE, pci_dram_size, return -EINVAL;
PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
pci_set_region(&pcie->hose.regions[1], pcie->io.start, return 0;
pcie->io.start, fdt_resource_size(&pcie->io), }
PCI_REGION_IO);
pci_set_region(&pcie->hose.regions[2], pcie->mem.start,
pcie->mem.start, fdt_resource_size(&pcie->mem),
PCI_REGION_MEM);
pci_set_region(&pcie->hose.regions[3], pcie->prefetch.start,
pcie->prefetch.start,
fdt_resource_size(&pcie->prefetch),
PCI_REGION_MEM | PCI_REGION_PREFETCH);
pcie->hose.region_count = 4; static int pci_tegra_probe(struct udevice *dev)
{
struct tegra_pcie *pcie = dev_get_priv(dev);
int err;
pci_set_ops(&pcie->hose, err = tegra_pcie_power_on(pcie);
pci_hose_read_config_byte_via_dword, if (err < 0) {
pci_hose_read_config_word_via_dword, error("failed to power on");
tegra_pcie_read_conf, return err;
pci_hose_write_config_byte_via_dword, }
pci_hose_write_config_word_via_dword,
tegra_pcie_write_conf);
pci_register_hose(&pcie->hose); err = tegra_pcie_enable_controller(pcie);
if (err < 0) {
error("failed to enable controller");
return err;
}
#ifdef CONFIG_PCI_SCAN_SHOW err = tegra_pcie_setup_translations(dev);
printf("PCI: Enumerating devices...\n"); if (err < 0) {
printf("---------------------------------------\n"); error("failed to decode ranges");
printf(" Device ID Description\n"); return err;
printf(" ------ -- -----------\n"); }
#endif
pcie->hose.last_busno = pci_hose_scan(&pcie->hose); err = tegra_pcie_enable(pcie);
if (err < 0) {
error("failed to enable PCIe");
return err;
} }
return 0; return 0;
} }
void pci_init_board(void) static const struct dm_pci_ops pci_tegra_ops = {
{ .read_config = pci_tegra_read_config,
const void *fdt = gd->fdt_blob; .write_config = pci_tegra_write_config,
int count, nodes[1]; };
tegra_pcie_board_init(); static const struct udevice_id pci_tegra_ids[] = {
{ .compatible = "nvidia,tegra20-pcie", .data = TEGRA20_PCIE },
{ .compatible = "nvidia,tegra30-pcie", .data = TEGRA30_PCIE },
{ .compatible = "nvidia,tegra124-pcie", .data = TEGRA124_PCIE },
{ .compatible = "nvidia,tegra210-pcie", .data = TEGRA210_PCIE },
{ }
};
count = fdtdec_find_aliases_for_id(fdt, "pcie-controller", U_BOOT_DRIVER(pci_tegra) = {
COMPAT_NVIDIA_TEGRA210_PCIE, .name = "pci_tegra",
nodes, ARRAY_SIZE(nodes)); .id = UCLASS_PCI,
if (process_nodes(fdt, nodes, count)) .of_match = pci_tegra_ids,
return; .ops = &pci_tegra_ops,
.ofdata_to_platdata = pci_tegra_ofdata_to_platdata,
count = fdtdec_find_aliases_for_id(fdt, "pcie-controller", .probe = pci_tegra_probe,
COMPAT_NVIDIA_TEGRA124_PCIE, .priv_auto_alloc_size = sizeof(struct tegra_pcie),
nodes, ARRAY_SIZE(nodes)); };
if (process_nodes(fdt, nodes, count))
return;
count = fdtdec_find_aliases_for_id(fdt, "pcie-controller",
COMPAT_NVIDIA_TEGRA30_PCIE,
nodes, ARRAY_SIZE(nodes));
if (process_nodes(fdt, nodes, count))
return;
count = fdtdec_find_aliases_for_id(fdt, "pcie-controller",
COMPAT_NVIDIA_TEGRA20_PCIE,
nodes, ARRAY_SIZE(nodes));
if (process_nodes(fdt, nodes, count))
return;
}
int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev) int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
{ {

@ -128,10 +128,6 @@ enum fdt_compat_id {
COMPAT_NVIDIA_TEGRA124_SDMMC, /* Tegra124 SDMMC controller */ COMPAT_NVIDIA_TEGRA124_SDMMC, /* Tegra124 SDMMC controller */
COMPAT_NVIDIA_TEGRA30_SDMMC, /* Tegra30 SDMMC controller */ COMPAT_NVIDIA_TEGRA30_SDMMC, /* Tegra30 SDMMC controller */
COMPAT_NVIDIA_TEGRA20_SDMMC, /* Tegra20 SDMMC controller */ COMPAT_NVIDIA_TEGRA20_SDMMC, /* Tegra20 SDMMC controller */
COMPAT_NVIDIA_TEGRA124_PCIE, /* Tegra 124 PCIe controller */
COMPAT_NVIDIA_TEGRA210_PCIE, /* Tegra 210 PCIe controller */
COMPAT_NVIDIA_TEGRA30_PCIE, /* Tegra 30 PCIe controller */
COMPAT_NVIDIA_TEGRA20_PCIE, /* Tegra 20 PCIe controller */
COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL, COMPAT_NVIDIA_TEGRA124_XUSB_PADCTL,
/* Tegra124 XUSB pad controller */ /* Tegra124 XUSB pad controller */
COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL, COMPAT_NVIDIA_TEGRA210_XUSB_PADCTL,

@ -34,10 +34,6 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(NVIDIA_TEGRA124_SDMMC, "nvidia,tegra124-sdhci"), COMPAT(NVIDIA_TEGRA124_SDMMC, "nvidia,tegra124-sdhci"),
COMPAT(NVIDIA_TEGRA30_SDMMC, "nvidia,tegra30-sdhci"), COMPAT(NVIDIA_TEGRA30_SDMMC, "nvidia,tegra30-sdhci"),
COMPAT(NVIDIA_TEGRA20_SDMMC, "nvidia,tegra20-sdhci"), COMPAT(NVIDIA_TEGRA20_SDMMC, "nvidia,tegra20-sdhci"),
COMPAT(NVIDIA_TEGRA124_PCIE, "nvidia,tegra124-pcie"),
COMPAT(NVIDIA_TEGRA210_PCIE, "nvidia,tegra210-pcie"),
COMPAT(NVIDIA_TEGRA30_PCIE, "nvidia,tegra30-pcie"),
COMPAT(NVIDIA_TEGRA20_PCIE, "nvidia,tegra20-pcie"),
COMPAT(NVIDIA_TEGRA124_XUSB_PADCTL, "nvidia,tegra124-xusb-padctl"), COMPAT(NVIDIA_TEGRA124_XUSB_PADCTL, "nvidia,tegra124-xusb-padctl"),
COMPAT(NVIDIA_TEGRA210_XUSB_PADCTL, "nvidia,tegra210-xusb-padctl"), COMPAT(NVIDIA_TEGRA210_XUSB_PADCTL, "nvidia,tegra210-xusb-padctl"),
COMPAT(SMSC_LAN9215, "smsc,lan9215"), COMPAT(SMSC_LAN9215, "smsc,lan9215"),

Loading…
Cancel
Save