dm: tegra: pci: Convert to livetree

Update the tegra pci driver to support a live device tree. Fix the check
for nvidia,num-lanes so that an error will actually be detected.

Tested-by: Marcel Ziswiler <marcel.ziswiler@toradex.com>
Tested-on: Beaver, Jetson-TK1
Signed-off-by: Simon Glass <sjg@chromium.org>
Tested-by: Stephen Warren <swarren@nvidia.com>
master
Simon Glass 7 years ago
parent 49cb9308c4
commit 68f0081139
  1. 53
      drivers/pci/pci_tegra.c

@ -16,7 +16,6 @@
#include <clk.h> #include <clk.h>
#include <dm.h> #include <dm.h>
#include <errno.h> #include <errno.h>
#include <fdtdec.h>
#include <malloc.h> #include <malloc.h>
#include <pci.h> #include <pci.h>
#include <power-domain.h> #include <power-domain.h>
@ -25,6 +24,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/gpio.h> #include <asm/gpio.h>
#include <linux/ioport.h>
#include <linux/list.h> #include <linux/list.h>
#ifndef CONFIG_TEGRA186 #ifndef CONFIG_TEGRA186
@ -220,9 +220,9 @@ struct tegra_pcie_soc {
struct tegra_pcie { struct tegra_pcie {
struct pci_controller hose; struct pci_controller hose;
struct fdt_resource pads; struct resource pads;
struct fdt_resource afi; struct resource afi;
struct fdt_resource cs; struct resource cs;
struct list_head ports; struct list_head ports;
unsigned long xbar; unsigned long xbar;
@ -364,13 +364,12 @@ static int pci_tegra_write_config(struct udevice *bus, pci_dev_t bdf,
return 0; return 0;
} }
static int tegra_pcie_port_parse_dt(const void *fdt, int node, static int tegra_pcie_port_parse_dt(ofnode node, struct tegra_pcie_port *port)
struct tegra_pcie_port *port)
{ {
const u32 *addr; const u32 *addr;
int len; int len;
addr = fdt_getprop(fdt, node, "assigned-addresses", &len); addr = ofnode_get_property(node, "assigned-addresses", &len);
if (!addr) { if (!addr) {
error("property \"assigned-addresses\" not found"); error("property \"assigned-addresses\" not found");
return -FDT_ERR_NOTFOUND; return -FDT_ERR_NOTFOUND;
@ -382,7 +381,7 @@ static int tegra_pcie_port_parse_dt(const void *fdt, int node,
return 0; return 0;
} }
static int tegra_pcie_get_xbar_config(const void *fdt, int node, u32 lanes, static int tegra_pcie_get_xbar_config(ofnode node, u32 lanes,
enum tegra_pci_id id, unsigned long *xbar) enum tegra_pci_id id, unsigned long *xbar)
{ {
switch (id) { switch (id) {
@ -456,14 +455,12 @@ 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_port_info(const void *fdt, int node, static int tegra_pcie_parse_port_info(ofnode node, uint *index, uint *lanes)
unsigned int *index,
unsigned int *lanes)
{ {
struct fdt_pci_addr addr; struct fdt_pci_addr addr;
int err; int err;
err = fdtdec_get_int(fdt, node, "nvidia,num-lanes", 0); err = ofnode_read_u32_default(node, "nvidia,num-lanes", -1);
if (err < 0) { if (err < 0) {
error("failed to parse \"nvidia,num-lanes\" property"); error("failed to parse \"nvidia,num-lanes\" property");
return err; return err;
@ -471,7 +468,7 @@ static int tegra_pcie_parse_port_info(const void *fdt, int node,
*lanes = err; *lanes = err;
err = fdtdec_get_pci_addr(fdt, node, 0, "reg", &addr); err = ofnode_read_pci_addr(node, 0, "reg", &addr);
if (err < 0) { if (err < 0) {
error("failed to parse \"reg\" property"); error("failed to parse \"reg\" property");
return err; return err;
@ -487,28 +484,26 @@ int __weak tegra_pcie_board_init(void)
return 0; return 0;
} }
static int tegra_pcie_parse_dt(const void *fdt, int node, enum tegra_pci_id id, static int tegra_pcie_parse_dt(struct udevice *dev, enum tegra_pci_id id,
struct tegra_pcie *pcie) struct tegra_pcie *pcie)
{ {
int err, subnode; ofnode subnode;
u32 lanes = 0; u32 lanes = 0;
int err;
err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "pads", err = dev_read_resource(dev, 0, &pcie->pads);
&pcie->pads);
if (err < 0) { if (err < 0) {
error("resource \"pads\" not found"); error("resource \"pads\" not found");
return err; return err;
} }
err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "afi", err = dev_read_resource(dev, 1, &pcie->afi);
&pcie->afi);
if (err < 0) { if (err < 0) {
error("resource \"afi\" not found"); error("resource \"afi\" not found");
return err; return err;
} }
err = fdt_get_named_resource(fdt, node, "reg", "reg-names", "cs", err = dev_read_resource(dev, 2, &pcie->cs);
&pcie->cs);
if (err < 0) { if (err < 0) {
error("resource \"cs\" not found"); error("resource \"cs\" not found");
return err; return err;
@ -531,12 +526,11 @@ static int tegra_pcie_parse_dt(const void *fdt, int node, enum tegra_pci_id id,
} }
#endif #endif
fdt_for_each_subnode(subnode, fdt, node) { dev_for_each_subnode(subnode, dev) {
unsigned int index = 0, num_lanes = 0; unsigned int index = 0, num_lanes = 0;
struct tegra_pcie_port *port; struct tegra_pcie_port *port;
err = tegra_pcie_parse_port_info(fdt, subnode, &index, err = tegra_pcie_parse_port_info(subnode, &index, &num_lanes);
&num_lanes);
if (err < 0) { if (err < 0) {
error("failed to obtain root port info"); error("failed to obtain root port info");
continue; continue;
@ -544,7 +538,7 @@ static int tegra_pcie_parse_dt(const void *fdt, int node, enum tegra_pci_id id,
lanes |= num_lanes << (index << 3); lanes |= num_lanes << (index << 3);
if (!fdtdec_get_is_enabled(fdt, subnode)) if (!ofnode_is_available(subnode))
continue; continue;
port = malloc(sizeof(*port)); port = malloc(sizeof(*port));
@ -555,7 +549,7 @@ static int tegra_pcie_parse_dt(const void *fdt, int node, enum tegra_pci_id id,
port->num_lanes = num_lanes; port->num_lanes = num_lanes;
port->index = index; port->index = index;
err = tegra_pcie_port_parse_dt(fdt, subnode, port); err = tegra_pcie_port_parse_dt(subnode, port);
if (err < 0) { if (err < 0) {
free(port); free(port);
continue; continue;
@ -565,7 +559,8 @@ static int tegra_pcie_parse_dt(const void *fdt, int node, enum tegra_pci_id id,
port->pcie = pcie; port->pcie = pcie;
} }
err = tegra_pcie_get_xbar_config(fdt, node, lanes, id, &pcie->xbar); err = tegra_pcie_get_xbar_config(dev_ofnode(dev), lanes, id,
&pcie->xbar);
if (err < 0) { if (err < 0) {
error("invalid lane configuration"); error("invalid lane configuration");
return err; return err;
@ -815,7 +810,7 @@ static int tegra_pcie_setup_translations(struct udevice *bus)
/* BAR 0: type 1 extended configuration space */ /* BAR 0: type 1 extended configuration space */
fpci = 0xfe100000; fpci = 0xfe100000;
size = fdt_resource_size(&pcie->cs); size = resource_size(&pcie->cs);
axi = pcie->cs.start; axi = pcie->cs.start;
afi_writel(pcie, axi, AFI_AXI_BAR0_START); afi_writel(pcie, axi, AFI_AXI_BAR0_START);
@ -1099,7 +1094,7 @@ static int pci_tegra_ofdata_to_platdata(struct udevice *dev)
INIT_LIST_HEAD(&pcie->ports); INIT_LIST_HEAD(&pcie->ports);
if (tegra_pcie_parse_dt(gd->fdt_blob, dev_of_offset(dev), id, pcie)) if (tegra_pcie_parse_dt(dev, id, pcie))
return -EINVAL; return -EINVAL;
return 0; return 0;

Loading…
Cancel
Save