[U-Boot] Device tree & PCI/ECAM questions

Hi all,
I am working on several drivers for our Octeon-TX/Thunder chips which talk to devices connected to the ECAM bus through another sub-bus and am having issues regarding the device tree.
We have a "PCI" driver to handle the ECAM and I created a simple-bus stub for our MRML bus which connects low-speed devices to the ECAM bus and all of the devices show up in the device tree.
My problem is that the devices also enumerated via PCI.
I have something like the following:
static int cavium_pci_mmc_probe(struct udevice *dev) { debug("%s: Entry\n", __func__); pci_dev_t bdf = dm_pci_get_bdf(dev); struct cavium_mmc_host *host = dev_get_priv(dev); size_t size; uint64_t base_addr = dm_pci_map_bar(dev, 0, &size, PCI_REGION_MEM); int rc = 0;
host->base_addr = base_addr; dev->req_seq = PCI_FUNC(bdf);
debug("%s(%s): ", __func__, dev->name); debug(" platdata: %p\n" " parent platdata: %p\n" " uclass platdata: %p\n" " base address: %lx\n" " of_offset: %d\n" " parent: %p\n" " priv: %p\n" " uclass: %p\n" " req_seq: %d\n" " seq: %d\n", dev->platdata, dev->parent_platdata, dev->uclass_platdata, base_addr, dev->of_offset, dev->parent, dev->priv, dev->uclass, dev->req_seq, dev->seq);
if (dev->of_offset >= 0) rc = process_node(dev, gd->fdt_blob, dev->of_offset);
return rc; }
static const struct udevice_id cavium_mmc_ids[] = { { .compatible = "cavium,thunder-8890-mmc" }, { .compatible = "cavium,mmc" }, { }, };
static const struct udevice_id cavium_mmc_slot_ids[] = { { .compatible = "cavium,thunder-8890-mmc-slot" }, { }, };
U_BOOT_DRIVER(cavium_pci_mmc) = { .name = "mmc_cavium", .id = UCLASS_MMC, .of_match = of_match_ptr(cavium_mmc_ids), .ofdata_to_platdata = cavium_mmc_ofdata_to_platdata, .probe = cavium_pci_mmc_probe, .priv_auto_alloc_size = sizeof(struct cavium_mmc_host), .ops = NULL, };
static struct pci_device_id cavium_pci_mmc_supported[] = { { PCI_VDEVICE(CAVIUM, PCI_DEVICE_ID_THUNDER_MMC) }, {}, };
U_BOOT_PCI_DEVICE(cavium_pci_mmc, cavium_pci_mmc_supported);
The problem I'm seeing is that in the probe function the of_offset field is always -1. Shouldn't it resolve this information via the compatible string in the device tree? How should I go about setting it up so that not only things like the base address get resolved but also the of_offset field since all of the slot configuration comes from the device tree.
In our case we have a single MMC device on the MRML bus connected to the ECAM bus (which looks like a PCI bus) which supports multiple slots with one set of registers.
-Aaron

On Tue, Nov 1, 2016 at 6:49 AM, Aaron Williams Aaron.Williams@caviumnetworks.com wrote:
Hi all,
I am working on several drivers for our Octeon-TX/Thunder chips which talk to devices connected to the ECAM bus through another sub-bus and am having issues regarding the device tree.
We have a "PCI" driver to handle the ECAM and I created a simple-bus stub for our MRML bus which connects low-speed devices to the ECAM bus and all of the devices show up in the device tree.
My problem is that the devices also enumerated via PCI.
I have something like the following:
static int cavium_pci_mmc_probe(struct udevice *dev) { debug("%s: Entry\n", __func__); pci_dev_t bdf = dm_pci_get_bdf(dev); struct cavium_mmc_host *host = dev_get_priv(dev); size_t size; uint64_t base_addr = dm_pci_map_bar(dev, 0, &size, PCI_REGION_MEM); int rc = 0;
host->base_addr = base_addr; dev->req_seq = PCI_FUNC(bdf); debug("%s(%s): ", __func__, dev->name); debug(" platdata: %p\n" " parent platdata: %p\n" " uclass platdata: %p\n" " base address: %lx\n" " of_offset: %d\n" " parent: %p\n" " priv: %p\n" " uclass: %p\n" " req_seq: %d\n" " seq: %d\n", dev->platdata, dev->parent_platdata, dev->uclass_platdata, base_addr, dev->of_offset, dev->parent, dev->priv, dev->uclass, dev->req_seq, dev->seq); if (dev->of_offset >= 0) rc = process_node(dev, gd->fdt_blob, dev->of_offset); return rc;
}
static const struct udevice_id cavium_mmc_ids[] = { { .compatible = "cavium,thunder-8890-mmc" }, { .compatible = "cavium,mmc" }, { }, };
static const struct udevice_id cavium_mmc_slot_ids[] = { { .compatible = "cavium,thunder-8890-mmc-slot" }, { }, };
U_BOOT_DRIVER(cavium_pci_mmc) = { .name = "mmc_cavium", .id = UCLASS_MMC, .of_match = of_match_ptr(cavium_mmc_ids), .ofdata_to_platdata = cavium_mmc_ofdata_to_platdata, .probe = cavium_pci_mmc_probe, .priv_auto_alloc_size = sizeof(struct cavium_mmc_host), .ops = NULL, };
static struct pci_device_id cavium_pci_mmc_supported[] = { { PCI_VDEVICE(CAVIUM, PCI_DEVICE_ID_THUNDER_MMC) }, {}, };
U_BOOT_PCI_DEVICE(cavium_pci_mmc, cavium_pci_mmc_supported);
I think you're not using dt?
The problem I'm seeing is that in the probe function the of_offset field is always -1. Shouldn't it resolve this information via the compatible string in the device tree? How should I go about setting it up so that not only
This look strange to me, but I am assuming PCI dev hierarchy may require u-boot,dm-pre-reloc on dt have you tried .flags = DM_FLAG_PRE_RELOC?
thanks!

Hi Jagen,
On 11/01/2016 11:33 AM, Jagan Teki wrote:
On Tue, Nov 1, 2016 at 6:49 AM, Aaron Williams Aaron.Williams@caviumnetworks.com wrote:
Hi all,
I am working on several drivers for our Octeon-TX/Thunder chips which talk to devices connected to the ECAM bus through another sub-bus and am having issues regarding the device tree.
We have a "PCI" driver to handle the ECAM and I created a simple-bus stub for our MRML bus which connects low-speed devices to the ECAM bus and all of the devices show up in the device tree.
My problem is that the devices also enumerated via PCI.
I have something like the following:
static int cavium_pci_mmc_probe(struct udevice *dev) { debug("%s: Entry\n", __func__); pci_dev_t bdf = dm_pci_get_bdf(dev); struct cavium_mmc_host *host = dev_get_priv(dev); size_t size; uint64_t base_addr = dm_pci_map_bar(dev, 0, &size, PCI_REGION_MEM); int rc = 0;
host->base_addr = base_addr; dev->req_seq = PCI_FUNC(bdf); debug("%s(%s): ", __func__, dev->name); debug(" platdata: %p\n" " parent platdata: %p\n" " uclass platdata: %p\n" " base address: %lx\n" " of_offset: %d\n" " parent: %p\n" " priv: %p\n" " uclass: %p\n" " req_seq: %d\n" " seq: %d\n", dev->platdata, dev->parent_platdata, dev->uclass_platdata, base_addr, dev->of_offset, dev->parent, dev->priv, dev->uclass, dev->req_seq, dev->seq); if (dev->of_offset >= 0) rc = process_node(dev, gd->fdt_blob, dev->of_offset); return rc;
}
static const struct udevice_id cavium_mmc_ids[] = { { .compatible = "cavium,thunder-8890-mmc" }, { .compatible = "cavium,mmc" }, { }, };
static const struct udevice_id cavium_mmc_slot_ids[] = { { .compatible = "cavium,thunder-8890-mmc-slot" }, { }, };
U_BOOT_DRIVER(cavium_pci_mmc) = { .name = "mmc_cavium", .id = UCLASS_MMC, .of_match = of_match_ptr(cavium_mmc_ids), .ofdata_to_platdata = cavium_mmc_ofdata_to_platdata, .probe = cavium_pci_mmc_probe, .priv_auto_alloc_size = sizeof(struct cavium_mmc_host), .ops = NULL, };
static struct pci_device_id cavium_pci_mmc_supported[] = { { PCI_VDEVICE(CAVIUM, PCI_DEVICE_ID_THUNDER_MMC) }, {}, };
U_BOOT_PCI_DEVICE(cavium_pci_mmc, cavium_pci_mmc_supported);
I think you're not using dt?
I'm using the dt and some of our other code uses it, though not specifically for the drivers. It's used for the serial interface, for example.
The problem I'm seeing is that in the probe function the of_offset field is always -1. Shouldn't it resolve this information via the compatible string in the device tree? How should I go about setting it up so that not only
This look strange to me, but I am assuming PCI dev hierarchy may require u-boot,dm-pre-reloc on dt have you tried .flags = DM_FLAG_PRE_RELOC?
thanks!
I think I see the problem. The problem is that we have this MRML bus which is a sort of PCI bridge for low-speed devices but we don't have a proper driver for this. When scanning the devices, they show up in the parent ECAM bus and not on the MRML bus so I'm guessing I need to create a PCI bridge driver for this.
-Aaron
participants (2)
-
Aaron Williams
-
Jagan Teki