From 40305240c66ab5e3725c131e321402c7dfe687a2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 29 Dec 2014 19:32:23 -0700 Subject: x86: Correct endianness isues in pci_rom This code is too x86-dependent at present. Correct it so that it can run on big-endian machines. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/pci/pci_rom.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) (limited to 'drivers/pci') diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 7d25cc9..86f0e95 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -66,6 +66,7 @@ static int pci_rom_probe(pci_dev_t dev, uint class, struct pci_rom_header *rom_header; struct pci_rom_data *rom_data; u16 vendor, device; + u16 rom_vendor, rom_device; u32 vendev; u32 mapped_vendev; u32 rom_address; @@ -95,25 +96,27 @@ static int pci_rom_probe(pci_dev_t dev, uint class, rom_header = (struct pci_rom_header *)rom_address; debug("PCI expansion ROM, signature %#04x, INIT size %#04x, data ptr %#04x\n", - le32_to_cpu(rom_header->signature), - rom_header->size * 512, le32_to_cpu(rom_header->data)); + le16_to_cpu(rom_header->signature), + rom_header->size * 512, le16_to_cpu(rom_header->data)); - if (le32_to_cpu(rom_header->signature) != PCI_ROM_HDR) { + if (le16_to_cpu(rom_header->signature) != PCI_ROM_HDR) { printf("Incorrect expansion ROM header signature %04x\n", - le32_to_cpu(rom_header->signature)); + le16_to_cpu(rom_header->signature)); return -EINVAL; } - rom_data = (((void *)rom_header) + le32_to_cpu(rom_header->data)); + rom_data = (((void *)rom_header) + le16_to_cpu(rom_header->data)); + rom_vendor = le16_to_cpu(rom_data->vendor); + rom_device = le16_to_cpu(rom_data->device); debug("PCI ROM image, vendor ID %04x, device ID %04x,\n", - rom_data->vendor, rom_data->device); + rom_vendor, rom_device); /* If the device id is mapped, a mismatch is expected */ - if ((vendor != rom_data->vendor || device != rom_data->device) && + if ((vendor != rom_vendor || device != rom_device) && (vendev == mapped_vendev)) { printf("ID mismatch: vendor ID %04x, device ID %04x\n", - rom_data->vendor, rom_data->device); + rom_vendor, rom_device); return -EPERM; } @@ -144,10 +147,10 @@ int pci_rom_load(uint16_t class, struct pci_rom_header *rom_header, image_size); rom_data = (struct pci_rom_data *)((void *)rom_header + - le32_to_cpu(rom_header->data)); + le16_to_cpu(rom_header->data)); - image_size = le32_to_cpu(rom_data->ilen) * 512; - } while ((rom_data->type != 0) && (rom_data->indicator != 0)); + image_size = le16_to_cpu(rom_data->ilen) * 512; + } while ((rom_data->type != 0) && (rom_data->indicator == 0)); if (rom_data->type != 0) return -EACCES; -- cgit v1.1 From bdc88d4eb31e2bc84afb427c216c79e87a4233ef Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 29 Dec 2014 19:32:24 -0700 Subject: x86: Support ROMs on other archs We shouldn't assume that the VGA ROM can always be loaded at c0000. This is only true on x86 machines. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/pci/pci_rom.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/pci') diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 86f0e95..124b730 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -157,7 +157,13 @@ int pci_rom_load(uint16_t class, struct pci_rom_header *rom_header, rom_size = rom_header->size * 512; +#ifdef PCI_VGA_RAM_IMAGE_START target = (void *)PCI_VGA_RAM_IMAGE_START; +#else + target = (void *)malloc(rom_size); + if (!target) + return -ENOMEM; +#endif if (target != rom_header) { ulong start = get_timer(0); -- cgit v1.1 From c5caba03665b0491832ca4c38209d71ff28bf593 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Mon, 29 Dec 2014 19:32:27 -0700 Subject: x86: pci: Don't stop when we get a vendor/device mismatch These are quite common and we may as well press on and not be so picky. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/pci/pci_rom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/pci') diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 124b730..a16e99f 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -117,7 +117,7 @@ static int pci_rom_probe(pci_dev_t dev, uint class, (vendev == mapped_vendev)) { printf("ID mismatch: vendor ID %04x, device ID %04x\n", rom_vendor, rom_device); - return -EPERM; + /* Continue anyway */ } debug("PCI ROM image, Class Code %04x%02x, Code Type %02x\n", -- cgit v1.1 From 4a2708a097eacd7aa3d10ccf26a70a467fa69217 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 14 Jan 2015 21:37:04 -0700 Subject: x86: Access the VGA ROM when needed Add code to the generic pci_rom file to access the VGA ROM in PCI space when needed. Signed-off-by: Simon Glass --- drivers/pci/pci_auto.c | 28 +++++++++++++++++++++++++++- drivers/pci/pci_rom.c | 7 ++++++- 2 files changed, 33 insertions(+), 2 deletions(-) (limited to 'drivers/pci') diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index 44470fa..ed92857 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -11,7 +11,7 @@ */ #include - +#include #include #undef DEBUG @@ -191,6 +191,32 @@ void pciauto_setup_device(struct pci_controller *hose, pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80); } +int pciauto_setup_rom(struct pci_controller *hose, pci_dev_t dev) +{ + pci_addr_t bar_value; + pci_size_t bar_size; + u32 bar_response; + u16 cmdstat = 0; + + pci_hose_write_config_dword(hose, dev, PCI_ROM_ADDRESS, 0xfffffffe); + pci_hose_read_config_dword(hose, dev, PCI_ROM_ADDRESS, &bar_response); + if (!bar_response) + return -ENOENT; + + bar_size = -(bar_response & ~1); + DEBUGF("PCI Autoconfig: ROM, size=%#x, ", bar_size); + if (pciauto_region_allocate(hose->pci_mem, bar_size, &bar_value) == 0) { + pci_hose_write_config_dword(hose, dev, PCI_ROM_ADDRESS, + bar_value); + } + DEBUGF("\n"); + pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat); + cmdstat |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER; + pci_hose_write_config_word(hose, dev, PCI_COMMAND, cmdstat); + + return 0; +} + void pciauto_prescan_setup_bridge(struct pci_controller *hose, pci_dev_t dev, int sub_bus) { diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index a16e99f..eb76591 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -81,7 +81,12 @@ static int pci_rom_probe(pci_dev_t dev, uint class, #ifdef CONFIG_X86_OPTION_ROM_ADDR rom_address = CONFIG_X86_OPTION_ROM_ADDR; #else - pci_write_config_dword(dev, PCI_ROM_ADDRESS, (u32)PCI_ROM_ADDRESS_MASK); + + if (pciauto_setup_rom(pci_bus_to_hose(PCI_BUS(dev)), dev)) { + debug("Cannot find option ROM\n"); + return -ENOENT; + } + pci_read_config_dword(dev, PCI_ROM_ADDRESS, &rom_address); if (rom_address == 0x00000000 || rom_address == 0xffffffff) { debug("%s: rom_address=%x\n", __func__, rom_address); -- cgit v1.1 From 053b86e6d8e50359412e626c33bae3f7bafd74dd Mon Sep 17 00:00:00 2001 From: Sjoerd Simons Date: Tue, 20 Jan 2015 18:06:53 +0100 Subject: pci: tegra: Fix port information parsing commit a62e84d7b1824a202dd incorrectly changed the tegra pci code to the new fdtdec pci helpers. To get the device index of the root port, the "reg" property should be parsed from the dtb (as was previously the case). With this patch i can successfully network boot my jetson tk1 Signed-off-by: Sjoerd Simons Tested-by: Thierry Reding Acked-by: Thierry Reding --- drivers/pci/pci_tegra.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/pci') diff --git a/drivers/pci/pci_tegra.c b/drivers/pci/pci_tegra.c index f9e05ad..67b5fdf 100644 --- a/drivers/pci/pci_tegra.c +++ b/drivers/pci/pci_tegra.c @@ -459,7 +459,6 @@ static int tegra_pcie_parse_port_info(const void *fdt, int node, unsigned int *lanes) { struct fdt_pci_addr addr; - pci_dev_t bdf; int err; err = fdtdec_get_int(fdt, node, "nvidia,num-lanes", 0); @@ -470,13 +469,13 @@ static int tegra_pcie_parse_port_info(const void *fdt, int node, *lanes = err; - err = fdtdec_get_pci_bdf(fdt, node, &addr, &bdf); + err = fdtdec_get_pci_addr(fdt, node, 0, "reg", &addr); if (err < 0) { error("failed to parse \"reg\" property"); return err; } - *index = PCI_DEV(bdf) - 1; + *index = PCI_DEV(addr.phys_hi) - 1; return 0; } -- cgit v1.1