From 4d21455e09f950d543954c5113f379208f11988e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 8 Sep 2015 17:52:47 -0600 Subject: dm: pci: Tidy up auto-config error handling When the auto-configuration process fails for a device (generally due to lack of memory) we should return the error correctly so that we don't continue to try memory allocations which will fail. Adjust the code to check for errors and abort if something goes wrong. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/pci/pci-uclass.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 0756bbe..43522d2 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -401,9 +401,13 @@ int pci_auto_config_devices(struct udevice *bus) !ret && dev; ret = device_find_next_child(&dev)) { unsigned int max_bus; + int ret; debug("%s: device %s\n", __func__, dev->name); - max_bus = pciauto_config_device(hose, pci_get_bdf(dev)); + ret = pciauto_config_device(hose, pci_get_bdf(dev)); + if (ret < 0) + return ret; + max_bus = ret; sub_bus = max(sub_bus, max_bus); } debug("%s: done\n", __func__); @@ -777,6 +781,8 @@ static int pci_uclass_post_probe(struct udevice *bus) #ifdef CONFIG_PCI_PNP ret = pci_auto_config_devices(bus); + if (ret < 0) + return ret; #endif #if defined(CONFIG_X86) && defined(CONFIG_HAVE_FSP) @@ -793,11 +799,14 @@ static int pci_uclass_post_probe(struct udevice *bus) * Note we only call this 1) after U-Boot is relocated, and 2) * root bus has finished probing. */ - if ((gd->flags & GD_FLG_RELOC) && (bus->seq == 0)) + if ((gd->flags & GD_FLG_RELOC) && (bus->seq == 0)) { ret = fsp_init_phase_pci(); + if (ret) + return ret; + } #endif - return ret < 0 ? ret : 0; + return 0; } static int pci_uclass_child_post_bind(struct udevice *dev) -- cgit v1.1 From 3129ace48948043467439e848264a287d9cd5cce Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 8 Sep 2015 17:52:48 -0600 Subject: dm: pci: Correct a few debug() statements One debug() statement is missing a newline. The other has a repeated word. Fix these. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/pci/pci-uclass.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 43522d2..87eee45 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -438,7 +438,7 @@ int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf) ret = device_probe(bus); if (ret) { - debug("%s: Cannot probe bus bus %s: %d\n", __func__, bus->name, + debug("%s: Cannot probe bus %s: %d\n", __func__, bus->name, ret); return ret; } @@ -557,7 +557,7 @@ static int pci_find_and_bind_driver(struct udevice *parent, ret = device_bind_driver(parent, drv, str, devp); if (ret) { - debug("%s: Failed to bind generic driver: %d", __func__, ret); + debug("%s: Failed to bind generic driver: %d\n", __func__, ret); return ret; } debug("%s: No match found: bound generic driver instead\n", __func__); -- cgit v1.1 From 5dbcf3a0f91b1d7612ede730736efe696edf4d85 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Tue, 8 Sep 2015 17:52:49 -0600 Subject: dm: pci: Adjust pci_find_and_bind_driver() to return -EPERM The current code returns 0 even if it failed to find or bind a driver. The caller then has to check the returned device to see if it is NULL. It is better to return an error code in this case so that it is clear what happened. Adjust the code to return -EPERM, indicating that the device was not bound because it is not needed for pre-relocation use. Add comments so that the return value is clear. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/pci/pci-uclass.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 87eee45..2f4368f 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -478,10 +478,17 @@ static bool pci_match_one_id(const struct pci_device_id *id, * pci_find_and_bind_driver() - Find and bind the right PCI driver * * This only looks at certain fields in the descriptor. + * + * @parent: Parent bus + * @find_id: Specification of the driver to find + * @bdf: Bus/device/function addreess - see PCI_BDF() + * @devp: Returns a pointer to the device created + * @return 0 if OK, -EPERM if the device is not needed before relocation and + * therefore was not created, other -ve value on error */ static int pci_find_and_bind_driver(struct udevice *parent, - struct pci_device_id *find_id, pci_dev_t bdf, - struct udevice **devp) + struct pci_device_id *find_id, + pci_dev_t bdf, struct udevice **devp) { struct pci_driver_entry *start, *entry; const char *drv; @@ -517,7 +524,7 @@ static int pci_find_and_bind_driver(struct udevice *parent, */ if (!(gd->flags & GD_FLG_RELOC) && !(drv->flags & DM_FLAG_PRE_RELOC)) - return 0; + return -EPERM; /* * We could pass the descriptor to the driver as @@ -545,7 +552,7 @@ static int pci_find_and_bind_driver(struct udevice *parent, * limited (ie: using Cache As RAM). */ if (!(gd->flags & GD_FLG_RELOC) && !bridge) - return 0; + return -EPERM; /* Bind a generic driver so that the device can be used */ sprintf(name, "pci_%x:%x.%x", parent->seq, PCI_DEV(bdf), @@ -633,17 +640,17 @@ int pci_bind_bus_devices(struct udevice *bus) ret = pci_find_and_bind_driver(bus, &find_id, bdf, &dev); } - if (ret) + if (ret == -EPERM) + continue; + else if (ret) return ret; /* Update the platform data */ - if (dev) { - pplat = dev_get_parent_platdata(dev); - pplat->devfn = PCI_MASK_BUS(bdf); - pplat->vendor = vendor; - pplat->device = device; - pplat->class = class; - } + pplat = dev_get_parent_platdata(dev); + pplat->devfn = PCI_MASK_BUS(bdf); + pplat->vendor = vendor; + pplat->device = device; + pplat->class = class; } return 0; -- cgit v1.1 From cdf9f085f209ba214178fe749133096721a208a6 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 1 Oct 2015 00:35:59 -0700 Subject: pci: Set PCI_COMMAND_IO bit for VGA device PCI_COMMAND_IO bit must be set for VGA device as it needs to respond to legacy VGA IO address. Signed-off-by: Bin Meng Acked-by: Simon Glass --- drivers/pci/pci_auto.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c index 79f27c7..0412bf3 100644 --- a/drivers/pci/pci_auto.c +++ b/drivers/pci/pci_auto.c @@ -89,6 +89,7 @@ void pciauto_setup_device(struct pci_controller *hose, struct pci_region *bar_res; int found_mem64 = 0; #endif + u16 class; pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat); cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | PCI_COMMAND_MASTER; @@ -206,6 +207,11 @@ void pciauto_setup_device(struct pci_controller *hose, } #endif + /* PCI_COMMAND_IO must be set for VGA device */ + pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class); + if (class == PCI_CLASS_DISPLAY_VGA) + cmdstat |= PCI_COMMAND_IO; + pci_hose_write_config_word(hose, dev, PCI_COMMAND, cmdstat); pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, CONFIG_SYS_PCI_CACHE_LINE_SIZE); -- cgit v1.1 From af67e7ce237fa0956168efca7909458d4ea93d4b Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 1 Oct 2015 00:36:00 -0700 Subject: video: vesa_fb: Fix wrong return value check of pci_find_class() When pci_find_class() fails to find a device, it returns -ENODEV. But now we check the return value against -1. Fix it. Signed-off-by: Bin Meng Acked-by: Simon Glass Acked-by: Anatolij Gustschin --- drivers/video/vesa_fb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/vesa_fb.c b/drivers/video/vesa_fb.c index 4e6d070..a19651f 100644 --- a/drivers/video/vesa_fb.c +++ b/drivers/video/vesa_fb.c @@ -34,7 +34,7 @@ void *video_hw_init(void) } if (vbe_get_video_info(gdev)) { dev = pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, 0); - if (dev == -1) { + if (dev < 0) { printf("no card detected\n"); return NULL; } -- cgit v1.1 From 069155cbb44c1e9e45676ac64e3c95f76a8d5820 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 1 Oct 2015 00:36:01 -0700 Subject: dm: pci: Fix pci_last_busno() to return the real last bus no Currently pci_last_busno() only checks the last bridge device under the first UCLASS_PCI device. This is not the case when there are multiple bridge devices. Signed-off-by: Bin Meng Acked-by: Simon Glass --- drivers/pci/pci-uclass.c | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index 2f4368f..d15de5a 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -85,30 +85,7 @@ static int pci_get_bus_max(void) int pci_last_busno(void) { - struct pci_controller *hose; - struct udevice *bus; - struct uclass *uc; - int ret; - - debug("pci_last_busno\n"); - ret = uclass_get(UCLASS_PCI, &uc); - if (ret || list_empty(&uc->dev_head)) - return -1; - - /* Probe the last bus */ - bus = list_entry(uc->dev_head.prev, struct udevice, uclass_node); - debug("bus = %p, %s\n", bus, bus->name); - assert(bus); - ret = device_probe(bus); - if (ret) - return ret; - - /* If that bus has bridges, we may have new buses now. Get the last */ - bus = list_entry(uc->dev_head.prev, struct udevice, uclass_node); - hose = dev_get_uclass_priv(bus); - debug("bus = %s, hose = %p\n", bus->name, hose); - - return hose->last_busno; + return pci_get_bus_max(); } int pci_get_ff(enum pci_size_t size) -- cgit v1.1 From bbbcb5262839e19fa4c327e1797db08468fc6743 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Thu, 1 Oct 2015 00:36:02 -0700 Subject: dm: pci: Enable VGA address forwarding on bridges To support graphics card behind a PCI bridge, the bridge control register (offset 0x3e) in the configuration space must turn on VGA address forwarding. Signed-off-by: Bin Meng Acked-by: Simon Glass --- drivers/pci/pci-uclass.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index d15de5a..1d93194 100644 --- a/drivers/pci/pci-uclass.c +++ b/drivers/pci/pci-uclass.c @@ -364,9 +364,23 @@ int dm_pci_read_config32(struct udevice *dev, int offset, u32 *valuep) return 0; } +static void set_vga_bridge_bits(struct udevice *dev) +{ + struct udevice *parent = dev->parent; + u16 bc; + + while (parent->seq != 0) { + dm_pci_read_config16(parent, PCI_BRIDGE_CONTROL, &bc); + bc |= PCI_BRIDGE_CTL_VGA; + dm_pci_write_config16(parent, PCI_BRIDGE_CONTROL, bc); + parent = parent->parent; + } +} + int pci_auto_config_devices(struct udevice *bus) { struct pci_controller *hose = bus->uclass_priv; + struct pci_child_platdata *pplat; unsigned int sub_bus; struct udevice *dev; int ret; @@ -386,6 +400,10 @@ int pci_auto_config_devices(struct udevice *bus) return ret; max_bus = ret; sub_bus = max(sub_bus, max_bus); + + pplat = dev_get_parent_platdata(dev); + if (pplat->class == (PCI_CLASS_DISPLAY_VGA << 8)) + set_vga_bridge_bits(dev); } debug("%s: done\n", __func__); -- cgit v1.1 From 5ac98cb9bd1f9b74e2165d69da267f3522714c56 Mon Sep 17 00:00:00 2001 From: George McCollister Date: Mon, 12 Oct 2015 16:18:41 -0500 Subject: x86: spi: Add support for Wildcat Point Add the Wildcat Point ID so Broadwell U based boards can use SPI. Signed-off-by: George McCollister Reviewed-by: Bin Meng --- drivers/spi/ich.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c index 2e388e7..be4c0a3 100644 --- a/drivers/spi/ich.c +++ b/drivers/spi/ich.c @@ -133,7 +133,8 @@ static int get_ich_version(uint16_t device_id) (device_id >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN && device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX) || device_id == PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC || - device_id == PCI_DEVICE_ID_INTEL_LYNXPOINT_LPC) + device_id == PCI_DEVICE_ID_INTEL_LYNXPOINT_LPC || + device_id == PCI_DEVICE_ID_INTEL_WILDCATPOINT_LPC) return 9; return 0; -- cgit v1.1 From 97b059730218824a1455f030aadd78ef51729ec0 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 18 Oct 2015 19:51:23 -0600 Subject: debug_uart: Adjust the declaration of debug_uart_init() We want to be able to add other common code to this function. So change the driver's version to have an underscore before it, just like _debug_uart_putc(). Define debug_uart_init() to call this version. Update all drivers to this new method. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/serial/ns16550.c | 2 +- drivers/serial/serial_efi.c | 2 +- drivers/serial/serial_s5p.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index 6275a11..6433844 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -257,7 +257,7 @@ int NS16550_tstc(NS16550_t com_port) (1 << CONFIG_DEBUG_UART_SHIFT), \ CONFIG_DEBUG_UART_SHIFT) -void debug_uart_init(void) +static inline void _debug_uart_init(void) { struct NS16550 *com_port = (struct NS16550 *)CONFIG_DEBUG_UART_BASE; int baud_divisor; diff --git a/drivers/serial/serial_efi.c b/drivers/serial/serial_efi.c index cf57d89..ea25c25 100644 --- a/drivers/serial/serial_efi.c +++ b/drivers/serial/serial_efi.c @@ -107,7 +107,7 @@ static int serial_efi_pending(struct udevice *dev, bool input) * There is nothing to init here since the EFI console is already running by * the time we enter U-Boot. */ -void debug_uart_init(void) +static inline void _debug_uart_init(void) { } diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c index 3f0b588..feba467 100644 --- a/drivers/serial/serial_s5p.c +++ b/drivers/serial/serial_s5p.c @@ -207,7 +207,7 @@ U_BOOT_DRIVER(serial_s5p) = { #include -void debug_uart_init(void) +static inline void _debug_uart_init(void) { struct s5p_uart *uart = (struct s5p_uart *)CONFIG_DEBUG_UART_BASE; -- cgit v1.1 From 0e977bc1455699fd8a9303ee3e8fd66a3c8eaced Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 18 Oct 2015 19:51:24 -0600 Subject: debug_uart: Support board-specific UART initialisation Some boards need to set things up before the debug UART can be used. On these boards a call to debug_uart_init() is insufficient. When this option is enabled, the function board_debug_uart_init() will be called when debug_uart_init() is called. You can put any code here that is needed to set up the UART ready for use, such as set pin multiplexing or enable clocks. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/serial/Kconfig | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'drivers') diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index ddb725d..39f6500 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -109,6 +109,17 @@ config DEBUG_UART_SHIFT value. Use this value to specify the shift to use, where 0=byte registers, 2=32-bit word registers, etc. +config DEBUG_UART_BOARD_INIT + bool "Enable board-specific debug UART init" + depends on DEBUG_UART + help + Some boards need to set things up before the debug UART can be used. + On these boards a call to debug_uart_init() is insufficient. When + this option is enabled, the function board_debug_uart_init() will + be called when debug_uart_init() is called. You can put any code + here that is needed to set up the UART ready for use, such as set + pin multiplexing or enable clocks. + config ROCKCHIP_SERIAL bool "Rockchip on-chip UART support" depends on ARCH_ROCKCHIP && DM_SERIAL -- cgit v1.1 From c7fefcb9125bbd183dc095996c6747273043d988 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 18 Oct 2015 19:51:25 -0600 Subject: debug_uart: Add an option to announce the debug UART It is useful to see a message from the debug UART early during boot so that you know things are working. Add an option to enable this. The message will be displayed as soon as debug_uart_init() is called. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/serial/Kconfig | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'drivers') diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 39f6500..ac5920a 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -120,6 +120,16 @@ config DEBUG_UART_BOARD_INIT here that is needed to set up the UART ready for use, such as set pin multiplexing or enable clocks. +config DEBUG_UART_ANNOUNCE + bool "Show a message when the debug UART starts up" + depends on DEBUG_UART + help + Enable this option to show a message when the debug UART is ready + for use. You will see a message like " " as soon as + U-Boot has the UART ready for use (i.e. your code calls + debug_uart_init()). This can be useful just as a check that + everything is working. + config ROCKCHIP_SERIAL bool "Rockchip on-chip UART support" depends on ARCH_ROCKCHIP && DM_SERIAL -- cgit v1.1 From 1bcb5c3a6cbaaf29d03bd58d068a7d42042476d5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 18 Oct 2015 15:55:29 -0600 Subject: rtc: mc146818: Add a comment to the #endif Add a comment to make it clear to which block the #endif relates. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/rtc/mc146818.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c index 363ade3..9e94a80 100644 --- a/drivers/rtc/mc146818.c +++ b/drivers/rtc/mc146818.c @@ -192,7 +192,7 @@ static void mc146818_init(void) /* Clear any pending interrupts */ mc146818_read8(RTC_CONFIG_C); } -#endif +#endif /* CONFIG_CMD_DATE */ #ifdef CONFIG_DM_RTC -- cgit v1.1 From b26eb88658b9fbb87c5bae22cede05de3124abb7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 18 Oct 2015 15:55:30 -0600 Subject: rtc: mc146818: Use probe() to set up the device At present this driver uses bind() to set up the device. The bind() method should not touch the hardware, so move the init code to probe(). Signed-off-by: Simon Glass --- drivers/rtc/mc146818.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c index 9e94a80..da804d5 100644 --- a/drivers/rtc/mc146818.c +++ b/drivers/rtc/mc146818.c @@ -225,7 +225,7 @@ static int rtc_mc146818_write8(struct udevice *dev, unsigned int reg, int val) return 0; } -static int rtc_mc146818_bind(struct udevice *dev) +static int rtc_mc146818_probe(struct udevice *dev) { mc146818_init(); @@ -249,7 +249,7 @@ U_BOOT_DRIVER(rtc_mc146818) = { .name = "rtc_mc146818", .id = UCLASS_RTC, .of_match = rtc_mc146818_ids, - .bind = rtc_mc146818_bind, + .probe = rtc_mc146818_probe, .ops = &rtc_mc146818_ops, }; -- cgit v1.1 From 9a4eb5977ad5dc2516e1219613258e30b10d27bd Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 18 Oct 2015 15:55:31 -0600 Subject: dm: rtc: Correct rtc_read32() return value The current check is incorrect and will fail when any non-zero byte is read. Fix it. Signed-off-by: Simon Glass Reviewed-by: Bin Meng --- drivers/rtc/rtc-uclass.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-uclass.c b/drivers/rtc/rtc-uclass.c index fe74c69..300e9b3 100644 --- a/drivers/rtc/rtc-uclass.c +++ b/drivers/rtc/rtc-uclass.c @@ -68,7 +68,7 @@ int rtc_read32(struct udevice *dev, unsigned int reg, u32 *valuep) for (i = 0; i < sizeof(value); i++) { ret = rtc_read8(dev, reg + i); - if (ret) + if (ret < 0) return ret; value |= ret << (i << 3); } -- cgit v1.1