From ef2d17fe21c54adf9f24ee0b32db4ebb56f4eb83 Mon Sep 17 00:00:00 2001 From: Minghuan Lian Date: Thu, 22 Jan 2015 13:21:55 +0800 Subject: drivers/pci/pci_rom.c: fix compile warning under 64bit mode Fix this: drivers/pci/pci_rom.c:95:15: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] rom_header = (struct pci_rom_header *)rom_address; Signed-off-by: Minghuan Lian --- 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 eb76591..5729a15 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -98,7 +98,7 @@ static int pci_rom_probe(pci_dev_t dev, uint class, rom_address | PCI_ROM_ADDRESS_ENABLE); #endif debug("Option ROM address %x\n", rom_address); - rom_header = (struct pci_rom_header *)rom_address; + rom_header = (struct pci_rom_header *)(unsigned long)rom_address; debug("PCI expansion ROM, signature %#04x, INIT size %#04x, data ptr %#04x\n", le16_to_cpu(rom_header->signature), -- cgit v1.1 From 250e039da8c7e485dabdc84f0457b2a901757e28 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:27 -0700 Subject: pci: Add a function to find a device by class There is an existing function prototype in the header file but it is not implemented. Implement something similar. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/pci/pci.c | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) (limited to 'drivers/pci') diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 950a247..e1296ca 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -15,6 +15,7 @@ #include #include +#include #include #include #include @@ -236,6 +237,48 @@ pci_dev_t pci_find_devices(struct pci_device_id *ids, int index) return -1; } +pci_dev_t pci_find_class(uint find_class, int index) +{ + int bus; + int devnum; + pci_dev_t bdf; + uint32_t class; + + for (bus = 0; bus <= pci_last_busno(); bus++) { + for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES - 1; devnum++) { + pci_read_config_dword(PCI_BDF(bus, devnum, 0), + PCI_CLASS_REVISION, &class); + if (class >> 16 == 0xffff) + continue; + + for (bdf = PCI_BDF(bus, devnum, 0); + bdf <= PCI_BDF(bus, devnum, + PCI_MAX_PCI_FUNCTIONS - 1); + bdf += PCI_BDF(0, 0, 1)) { + pci_read_config_dword(bdf, PCI_CLASS_REVISION, + &class); + class >>= 8; + + if (class != find_class) + continue; + /* + * Decrement the index. We want to return the + * correct device, so index is 0 for the first + * matching device, 1 for the second, etc. + */ + if (index) { + index--; + continue; + } + /* Return index'th controller. */ + return bdf; + } + } + } + + return -ENODEV; +} + pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index) { struct pci_device_id ids[2] = { {}, {0, 0} }; -- cgit v1.1 From bc17d8f4ac41a6a4bcc4b28f1c6216a5a034fa63 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 27 Jan 2015 22:13:34 -0700 Subject: x86: video: Allow video ROM execution to fall back to the other method If the BIOS emulator is not available, allow use of native execution if available, and vice versa. This can be controlled by the caller. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/pci/pci_rom.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'drivers/pci') diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 5729a15..48c0a77 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -228,11 +228,12 @@ int vbe_get_video_info(struct graphic_device *gdev) #endif } -int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate) +int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), int exec_method) { struct pci_rom_header *rom, *ram; int vesa_mode = -1; uint16_t class; + bool emulate; int ret; /* Only execute VGA ROMs */ @@ -262,6 +263,29 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate) vesa_mode = CONFIG_FRAMEBUFFER_VESA_MODE; #endif debug("Selected vesa mode %#x\n", vesa_mode); + + if (exec_method & PCI_ROM_USE_NATIVE) { +#ifdef CONFIG_X86 + emulate = false; +#else + if (!(exec_method & PCI_ROM_ALLOW_FALLBACK)) { + printf("BIOS native execution is only available on x86\n"); + return -ENOSYS; + } + emulate = true; +#endif + } else { +#ifdef CONFIG_BIOSEMU + emulate = true; +#else + if (!(exec_method & PCI_ROM_ALLOW_FALLBACK)) { + printf("BIOS emulation not available - see CONFIG_BIOSEMU\n"); + return -ENOSYS; + } + emulate = false; +#endif + } + if (emulate) { #ifdef CONFIG_BIOSEMU BE_VGAInfo *info; @@ -274,9 +298,6 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate) vesa_mode, &mode_info); if (ret) return ret; -#else - printf("BIOS emulation not available - see CONFIG_BIOSEMU\n"); - return -ENOSYS; #endif } else { #ifdef CONFIG_X86 @@ -284,9 +305,6 @@ int pci_run_vga_bios(pci_dev_t dev, int (*int15_handler)(void), bool emulate) bios_run_on_x86(dev, (unsigned long)ram, vesa_mode, &mode_info); -#else - printf("BIOS native execution is only available on x86\n"); - return -ENOSYS; #endif } debug("Final vesa mode %#x\n", mode_info.video_mode); -- cgit v1.1 From 6eefd5279c4e80d613420066364ec3c8ba551a56 Mon Sep 17 00:00:00 2001 From: David Feng Date: Mon, 2 Feb 2015 16:53:13 +0800 Subject: PCI: add 64-bit prefetchable memory support PCI specification allow prefetchable memory to be 32-bit or 64-bit. PCI express specification states that all memmory bars for prefetchable memory must be implemented as 64-bit. They all require that 64 bit prefetchble memory are suported especially when u-boot is ported to more and more 64bit processors. Signed-off-by: David Feng Reviewed-by: Bin Meng --- drivers/pci/pci_auto.c | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) (limited to 'drivers/pci') diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index ed92857..378efbf 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -223,9 +223,12 @@ void pciauto_prescan_setup_bridge(struct pci_controller *hose, struct pci_region *pci_mem = hose->pci_mem; struct pci_region *pci_prefetch = hose->pci_prefetch; struct pci_region *pci_io = hose->pci_io; - u16 cmdstat; + u16 cmdstat, prefechable_64; pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat); + pci_hose_read_config_word(hose, dev, PCI_PREF_MEMORY_BASE, + &prefechable_64); + prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK; /* Configure bus number registers */ pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS, @@ -252,12 +255,26 @@ void pciauto_prescan_setup_bridge(struct pci_controller *hose, /* Set up memory and I/O filter limits, assume 32-bit I/O space */ pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, (pci_prefetch->bus_lower & 0xfff00000) >> 16); + if (prefechable_64 == PCI_PREF_RANGE_TYPE_64) +#ifdef CONFIG_SYS_PCI_64BIT + pci_hose_write_config_dword(hose, dev, + PCI_PREF_BASE_UPPER32, + pci_prefetch->bus_lower >> 32); +#else + pci_hose_write_config_dword(hose, dev, + PCI_PREF_BASE_UPPER32, + 0x0); +#endif cmdstat |= PCI_COMMAND_MEMORY; } else { /* We don't support prefetchable memory for now, so disable */ pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, 0x1000); pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, 0x0); + if (prefechable_64 == PCI_PREF_RANGE_TYPE_64) { + pci_hose_write_config_word(hose, dev, PCI_PREF_BASE_UPPER32, 0x0); + pci_hose_write_config_word(hose, dev, PCI_PREF_LIMIT_UPPER32, 0x0); + } } if (pci_io) { @@ -297,11 +314,28 @@ void pciauto_postscan_setup_bridge(struct pci_controller *hose, } if (pci_prefetch) { + u16 prefechable_64; + + pci_hose_read_config_word(hose, dev, + PCI_PREF_MEMORY_LIMIT, + &prefechable_64); + prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK; + /* Round memory allocator to 1MB boundary */ pciauto_region_align(pci_prefetch, 0x100000); pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, (pci_prefetch->bus_lower - 1) >> 16); + if (prefechable_64 == PCI_PREF_RANGE_TYPE_64) +#ifdef CONFIG_SYS_PCI_64BIT + pci_hose_write_config_dword(hose, dev, + PCI_PREF_LIMIT_UPPER32, + (pci_prefetch->bus_lower - 1) >> 32); +#else + pci_hose_write_config_dword(hose, dev, + PCI_PREF_LIMIT_UPPER32, + 0x0); +#endif } if (pci_io) { -- cgit v1.1