From df233e734fb70076c0434b242594476332208ee0 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 9 Sep 2016 07:45:49 +0200 Subject: x86: conga-qeval20-qa3: Add README to explain the console UART options This patch adds a small README to explain the 2 defconfig files and its usage for the different console UART options. Signed-off-by: Stefan Roese Reviewed-by: Bin Meng Cc: Simon Glass diff --git a/board/congatec/conga-qeval20-qa3-e3845/README b/board/congatec/conga-qeval20-qa3-e3845/README new file mode 100644 index 0000000..98ff992 --- /dev/null +++ b/board/congatec/conga-qeval20-qa3-e3845/README @@ -0,0 +1,23 @@ +------------------------------ +U-Boot console UART selection: +------------------------------ + +The U-Boot port for this congatec board currently supports two different +configurations (defconfig files). The only difference is the UART that +is used as the U-Boot console UART. The default defconfig file: + +conga-qeval20-qa3-e3845_defconfig + +provides this console on the UART0 which is provided via a Winbond +Super-IO chip connected on the congatec Qseven 2.0 evaluation carrier +board (conga-QEVAL). This UART is the one provided with a SubD9 +connector on the mainboard (the low one). The 2nd defconfig file: + +conga-qeval20-qa3-e3845-internal-uart_defconfig + +provides the U-Boot console on the BayTrail internal legacy UART, +which is routed from the QSeven SoM to the X300 connector on the +baseboard. Here is called COM2. The baseboard already provides the +RS232 level shifters. So a TTL-USB UART adapter does not work in +this case. The signals need to get connected directly to the +RS232 level signals of the PC UART via some adapter cable. -- cgit v0.10.2 From 5572367cc595d567361fc29298c099922ed65812 Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 26 Sep 2016 10:18:07 +0200 Subject: x86: baytrail: Add 2nd eMMC controller to the PCI probe list With this addition, the eMMC device available on the congatec and DFI BayTrail SoM is detected correctly. Signed-off-by: Stefan Roese Cc: Simon Glass Cc: Bin Meng Reviewed-by: Bin Meng diff --git a/arch/x86/cpu/baytrail/valleyview.c b/arch/x86/cpu/baytrail/valleyview.c index b312d9f..87ba849 100644 --- a/arch/x86/cpu/baytrail/valleyview.c +++ b/arch/x86/cpu/baytrail/valleyview.c @@ -12,8 +12,9 @@ #include static struct pci_device_id mmc_supported[] = { - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO }, - { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDCARD }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_SDIO }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_SD }, + { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_EMMC2 }, {}, }; diff --git a/include/pci_ids.h b/include/pci_ids.h index 17a01a0..ab6aa58 100644 --- a/include/pci_ids.h +++ b/include/pci_ids.h @@ -2599,13 +2599,14 @@ #define PCI_DEVICE_ID_INTEL_I960 0x0960 #define PCI_DEVICE_ID_INTEL_I960RM 0x0962 #define PCI_DEVICE_ID_INTEL_CENTERTON_ILB 0x0c60 -#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDIO 0x0f15 -#define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SDCARD 0x0f16 +#define PCI_DEVICE_ID_INTEL_BYT_SDIO 0x0f15 +#define PCI_DEVICE_ID_INTEL_BYT_SD 0x0f16 #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC 0x0f1c #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_IDE 0x0f20 #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_IDE_ALT 0x0f21 #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA 0x0f22 #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA_ALT 0x0f23 +#define PCI_DEVICE_ID_INTEL_BYT_EMMC2 0x0f50 #define PCI_DEVICE_ID_INTEL_82541ER 0x1078 #define PCI_DEVICE_ID_INTEL_82541GI_LF 0x107c #define PCI_DEVICE_ID_INTEL_82542 0x1000 -- cgit v0.10.2 From 88d915b10f44e044dfd874e201a4ce1fcdbff59a Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Fri, 30 Sep 2016 09:15:59 +0200 Subject: x86: Fix Linux v4.7+ zimage booting (update bootparam.h) Booting Linux kernel v4.7+ does not work since Linux kernel commit 974f221c "x86/boot: Move compressed kernel to the end of the decompression buffer". This patch adds the latest version of the setup_header struct, adding "init_size" which is needed since this commit referenced above. With this patch, booting Linux v4.8-rc8 does work again on x86 boards. Signed-off-by: Stefan Roese Reviewed-by: Simon Glass Reviewed-by: Bin Meng Tested-by: Bin Meng diff --git a/arch/x86/include/asm/bootparam.h b/arch/x86/include/asm/bootparam.h index 1400951..a373a79 100644 --- a/arch/x86/include/asm/bootparam.h +++ b/arch/x86/include/asm/bootparam.h @@ -63,6 +63,9 @@ struct setup_header { __u32 payload_offset; __u32 payload_length; __u64 setup_data; + __u64 pref_address; + __u32 init_size; + __u32 handover_offset; } __attribute__((packed)); struct sys_desc_table { -- cgit v0.10.2 From 26f50fbed2f19edf0c4a2eb80e7fa12941764660 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 5 Oct 2016 20:42:09 -0600 Subject: Revert "x86: broadwell: gpio: Remove the codes to set up pin control" This makes the assumption that setting up pinctrl in cpu_init_r() is safe. On samus we need GPIOs before relocation in order to support power control. This commit fixes the following message on boot: initcall sequence ffe5c6f4 failed at call ffe01d3d (err=-1) ### ERROR ### Please RESET the board ### In any case it seems better to leave init to driver model, so that it can pick up the GPIO driver when it needs it. Since pinctrl is a dependency of the GPIO driver, we may as well put the dependency there and avoid these problems. This reverts commit 9769e05bcf79939bad23a719982dd1f85a110f3c. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/drivers/gpio/intel_broadwell_gpio.c b/drivers/gpio/intel_broadwell_gpio.c index 8b50900..81ce446 100644 --- a/drivers/gpio/intel_broadwell_gpio.c +++ b/drivers/gpio/intel_broadwell_gpio.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -118,6 +119,12 @@ static int broadwell_gpio_probe(struct udevice *dev) struct broadwell_bank_platdata *plat = dev_get_platdata(dev); struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev); struct broadwell_bank_priv *priv = dev_get_priv(dev); + struct udevice *pinctrl; + int ret; + + /* Set up pin control if available */ + ret = syscon_get_by_driver_data(X86_SYSCON_PINCONF, &pinctrl); + debug("%s, pinctrl=%p, ret=%d\n", __func__, pinctrl, ret); uc_priv->gpio_count = GPIO_PER_BANK; uc_priv->bank_name = plat->bank_name; -- cgit v0.10.2 From a5b8722532729c62370b6abb278420804d5d071b Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 5 Oct 2016 20:42:10 -0600 Subject: x86: Add an accelerated memmove() function Bring in a faster memmove() from Linux 4.7. This speeds up scrolling on the display. Signed-off-by: Simon Glass Reviewed-by: Bin Meng Tested-by: Bin Meng diff --git a/arch/x86/include/asm/string.h b/arch/x86/include/asm/string.h index 0ad612f..38afd23 100644 --- a/arch/x86/include/asm/string.h +++ b/arch/x86/include/asm/string.h @@ -17,7 +17,7 @@ extern char * strchr(const char * s, int c); #define __HAVE_ARCH_MEMCPY extern void * memcpy(void *, const void *, __kernel_size_t); -#undef __HAVE_ARCH_MEMMOVE +#define __HAVE_ARCH_MEMMOVE extern void * memmove(void *, const void *, __kernel_size_t); #undef __HAVE_ARCH_MEMCHR diff --git a/arch/x86/lib/string.c b/arch/x86/lib/string.c index 6c66431..5343c2b 100644 --- a/arch/x86/lib/string.c +++ b/arch/x86/lib/string.c @@ -130,3 +130,164 @@ void *memcpy(void *dstpp, const void *srcpp, size_t len) return dstpp; } + +void *memmove(void *dest, const void *src, size_t n) +{ + int d0, d1, d2, d3, d4, d5; + char *ret = dest; + + __asm__ __volatile__( + /* Handle more 16 bytes in loop */ + "cmp $0x10, %0\n\t" + "jb 1f\n\t" + + /* Decide forward/backward copy mode */ + "cmp %2, %1\n\t" + "jb 2f\n\t" + + /* + * movs instruction have many startup latency + * so we handle small size by general register. + */ + "cmp $680, %0\n\t" + "jb 3f\n\t" + /* movs instruction is only good for aligned case */ + "mov %1, %3\n\t" + "xor %2, %3\n\t" + "and $0xff, %3\n\t" + "jz 4f\n\t" + "3:\n\t" + "sub $0x10, %0\n\t" + + /* We gobble 16 bytes forward in each loop */ + "3:\n\t" + "sub $0x10, %0\n\t" + "mov 0*4(%1), %3\n\t" + "mov 1*4(%1), %4\n\t" + "mov %3, 0*4(%2)\n\t" + "mov %4, 1*4(%2)\n\t" + "mov 2*4(%1), %3\n\t" + "mov 3*4(%1), %4\n\t" + "mov %3, 2*4(%2)\n\t" + "mov %4, 3*4(%2)\n\t" + "lea 0x10(%1), %1\n\t" + "lea 0x10(%2), %2\n\t" + "jae 3b\n\t" + "add $0x10, %0\n\t" + "jmp 1f\n\t" + + /* Handle data forward by movs */ + ".p2align 4\n\t" + "4:\n\t" + "mov -4(%1, %0), %3\n\t" + "lea -4(%2, %0), %4\n\t" + "shr $2, %0\n\t" + "rep movsl\n\t" + "mov %3, (%4)\n\t" + "jmp 11f\n\t" + /* Handle data backward by movs */ + ".p2align 4\n\t" + "6:\n\t" + "mov (%1), %3\n\t" + "mov %2, %4\n\t" + "lea -4(%1, %0), %1\n\t" + "lea -4(%2, %0), %2\n\t" + "shr $2, %0\n\t" + "std\n\t" + "rep movsl\n\t" + "mov %3,(%4)\n\t" + "cld\n\t" + "jmp 11f\n\t" + + /* Start to prepare for backward copy */ + ".p2align 4\n\t" + "2:\n\t" + "cmp $680, %0\n\t" + "jb 5f\n\t" + "mov %1, %3\n\t" + "xor %2, %3\n\t" + "and $0xff, %3\n\t" + "jz 6b\n\t" + + /* Calculate copy position to tail */ + "5:\n\t" + "add %0, %1\n\t" + "add %0, %2\n\t" + "sub $0x10, %0\n\t" + + /* We gobble 16 bytes backward in each loop */ + "7:\n\t" + "sub $0x10, %0\n\t" + + "mov -1*4(%1), %3\n\t" + "mov -2*4(%1), %4\n\t" + "mov %3, -1*4(%2)\n\t" + "mov %4, -2*4(%2)\n\t" + "mov -3*4(%1), %3\n\t" + "mov -4*4(%1), %4\n\t" + "mov %3, -3*4(%2)\n\t" + "mov %4, -4*4(%2)\n\t" + "lea -0x10(%1), %1\n\t" + "lea -0x10(%2), %2\n\t" + "jae 7b\n\t" + /* Calculate copy position to head */ + "add $0x10, %0\n\t" + "sub %0, %1\n\t" + "sub %0, %2\n\t" + + /* Move data from 8 bytes to 15 bytes */ + ".p2align 4\n\t" + "1:\n\t" + "cmp $8, %0\n\t" + "jb 8f\n\t" + "mov 0*4(%1), %3\n\t" + "mov 1*4(%1), %4\n\t" + "mov -2*4(%1, %0), %5\n\t" + "mov -1*4(%1, %0), %1\n\t" + + "mov %3, 0*4(%2)\n\t" + "mov %4, 1*4(%2)\n\t" + "mov %5, -2*4(%2, %0)\n\t" + "mov %1, -1*4(%2, %0)\n\t" + "jmp 11f\n\t" + + /* Move data from 4 bytes to 7 bytes */ + ".p2align 4\n\t" + "8:\n\t" + "cmp $4, %0\n\t" + "jb 9f\n\t" + "mov 0*4(%1), %3\n\t" + "mov -1*4(%1, %0), %4\n\t" + "mov %3, 0*4(%2)\n\t" + "mov %4, -1*4(%2, %0)\n\t" + "jmp 11f\n\t" + + /* Move data from 2 bytes to 3 bytes */ + ".p2align 4\n\t" + "9:\n\t" + "cmp $2, %0\n\t" + "jb 10f\n\t" + "movw 0*2(%1), %%dx\n\t" + "movw -1*2(%1, %0), %%bx\n\t" + "movw %%dx, 0*2(%2)\n\t" + "movw %%bx, -1*2(%2, %0)\n\t" + "jmp 11f\n\t" + + /* Move data for 1 byte */ + ".p2align 4\n\t" + "10:\n\t" + "cmp $1, %0\n\t" + "jb 11f\n\t" + "movb (%1), %%cl\n\t" + "movb %%cl, (%2)\n\t" + ".p2align 4\n\t" + "11:" + : "=&c" (d0), "=&S" (d1), "=&D" (d2), + "=r" (d3), "=r" (d4), "=r"(d5) + : "0" (n), + "1" (src), + "2" (dest) + : "memory"); + + return ret; +} -- cgit v0.10.2 From b91c6a1209e7da1a7f989d9ac35d0d8be0b7b710 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 5 Oct 2016 20:42:11 -0600 Subject: Fix return value in trailing_strtoln() This function should return -1 if there is no trailing integer in the string. Instead it returns 0. Fix it by checking for this condition at the start. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/lib/strto.c b/lib/strto.c index a6c0157..e93a4f5 100644 --- a/lib/strto.c +++ b/lib/strto.c @@ -160,9 +160,11 @@ long trailing_strtoln(const char *str, const char *end) if (!end) end = str + strlen(str); - for (p = end - 1; p > str; p--) { - if (!isdigit(*p)) - return simple_strtoul(p + 1, NULL, 10); + if (isdigit(end[-1])) { + for (p = end - 1; p > str; p--) { + if (!isdigit(*p)) + return simple_strtoul(p + 1, NULL, 10); + } } return -1; -- cgit v0.10.2 From 5023bd7a804e09d0bf4937d8fecb5d85af6dba3c Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 5 Oct 2016 20:42:12 -0600 Subject: list: Add list_last_entry() to find the last entry We have list_first_entry() but in some cases it is useful to find the last item added to the list. Add a macro for this. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/include/linux/list.h b/include/linux/list.h index b78851c..5b8d1df 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -338,6 +338,17 @@ static inline void list_splice_tail_init(struct list_head *list, list_entry((ptr)->next, type, member) /** + * list_last_entry - get the last element from a list + * @ptr: the list head to take the element from. + * @type: the type of the struct this is embedded in. + * @member: the name of the list_struct within the struct. + * + * Note, that list is expected to be not empty. + */ +#define list_last_entry(ptr, type, member) \ + list_entry((ptr)->prev, type, member) + +/** * list_for_each - iterate over a list * @pos: the &struct list_head to use as a loop cursor. * @head: the head for your list. -- cgit v0.10.2 From 0a5f6f869f1c2c6e9f75d83203754937014cbe47 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 5 Oct 2016 20:42:13 -0600 Subject: dm: core: Add a function to get a uclass name It is useful in debug() statements to display the name of the uclass for a device. Add a simple function to provide this. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c index de602ae..60610e5 100644 --- a/drivers/core/uclass.c +++ b/drivers/core/uclass.c @@ -148,6 +148,15 @@ int uclass_get(enum uclass_id id, struct uclass **ucp) return 0; } +const char *uclass_get_name(enum uclass_id id) +{ + struct uclass *uc; + + if (uclass_get(id, &uc)) + return NULL; + return uc->uc_drv->name; +} + int uclass_find_device(enum uclass_id id, int index, struct udevice **devp) { struct uclass *uc; diff --git a/include/dm/uclass.h b/include/dm/uclass.h index 84f05bc..b583aa8 100644 --- a/include/dm/uclass.h +++ b/include/dm/uclass.h @@ -119,6 +119,14 @@ struct uclass_driver { int uclass_get(enum uclass_id key, struct uclass **ucp); /** + * uclass_get_name() - Get the name of a uclass driver + * + * @id: ID to look up + * @returns the name of the uclass driver for that ID, or NULL if none + */ +const char *uclass_get_name(enum uclass_id id); + +/** * uclass_get_device() - Get a uclass device based on an ID and index * * The device is probed to activate it ready for use. -- cgit v0.10.2 From 1df912762815df8a1254e4629dfb62e1845c15dd Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 5 Oct 2016 20:42:14 -0600 Subject: x86: video: Fix typo in broadwell Kconfig 'enabled' should be 'enables'. Fix it. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 8361a71..97dbb64 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -366,7 +366,7 @@ config VIDEO_BROADWELL_IGD bool "Enable Intel Broadwell integrated graphics device" depends on X86 help - This enabled support for integrated graphics on Intel broadwell + This enables support for integrated graphics on Intel broadwell devices. Initialisation is mostly performed by a VGA boot ROM, with some setup handled by U-Boot itself. The graphics adaptor works as a VESA device and supports LCD panels, eDP and LVDS outputs. -- cgit v0.10.2 From d8441ea27ed1253f17f05f30057853a95a28b4c7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 5 Oct 2016 20:42:16 -0600 Subject: dm: stdio: Allow lazy probing of video devices At present all video devices are probed on start-up. It would be better to probe a device only when it is needed. This can happen if it is referenced in the stdout environment variable, for example. Add support for this by searching for a suitable device when needed, probing it, and finding the stdio device it creates. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/common/stdio.c b/common/stdio.c index f99cfe7..ab9b05d 100644 --- a/common/stdio.c +++ b/common/stdio.c @@ -121,19 +121,87 @@ struct list_head* stdio_get_list(void) return &(devs.list); } +#ifdef CONFIG_DM_VIDEO +/** + * stdio_probe_device() - Find a device which provides the given stdio device + * + * This looks for a device of the given uclass which provides a particular + * stdio device. It is currently really only useful for UCLASS_VIDEO. + * + * Ultimately we want to be able to probe a device by its stdio name. At + * present devices register in their probe function (for video devices this + * is done in vidconsole_post_probe()) and we don't know what name they will + * use until they do so. + * TODO(sjg@chromium.org): We should be able to determine the name before + * probing, and probe the required device. + * + * @name: stdio device name (e.g. "vidconsole") + * id: Uclass ID of device to look for (e.g. UCLASS_VIDEO) + * @sdevp: Returns stdout device, if found, else NULL + * @return 0 if found, -ENOENT if no device found with that name, other -ve + * on other error + */ +static int stdio_probe_device(const char *name, enum uclass_id id, + struct stdio_dev **sdevp) +{ + struct stdio_dev *sdev; + struct udevice *dev; + int seq, ret; + + *sdevp = NULL; + seq = trailing_strtoln(name, NULL); + if (seq == -1) + ret = uclass_first_device_err(id, &dev); + else + ret = uclass_get_device_by_seq(id, seq, &dev); + if (ret) { + debug("No %s device for seq %d (%s)\n", uclass_get_name(id), + seq, name); + return ret; + } + /* The device should be be the last one registered */ + sdev = list_empty(&devs.list) ? NULL : + list_last_entry(&devs.list, struct stdio_dev, list); + if (!sdev || strcmp(sdev->name, name)) { + debug("Device '%s' did not register with stdio as '%s'\n", + dev->name, name); + return -ENOENT; + } + *sdevp = sdev; + + return 0; +} +#endif + struct stdio_dev* stdio_get_by_name(const char *name) { struct list_head *pos; - struct stdio_dev *dev; + struct stdio_dev *sdev; if(!name) return NULL; list_for_each(pos, &(devs.list)) { - dev = list_entry(pos, struct stdio_dev, list); - if(strcmp(dev->name, name) == 0) - return dev; + sdev = list_entry(pos, struct stdio_dev, list); + if (strcmp(sdev->name, name) == 0) + return sdev; } +#ifdef CONFIG_DM_VIDEO + /* + * We did not find a suitable stdio device. If there is a video + * driver with a name starting with 'vidconsole', we can try probing + * that in the hope that it will produce the required stdio device. + * + * This function is sometimes called with the entire value of + * 'stdout', which may include a list of devices separate by commas. + * Obviously this is not going to work, so we ignore that case. The + * call path in that case is console_init_r() -> search_device() -> + * stdio_get_by_name(). + */ + if (!strncmp(name, "vidconsole", 10) && !strchr(name, ',') && + !stdio_probe_device(name, UCLASS_VIDEO, &sdev)) + return sdev; +#endif return NULL; } @@ -282,6 +350,16 @@ int stdio_add_devices(void) #endif #endif #ifdef CONFIG_DM_VIDEO + /* + * If the console setting is not in environment variables then + * console_init_r() will not be calling iomux_doenv() (which calls + * search_device()). So we will not dynamically add devices by + * calling stdio_probe_device(). + * + * So just probe all video devices now so that whichever one is + * required will be available. + */ +#ifndef CONFIG_SYS_CONSOLE_IS_IN_ENV struct udevice *vdev; # ifndef CONFIG_DM_KEYBOARD int ret; @@ -293,6 +371,7 @@ int stdio_add_devices(void) ; if (ret) printf("%s: Video device failed (ret=%d)\n", __func__, ret); +#endif /* !CONFIG_SYS_CONSOLE_IS_IN_ENV */ #else # if defined(CONFIG_LCD) drv_lcd_init (); -- cgit v0.10.2 From ee87ee82e1c9052d59e44c5c29448f4545ab59e7 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 5 Oct 2016 20:42:17 -0600 Subject: dm: video: Add driver-model support to vesa graphics Provide a function to run the Vesa BIOS for a given PCI device and obtain the resulting configuration (e.g. display size) for use by the video uclass. This makes it easier to write a video driver that uses vesa and supports driver model. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 399055b..21ed17c 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -348,3 +349,57 @@ err: free(ram); return ret; } + +#ifdef CONFIG_DM_VIDEO +static int vbe_setup_video_priv(struct vesa_mode_info *vesa, + struct video_priv *uc_priv, + struct video_uc_platdata *plat) +{ + if (!vesa->x_resolution) + return -ENXIO; + uc_priv->xsize = vesa->x_resolution; + uc_priv->ysize = vesa->y_resolution; + switch (vesa->bits_per_pixel) { + case 32: + case 24: + uc_priv->bpix = VIDEO_BPP32; + break; + case 16: + uc_priv->bpix = VIDEO_BPP16; + break; + default: + return -EPROTONOSUPPORT; + } + plat->base = vesa->phys_base_ptr; + plat->size = vesa->bytes_per_scanline * vesa->y_resolution; + + return 0; +} + +int vbe_setup_video(struct udevice *dev, int (*int15_handler)(void)) +{ + struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); + struct video_priv *uc_priv = dev_get_uclass_priv(dev); + int ret; + + /* If we are running from EFI or coreboot, this can't work */ + if (!ll_boot_init()) + return -EPERM; + bootstage_start(BOOTSTAGE_ID_ACCUM_LCD, "vesa display"); + ret = dm_pci_run_vga_bios(dev, int15_handler, PCI_ROM_USE_NATIVE | + PCI_ROM_ALLOW_FALLBACK); + bootstage_accum(BOOTSTAGE_ID_ACCUM_LCD); + if (ret) { + debug("failed to run video BIOS: %d\n", ret); + return ret; + } + + ret = vbe_setup_video_priv(&mode_info.vesa, uc_priv, plat); + if (ret) { + debug("No video mode configured\n"); + return ret; + } + + return 0; +} +#endif diff --git a/include/vbe.h b/include/vbe.h index 164ccae..a743892 100644 --- a/include/vbe.h +++ b/include/vbe.h @@ -106,5 +106,7 @@ extern struct vbe_mode_info mode_info; struct graphic_device; int vbe_get_video_info(struct graphic_device *gdev); +struct video_priv; +int vbe_setup_video(struct udevice *dev, int (*int15_handler)(void)); #endif -- cgit v0.10.2 From 2c943804afdff8817387aa828ef9218efcf1d590 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 5 Oct 2016 20:42:15 -0600 Subject: dm: x86: video: Add a driver-model driver for ivybridge graphics At present we use the legacy vesa driver for graphics. Add a driver which supports driver model. This can be probed only when needed, removing the need to start up the display if it is not used. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 97dbb64..fd26690 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -374,6 +374,18 @@ config VIDEO_BROADWELL_IGD a special tool which configures the VGA ROM, but the graphics resolution can be selected in U-Boot. +config VIDEO_IVYBRIDGE_IGD + bool "Enable Intel Ivybridge integration graphics support" + depends on X86 + help + This enables support for integrated graphics on Intel ivybridge + devices. Initialisation is mostly performed by a VGA boot ROM, with + some setup handled by U-Boot itself. The graphics adaptor works as + a VESA device and supports LCD panels, eDP and LVDS outputs. + Configuration of most aspects of device operation is performed using + a special tool which configures the VGA ROM, but the graphics + resolution can be selected in U-Boot. + config VIDEO_ROCKCHIP bool "Enable Rockchip video support" depends on DM_VIDEO diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 3f045fe..b888e99 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_CONSOLE_TRUETYPE) += console_truetype.o fonts/ endif obj-$(CONFIG_VIDEO_BROADWELL_IGD) += broadwell_igd.o +obj-$(CONFIG_VIDEO_IVYBRIDGE_IGD) += ivybridge_igd.o obj-$(CONFIG_ATI_RADEON_FB) += ati_radeon_fb.o videomodes.o obj-$(CONFIG_ATMEL_HLCD) += atmel_hlcdfb.o diff --git a/drivers/video/ivybridge_igd.c b/drivers/video/ivybridge_igd.c new file mode 100644 index 0000000..94db3dd --- /dev/null +++ b/drivers/video/ivybridge_igd.c @@ -0,0 +1,843 @@ +/* + * Copyright (C) 2016 Google, Inc + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct gt_powermeter { + u16 reg; + u32 value; +}; + +/* These are magic values - unfortunately the meaning is unknown */ +static const struct gt_powermeter snb_pm_gt1[] = { + { 0xa200, 0xcc000000 }, + { 0xa204, 0x07000040 }, + { 0xa208, 0x0000fe00 }, + { 0xa20c, 0x00000000 }, + { 0xa210, 0x17000000 }, + { 0xa214, 0x00000021 }, + { 0xa218, 0x0817fe19 }, + { 0xa21c, 0x00000000 }, + { 0xa220, 0x00000000 }, + { 0xa224, 0xcc000000 }, + { 0xa228, 0x07000040 }, + { 0xa22c, 0x0000fe00 }, + { 0xa230, 0x00000000 }, + { 0xa234, 0x17000000 }, + { 0xa238, 0x00000021 }, + { 0xa23c, 0x0817fe19 }, + { 0xa240, 0x00000000 }, + { 0xa244, 0x00000000 }, + { 0xa248, 0x8000421e }, + { 0 } +}; + +static const struct gt_powermeter snb_pm_gt2[] = { + { 0xa200, 0x330000a6 }, + { 0xa204, 0x402d0031 }, + { 0xa208, 0x00165f83 }, + { 0xa20c, 0xf1000000 }, + { 0xa210, 0x00000000 }, + { 0xa214, 0x00160016 }, + { 0xa218, 0x002a002b }, + { 0xa21c, 0x00000000 }, + { 0xa220, 0x00000000 }, + { 0xa224, 0x330000a6 }, + { 0xa228, 0x402d0031 }, + { 0xa22c, 0x00165f83 }, + { 0xa230, 0xf1000000 }, + { 0xa234, 0x00000000 }, + { 0xa238, 0x00160016 }, + { 0xa23c, 0x002a002b }, + { 0xa240, 0x00000000 }, + { 0xa244, 0x00000000 }, + { 0xa248, 0x8000421e }, + { 0 } +}; + +static const struct gt_powermeter ivb_pm_gt1[] = { + { 0xa800, 0x00000000 }, + { 0xa804, 0x00021c00 }, + { 0xa808, 0x00000403 }, + { 0xa80c, 0x02001700 }, + { 0xa810, 0x05000200 }, + { 0xa814, 0x00000000 }, + { 0xa818, 0x00690500 }, + { 0xa81c, 0x0000007f }, + { 0xa820, 0x01002501 }, + { 0xa824, 0x00000300 }, + { 0xa828, 0x01000331 }, + { 0xa82c, 0x0000000c }, + { 0xa830, 0x00010016 }, + { 0xa834, 0x01100101 }, + { 0xa838, 0x00010103 }, + { 0xa83c, 0x00041300 }, + { 0xa840, 0x00000b30 }, + { 0xa844, 0x00000000 }, + { 0xa848, 0x7f000000 }, + { 0xa84c, 0x05000008 }, + { 0xa850, 0x00000001 }, + { 0xa854, 0x00000004 }, + { 0xa858, 0x00000007 }, + { 0xa85c, 0x00000000 }, + { 0xa860, 0x00010000 }, + { 0xa248, 0x0000221e }, + { 0xa900, 0x00000000 }, + { 0xa904, 0x00001c00 }, + { 0xa908, 0x00000000 }, + { 0xa90c, 0x06000000 }, + { 0xa910, 0x09000200 }, + { 0xa914, 0x00000000 }, + { 0xa918, 0x00590000 }, + { 0xa91c, 0x00000000 }, + { 0xa920, 0x04002501 }, + { 0xa924, 0x00000100 }, + { 0xa928, 0x03000410 }, + { 0xa92c, 0x00000000 }, + { 0xa930, 0x00020000 }, + { 0xa934, 0x02070106 }, + { 0xa938, 0x00010100 }, + { 0xa93c, 0x00401c00 }, + { 0xa940, 0x00000000 }, + { 0xa944, 0x00000000 }, + { 0xa948, 0x10000e00 }, + { 0xa94c, 0x02000004 }, + { 0xa950, 0x00000001 }, + { 0xa954, 0x00000004 }, + { 0xa960, 0x00060000 }, + { 0xaa3c, 0x00001c00 }, + { 0xaa54, 0x00000004 }, + { 0xaa60, 0x00060000 }, + { 0 } +}; + +static const struct gt_powermeter ivb_pm_gt2[] = { + { 0xa800, 0x10000000 }, + { 0xa804, 0x00033800 }, + { 0xa808, 0x00000902 }, + { 0xa80c, 0x0c002f00 }, + { 0xa810, 0x12000400 }, + { 0xa814, 0x00000000 }, + { 0xa818, 0x00d20800 }, + { 0xa81c, 0x00000002 }, + { 0xa820, 0x03004b02 }, + { 0xa824, 0x00000600 }, + { 0xa828, 0x07000773 }, + { 0xa82c, 0x00000000 }, + { 0xa830, 0x00010032 }, + { 0xa834, 0x1520040d }, + { 0xa838, 0x00020105 }, + { 0xa83c, 0x00083700 }, + { 0xa840, 0x0000151d }, + { 0xa844, 0x00000000 }, + { 0xa848, 0x20001b00 }, + { 0xa84c, 0x0a000010 }, + { 0xa850, 0x00000000 }, + { 0xa854, 0x00000008 }, + { 0xa858, 0x00000008 }, + { 0xa85c, 0x00000000 }, + { 0xa860, 0x00020000 }, + { 0xa248, 0x0000221e }, + { 0xa900, 0x00000000 }, + { 0xa904, 0x00003500 }, + { 0xa908, 0x00000000 }, + { 0xa90c, 0x0c000000 }, + { 0xa910, 0x12000500 }, + { 0xa914, 0x00000000 }, + { 0xa918, 0x00b20000 }, + { 0xa91c, 0x00000000 }, + { 0xa920, 0x08004b02 }, + { 0xa924, 0x00000200 }, + { 0xa928, 0x07000820 }, + { 0xa92c, 0x00000000 }, + { 0xa930, 0x00030000 }, + { 0xa934, 0x050f020d }, + { 0xa938, 0x00020300 }, + { 0xa93c, 0x00903900 }, + { 0xa940, 0x00000000 }, + { 0xa944, 0x00000000 }, + { 0xa948, 0x20001b00 }, + { 0xa94c, 0x0a000010 }, + { 0xa950, 0x00000000 }, + { 0xa954, 0x00000008 }, + { 0xa960, 0x00110000 }, + { 0xaa3c, 0x00003900 }, + { 0xaa54, 0x00000008 }, + { 0xaa60, 0x00110000 }, + { 0 } +}; + +static const struct gt_powermeter ivb_pm_gt2_17w[] = { + { 0xa800, 0x20000000 }, + { 0xa804, 0x000e3800 }, + { 0xa808, 0x00000806 }, + { 0xa80c, 0x0c002f00 }, + { 0xa810, 0x0c000800 }, + { 0xa814, 0x00000000 }, + { 0xa818, 0x00d20d00 }, + { 0xa81c, 0x000000ff }, + { 0xa820, 0x03004b02 }, + { 0xa824, 0x00000600 }, + { 0xa828, 0x07000773 }, + { 0xa82c, 0x00000000 }, + { 0xa830, 0x00020032 }, + { 0xa834, 0x1520040d }, + { 0xa838, 0x00020105 }, + { 0xa83c, 0x00083700 }, + { 0xa840, 0x000016ff }, + { 0xa844, 0x00000000 }, + { 0xa848, 0xff000000 }, + { 0xa84c, 0x0a000010 }, + { 0xa850, 0x00000002 }, + { 0xa854, 0x00000008 }, + { 0xa858, 0x0000000f }, + { 0xa85c, 0x00000000 }, + { 0xa860, 0x00020000 }, + { 0xa248, 0x0000221e }, + { 0xa900, 0x00000000 }, + { 0xa904, 0x00003800 }, + { 0xa908, 0x00000000 }, + { 0xa90c, 0x0c000000 }, + { 0xa910, 0x12000800 }, + { 0xa914, 0x00000000 }, + { 0xa918, 0x00b20000 }, + { 0xa91c, 0x00000000 }, + { 0xa920, 0x08004b02 }, + { 0xa924, 0x00000300 }, + { 0xa928, 0x01000820 }, + { 0xa92c, 0x00000000 }, + { 0xa930, 0x00030000 }, + { 0xa934, 0x15150406 }, + { 0xa938, 0x00020300 }, + { 0xa93c, 0x00903900 }, + { 0xa940, 0x00000000 }, + { 0xa944, 0x00000000 }, + { 0xa948, 0x20001b00 }, + { 0xa94c, 0x0a000010 }, + { 0xa950, 0x00000000 }, + { 0xa954, 0x00000008 }, + { 0xa960, 0x00110000 }, + { 0xaa3c, 0x00003900 }, + { 0xaa54, 0x00000008 }, + { 0xaa60, 0x00110000 }, + { 0 } +}; + +static const struct gt_powermeter ivb_pm_gt2_35w[] = { + { 0xa800, 0x00000000 }, + { 0xa804, 0x00030400 }, + { 0xa808, 0x00000806 }, + { 0xa80c, 0x0c002f00 }, + { 0xa810, 0x0c000300 }, + { 0xa814, 0x00000000 }, + { 0xa818, 0x00d20d00 }, + { 0xa81c, 0x000000ff }, + { 0xa820, 0x03004b02 }, + { 0xa824, 0x00000600 }, + { 0xa828, 0x07000773 }, + { 0xa82c, 0x00000000 }, + { 0xa830, 0x00020032 }, + { 0xa834, 0x1520040d }, + { 0xa838, 0x00020105 }, + { 0xa83c, 0x00083700 }, + { 0xa840, 0x000016ff }, + { 0xa844, 0x00000000 }, + { 0xa848, 0xff000000 }, + { 0xa84c, 0x0a000010 }, + { 0xa850, 0x00000001 }, + { 0xa854, 0x00000008 }, + { 0xa858, 0x00000008 }, + { 0xa85c, 0x00000000 }, + { 0xa860, 0x00020000 }, + { 0xa248, 0x0000221e }, + { 0xa900, 0x00000000 }, + { 0xa904, 0x00003800 }, + { 0xa908, 0x00000000 }, + { 0xa90c, 0x0c000000 }, + { 0xa910, 0x12000800 }, + { 0xa914, 0x00000000 }, + { 0xa918, 0x00b20000 }, + { 0xa91c, 0x00000000 }, + { 0xa920, 0x08004b02 }, + { 0xa924, 0x00000300 }, + { 0xa928, 0x01000820 }, + { 0xa92c, 0x00000000 }, + { 0xa930, 0x00030000 }, + { 0xa934, 0x15150406 }, + { 0xa938, 0x00020300 }, + { 0xa93c, 0x00903900 }, + { 0xa940, 0x00000000 }, + { 0xa944, 0x00000000 }, + { 0xa948, 0x20001b00 }, + { 0xa94c, 0x0a000010 }, + { 0xa950, 0x00000000 }, + { 0xa954, 0x00000008 }, + { 0xa960, 0x00110000 }, + { 0xaa3c, 0x00003900 }, + { 0xaa54, 0x00000008 }, + { 0xaa60, 0x00110000 }, + { 0 } +}; + +static inline u32 gtt_read(void *bar, u32 reg) +{ + return readl(bar + reg); +} + +static inline void gtt_write(void *bar, u32 reg, u32 data) +{ + writel(data, bar + reg); +} + +static void gtt_write_powermeter(void *bar, const struct gt_powermeter *pm) +{ + for (; pm && pm->reg; pm++) + gtt_write(bar, pm->reg, pm->value); +} + +#define GTT_RETRY 1000 +static int gtt_poll(void *bar, u32 reg, u32 mask, u32 value) +{ + unsigned try = GTT_RETRY; + u32 data; + + while (try--) { + data = gtt_read(bar, reg); + if ((data & mask) == value) + return 1; + udelay(10); + } + + printf("GT init timeout\n"); + return 0; +} + +static int gma_pm_init_pre_vbios(void *gtt_bar, int rev) +{ + u32 reg32; + + debug("GT Power Management Init, silicon = %#x\n", rev); + + if (rev < IVB_STEP_C0) { + /* 1: Enable force wake */ + gtt_write(gtt_bar, 0xa18c, 0x00000001); + gtt_poll(gtt_bar, 0x130090, (1 << 0), (1 << 0)); + } else { + gtt_write(gtt_bar, 0xa180, 1 << 5); + gtt_write(gtt_bar, 0xa188, 0xffff0001); + gtt_poll(gtt_bar, 0x130040, (1 << 0), (1 << 0)); + } + + if ((rev & BASE_REV_MASK) == BASE_REV_SNB) { + /* 1d: Set GTT+0x42004 [15:14]=11 (SnB C1+) */ + reg32 = gtt_read(gtt_bar, 0x42004); + reg32 |= (1 << 14) | (1 << 15); + gtt_write(gtt_bar, 0x42004, reg32); + } + + if (rev >= IVB_STEP_A0) { + /* Display Reset Acknowledge Settings */ + reg32 = gtt_read(gtt_bar, 0x45010); + reg32 |= (1 << 1) | (1 << 0); + gtt_write(gtt_bar, 0x45010, reg32); + } + + /* 2: Get GT SKU from GTT+0x911c[13] */ + reg32 = gtt_read(gtt_bar, 0x911c); + if ((rev & BASE_REV_MASK) == BASE_REV_SNB) { + if (reg32 & (1 << 13)) { + debug("SNB GT1 Power Meter Weights\n"); + gtt_write_powermeter(gtt_bar, snb_pm_gt1); + } else { + debug("SNB GT2 Power Meter Weights\n"); + gtt_write_powermeter(gtt_bar, snb_pm_gt2); + } + } else { + u32 unit = readl(MCHBAR_REG(0x5938)) & 0xf; + + if (reg32 & (1 << 13)) { + /* GT1 SKU */ + debug("IVB GT1 Power Meter Weights\n"); + gtt_write_powermeter(gtt_bar, ivb_pm_gt1); + } else { + /* GT2 SKU */ + u32 tdp = readl(MCHBAR_REG(0x5930)) & 0x7fff; + tdp /= (1 << unit); + + if (tdp <= 17) { + /* <=17W ULV */ + debug("IVB GT2 17W Power Meter Weights\n"); + gtt_write_powermeter(gtt_bar, ivb_pm_gt2_17w); + } else if ((tdp >= 25) && (tdp <= 35)) { + /* 25W-35W */ + debug("IVB GT2 25W-35W Power Meter Weights\n"); + gtt_write_powermeter(gtt_bar, ivb_pm_gt2_35w); + } else { + /* All others */ + debug("IVB GT2 35W Power Meter Weights\n"); + gtt_write_powermeter(gtt_bar, ivb_pm_gt2_35w); + } + } + } + + /* 3: Gear ratio map */ + gtt_write(gtt_bar, 0xa004, 0x00000010); + + /* 4: GFXPAUSE */ + gtt_write(gtt_bar, 0xa000, 0x00070020); + + /* 5: Dynamic EU trip control */ + gtt_write(gtt_bar, 0xa080, 0x00000004); + + /* 6: ECO bits */ + reg32 = gtt_read(gtt_bar, 0xa180); + reg32 |= (1 << 26) | (1 << 31); + /* (bit 20=1 for SNB step D1+ / IVB A0+) */ + if (rev >= SNB_STEP_D1) + reg32 |= (1 << 20); + gtt_write(gtt_bar, 0xa180, reg32); + + /* 6a: for SnB step D2+ only */ + if (((rev & BASE_REV_MASK) == BASE_REV_SNB) && + (rev >= SNB_STEP_D2)) { + reg32 = gtt_read(gtt_bar, 0x9400); + reg32 |= (1 << 7); + gtt_write(gtt_bar, 0x9400, reg32); + + reg32 = gtt_read(gtt_bar, 0x941c); + reg32 &= 0xf; + reg32 |= (1 << 1); + gtt_write(gtt_bar, 0x941c, reg32); + gtt_poll(gtt_bar, 0x941c, (1 << 1), (0 << 1)); + } + + if ((rev & BASE_REV_MASK) == BASE_REV_IVB) { + reg32 = gtt_read(gtt_bar, 0x907c); + reg32 |= (1 << 16); + gtt_write(gtt_bar, 0x907c, reg32); + + /* 6b: Clocking reset controls */ + gtt_write(gtt_bar, 0x9424, 0x00000001); + } else { + /* 6b: Clocking reset controls */ + gtt_write(gtt_bar, 0x9424, 0x00000000); + } + + /* 7 */ + if (gtt_poll(gtt_bar, 0x138124, (1 << 31), (0 << 31))) { + gtt_write(gtt_bar, 0x138128, 0x00000029); /* Mailbox Data */ + /* Mailbox Cmd for RC6 VID */ + gtt_write(gtt_bar, 0x138124, 0x80000004); + if (gtt_poll(gtt_bar, 0x138124, (1 << 31), (0 << 31))) + gtt_write(gtt_bar, 0x138124, 0x8000000a); + gtt_poll(gtt_bar, 0x138124, (1 << 31), (0 << 31)); + } + + /* 8 */ + gtt_write(gtt_bar, 0xa090, 0x00000000); /* RC Control */ + gtt_write(gtt_bar, 0xa098, 0x03e80000); /* RC1e Wake Rate Limit */ + gtt_write(gtt_bar, 0xa09c, 0x0028001e); /* RC6/6p Wake Rate Limit */ + gtt_write(gtt_bar, 0xa0a0, 0x0000001e); /* RC6pp Wake Rate Limit */ + gtt_write(gtt_bar, 0xa0a8, 0x0001e848); /* RC Evaluation Interval */ + gtt_write(gtt_bar, 0xa0ac, 0x00000019); /* RC Idle Hysteresis */ + + /* 9 */ + gtt_write(gtt_bar, 0x2054, 0x0000000a); /* Render Idle Max Count */ + gtt_write(gtt_bar, 0x12054, 0x0000000a); /* Video Idle Max Count */ + gtt_write(gtt_bar, 0x22054, 0x0000000a); /* Blitter Idle Max Count */ + + /* 10 */ + gtt_write(gtt_bar, 0xa0b0, 0x00000000); /* Unblock Ack to Busy */ + gtt_write(gtt_bar, 0xa0b4, 0x000003e8); /* RC1e Threshold */ + gtt_write(gtt_bar, 0xa0b8, 0x0000c350); /* RC6 Threshold */ + gtt_write(gtt_bar, 0xa0bc, 0x000186a0); /* RC6p Threshold */ + gtt_write(gtt_bar, 0xa0c0, 0x0000fa00); /* RC6pp Threshold */ + + /* 11 */ + gtt_write(gtt_bar, 0xa010, 0x000f4240); /* RP Down Timeout */ + gtt_write(gtt_bar, 0xa014, 0x12060000); /* RP Interrupt Limits */ + gtt_write(gtt_bar, 0xa02c, 0x00015f90); /* RP Up Threshold */ + gtt_write(gtt_bar, 0xa030, 0x000186a0); /* RP Down Threshold */ + gtt_write(gtt_bar, 0xa068, 0x000186a0); /* RP Up EI */ + gtt_write(gtt_bar, 0xa06c, 0x000493e0); /* RP Down EI */ + gtt_write(gtt_bar, 0xa070, 0x0000000a); /* RP Idle Hysteresis */ + + /* 11a: Enable Render Standby (RC6) */ + if ((rev & BASE_REV_MASK) == BASE_REV_IVB) { + /* + * IvyBridge should also support DeepRenderStandby. + * + * Unfortunately it does not work reliably on all SKUs so + * disable it here and it can be enabled by the kernel. + */ + gtt_write(gtt_bar, 0xa090, 0x88040000); /* HW RC Control */ + } else { + gtt_write(gtt_bar, 0xa090, 0x88040000); /* HW RC Control */ + } + + /* 12: Normal Frequency Request */ + /* RPNFREQ_VAL comes from MCHBAR 0x5998 23:16 (8 bits!? use 7) */ + reg32 = readl(MCHBAR_REG(0x5998)); + reg32 >>= 16; + reg32 &= 0xef; + reg32 <<= 25; + gtt_write(gtt_bar, 0xa008, reg32); + + /* 13: RP Control */ + gtt_write(gtt_bar, 0xa024, 0x00000592); + + /* 14: Enable PM Interrupts */ + gtt_write(gtt_bar, 0x4402c, 0x03000076); + + /* Clear 0x6c024 [8:6] */ + reg32 = gtt_read(gtt_bar, 0x6c024); + reg32 &= ~0x000001c0; + gtt_write(gtt_bar, 0x6c024, reg32); + + return 0; +} + +static int gma_pm_init_post_vbios(struct udevice *dev, int rev, void *gtt_bar) +{ + const void *blob = gd->fdt_blob; + int node = dev->of_offset; + u32 reg32, cycle_delay; + + debug("GT Power Management Init (post VBIOS)\n"); + + /* 15: Deassert Force Wake */ + if (rev < IVB_STEP_C0) { + gtt_write(gtt_bar, 0xa18c, gtt_read(gtt_bar, 0xa18c) & ~1); + gtt_poll(gtt_bar, 0x130090, (1 << 0), (0 << 0)); + } else { + gtt_write(gtt_bar, 0xa188, 0x1fffe); + if (gtt_poll(gtt_bar, 0x130040, (1 << 0), (0 << 0))) { + gtt_write(gtt_bar, 0xa188, + gtt_read(gtt_bar, 0xa188) | 1); + } + } + + /* 16: SW RC Control */ + gtt_write(gtt_bar, 0xa094, 0x00060000); + + /* Setup Digital Port Hotplug */ + reg32 = gtt_read(gtt_bar, 0xc4030); + if (!reg32) { + u32 dp_hotplug[3]; + + if (fdtdec_get_int_array(blob, node, "intel,dp_hotplug", + dp_hotplug, ARRAY_SIZE(dp_hotplug))) + return -EINVAL; + + reg32 = (dp_hotplug[0] & 0x7) << 2; + reg32 |= (dp_hotplug[0] & 0x7) << 10; + reg32 |= (dp_hotplug[0] & 0x7) << 18; + gtt_write(gtt_bar, 0xc4030, reg32); + } + + /* Setup Panel Power On Delays */ + reg32 = gtt_read(gtt_bar, 0xc7208); + if (!reg32) { + reg32 = (unsigned)fdtdec_get_int(blob, node, + "panel-port-select", 0) << 30; + reg32 |= fdtdec_get_int(blob, node, "panel-power-up-delay", 0) + << 16; + reg32 |= fdtdec_get_int(blob, node, + "panel-power-backlight-on-delay", 0); + gtt_write(gtt_bar, 0xc7208, reg32); + } + + /* Setup Panel Power Off Delays */ + reg32 = gtt_read(gtt_bar, 0xc720c); + if (!reg32) { + reg32 = fdtdec_get_int(blob, node, "panel-power-down-delay", 0) + << 16; + reg32 |= fdtdec_get_int(blob, node, + "panel-power-backlight-off-delay", 0); + gtt_write(gtt_bar, 0xc720c, reg32); + } + + /* Setup Panel Power Cycle Delay */ + cycle_delay = fdtdec_get_int(blob, node, + "intel,panel-power-cycle-delay", 0); + if (cycle_delay) { + reg32 = gtt_read(gtt_bar, 0xc7210); + reg32 &= ~0xff; + reg32 |= cycle_delay; + gtt_write(gtt_bar, 0xc7210, reg32); + } + + /* Enable Backlight if needed */ + reg32 = fdtdec_get_int(blob, node, "intel,cpu-backlight", 0); + if (reg32) { + gtt_write(gtt_bar, 0x48250, (1 << 31)); + gtt_write(gtt_bar, 0x48254, reg32); + } + reg32 = fdtdec_get_int(blob, node, "intel,pch-backlight", 0); + if (reg32) { + gtt_write(gtt_bar, 0xc8250, (1 << 31)); + gtt_write(gtt_bar, 0xc8254, reg32); + } + + return 0; +} + +/* + * Some vga option roms are used for several chipsets but they only have one + * PCI ID in their header. If we encounter such an option rom, we need to do + * the mapping ourselves. + */ + +uint32_t board_map_oprom_vendev(uint32_t vendev) +{ + switch (vendev) { + case 0x80860102: /* GT1 Desktop */ + case 0x8086010a: /* GT1 Server */ + case 0x80860112: /* GT2 Desktop */ + case 0x80860116: /* GT2 Mobile */ + case 0x80860122: /* GT2 Desktop >=1.3GHz */ + case 0x80860126: /* GT2 Mobile >=1.3GHz */ + case 0x80860156: /* IVB */ + case 0x80860166: /* IVB */ + return 0x80860106; /* GT1 Mobile */ + } + + return vendev; +} + +static int int15_handler(void) +{ + int res = 0; + + debug("%s: INT15 function %04x!\n", __func__, M.x86.R_AX); + + switch (M.x86.R_AX) { + case 0x5f34: + /* + * Set Panel Fitting Hook: + * bit 2 = Graphics Stretching + * bit 1 = Text Stretching + * bit 0 = Centering (do not set with bit1 or bit2) + * 0 = video bios default + */ + M.x86.R_AX = 0x005f; + M.x86.R_CL = 0x00; /* Use video bios default */ + res = 1; + break; + case 0x5f35: + /* + * Boot Display Device Hook: + * bit 0 = CRT + * bit 1 = TV (eDP) + * bit 2 = EFP + * bit 3 = LFP + * bit 4 = CRT2 + * bit 5 = TV2 (eDP) + * bit 6 = EFP2 + * bit 7 = LFP2 + */ + M.x86.R_AX = 0x005f; + M.x86.R_CX = 0x0000; /* Use video bios default */ + res = 1; + break; + case 0x5f51: + /* + * Hook to select active LFP configuration: + * 00h = No LVDS, VBIOS does not enable LVDS + * 01h = Int-LVDS, LFP driven by integrated LVDS decoder + * 02h = SVDO-LVDS, LFP driven by SVDO decoder + * 03h = eDP, LFP Driven by Int-DisplayPort encoder + */ + M.x86.R_AX = 0x005f; + M.x86.R_CX = 0x0003; /* eDP */ + res = 1; + break; + case 0x5f70: + switch (M.x86.R_CH) { + case 0: + /* Get Mux */ + M.x86.R_AX = 0x005f; + M.x86.R_CX = 0x0000; + res = 1; + break; + case 1: + /* Set Mux */ + M.x86.R_AX = 0x005f; + M.x86.R_CX = 0x0000; + res = 1; + break; + case 2: + /* Get SG/Non-SG mode */ + M.x86.R_AX = 0x005f; + M.x86.R_CX = 0x0000; + res = 1; + break; + default: + /* Interrupt was not handled */ + debug("Unknown INT15 5f70 function: 0x%02x\n", + M.x86.R_CH); + break; + } + break; + case 0x5fac: + res = 1; + break; + default: + debug("Unknown INT15 function %04x!\n", M.x86.R_AX); + break; + } + return res; +} + +static void sandybridge_setup_graphics(struct udevice *dev, + struct udevice *video_dev) +{ + u32 reg32; + u16 reg16; + u8 reg8; + + dm_pci_read_config16(video_dev, PCI_DEVICE_ID, ®16); + switch (reg16) { + case 0x0102: /* GT1 Desktop */ + case 0x0106: /* GT1 Mobile */ + case 0x010a: /* GT1 Server */ + case 0x0112: /* GT2 Desktop */ + case 0x0116: /* GT2 Mobile */ + case 0x0122: /* GT2 Desktop >=1.3GHz */ + case 0x0126: /* GT2 Mobile >=1.3GHz */ + case 0x0156: /* IvyBridge */ + case 0x0166: /* IvyBridge */ + break; + default: + debug("Graphics not supported by this CPU/chipset\n"); + return; + } + + debug("Initialising Graphics\n"); + + /* Setup IGD memory by setting GGC[7:3] = 1 for 32MB */ + dm_pci_read_config16(dev, GGC, ®16); + reg16 &= ~0x00f8; + reg16 |= 1 << 3; + /* Program GTT memory by setting GGC[9:8] = 2MB */ + reg16 &= ~0x0300; + reg16 |= 2 << 8; + /* Enable VGA decode */ + reg16 &= ~0x0002; + dm_pci_write_config16(dev, GGC, reg16); + + /* Enable 256MB aperture */ + dm_pci_read_config8(video_dev, MSAC, ®8); + reg8 &= ~0x06; + reg8 |= 0x02; + dm_pci_write_config8(video_dev, MSAC, reg8); + + /* Erratum workarounds */ + reg32 = readl(MCHBAR_REG(0x5f00)); + reg32 |= (1 << 9) | (1 << 10); + writel(reg32, MCHBAR_REG(0x5f00)); + + /* Enable SA Clock Gating */ + reg32 = readl(MCHBAR_REG(0x5f00)); + writel(reg32 | 1, MCHBAR_REG(0x5f00)); + + /* GPU RC6 workaround for sighting 366252 */ + reg32 = readl(MCHBAR_REG(0x5d14)); + reg32 |= (1 << 31); + writel(reg32, MCHBAR_REG(0x5d14)); + + /* VLW */ + reg32 = readl(MCHBAR_REG(0x6120)); + reg32 &= ~(1 << 0); + writel(reg32, MCHBAR_REG(0x6120)); + + reg32 = readl(MCHBAR_REG(0x5418)); + reg32 |= (1 << 4) | (1 << 5); + writel(reg32, MCHBAR_REG(0x5418)); +} + +static int gma_func0_init(struct udevice *dev) +{ + struct udevice *nbridge; + void *gtt_bar; + ulong base; + u32 reg32; + int ret; + int rev; + + /* Enable PCH Display Port */ + writew(0x0010, RCB_REG(DISPBDF)); + setbits_le32(RCB_REG(FD2), PCH_ENABLE_DBDF); + + ret = uclass_first_device_err(UCLASS_NORTHBRIDGE, &nbridge); + if (ret) + return ret; + rev = bridge_silicon_revision(nbridge); + sandybridge_setup_graphics(nbridge, dev); + + /* IGD needs to be Bus Master */ + dm_pci_read_config32(dev, PCI_COMMAND, ®32); + reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO; + dm_pci_write_config32(dev, PCI_COMMAND, reg32); + + /* Use write-combining for the graphics memory, 256MB */ + base = dm_pci_read_bar32(dev, 2); + mtrr_add_request(MTRR_TYPE_WRCOMB, base, 256 << 20); + mtrr_commit(true); + + gtt_bar = (void *)dm_pci_read_bar32(dev, 0); + debug("GT bar %p\n", gtt_bar); + ret = gma_pm_init_pre_vbios(gtt_bar, rev); + if (ret) + return ret; + + return rev; +} + +static int bd82x6x_video_probe(struct udevice *dev) +{ + void *gtt_bar; + int ret, rev; + + rev = gma_func0_init(dev); + if (rev < 0) + return rev; + ret = vbe_setup_video(dev, int15_handler); + if (ret) + return ret; + + /* Post VBIOS init */ + gtt_bar = (void *)dm_pci_read_bar32(dev, 0); + ret = gma_pm_init_post_vbios(dev, rev, gtt_bar); + if (ret) + return ret; + + return 0; +} + +static const struct udevice_id bd82x6x_video_ids[] = { + { .compatible = "intel,gma" }, + { } +}; + +U_BOOT_DRIVER(bd82x6x_video) = { + .name = "bd82x6x_video", + .id = UCLASS_VIDEO, + .of_match = bd82x6x_video_ids, + .probe = bd82x6x_video_probe, +}; -- cgit v0.10.2 From 0d9483a25c5c936a87806108c29395f0c7d6b520 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 5 Oct 2016 20:42:18 -0600 Subject: x86: Adjust config to support DM_VIDEO Update the common configuration so that it works correctly when CONFIG_DM_VIDEO is enabled. This involves dropping the legacy CONFIG_VIDEO option and changing the stdio device from "vga" to "vidconsole". Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/include/configs/x86-chromebook.h b/include/configs/x86-chromebook.h index 312987e..7fba716 100644 --- a/include/configs/x86-chromebook.h +++ b/include/configs/x86-chromebook.h @@ -53,8 +53,14 @@ #define CONFIG_SYS_WHITE_ON_BLACK +#ifdef CONFIG_DM_VIDEO +#define VIDEO_DEV "vidconsole" +#else +#define VIDEO_DEV "vga" +#endif + #define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,i8042-kbd,serial\0" \ - "stdout=vga,serial\0" \ - "stderr=vga,serial\0" + "stdout=" VIDEO_DEV ",serial\0" \ + "stderr=" VIDEO_DEV ",serial\0" #endif diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index 74b2522..96c53b8 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -131,11 +131,13 @@ /*----------------------------------------------------------------------- * Video Configuration */ +#ifndef CONFIG_DM_VIDEO #define CONFIG_VIDEO #define CONFIG_VIDEO_SW_CURSOR #define VIDEO_FB_16BPP_WORD_SWAP #define CONFIG_VGA_AS_SINGLE_DEVICE #define CONFIG_CFB_CONSOLE +#endif #define CONFIG_CONSOLE_SCROLL_LINES 5 /*----------------------------------------------------------------------- -- cgit v0.10.2 From 443ffe509c7bedca440fbd37e3853895c8fe31f2 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 5 Oct 2016 20:42:19 -0600 Subject: dm: x86: Move samus to use new driver model support Update the samus driver to avoid the direct call to the video BIOS setup. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/cpu/broadwell/sdram.c b/arch/x86/cpu/broadwell/sdram.c index e7befde..74736cd 100644 --- a/arch/x86/cpu/broadwell/sdram.c +++ b/arch/x86/cpu/broadwell/sdram.c @@ -291,7 +291,6 @@ void board_debug_uart_init(void) static const struct udevice_id broadwell_syscon_ids[] = { { .compatible = "intel,me", .data = X86_SYSCON_ME }, - { .compatible = "intel,gma", .data = X86_SYSCON_GMA }, { } }; diff --git a/drivers/video/broadwell_igd.c b/drivers/video/broadwell_igd.c index 4286fd0..beef770 100644 --- a/drivers/video/broadwell_igd.c +++ b/drivers/video/broadwell_igd.c @@ -9,10 +9,8 @@ #include #include #include -#include #include #include -#include #include #include #include @@ -20,11 +18,9 @@ #include #include #include -#include #include "i915_reg.h" struct broadwell_igd_priv { - GraphicDevice ctfb; u8 *regs; }; @@ -664,10 +660,7 @@ static int broadwell_igd_probe(struct udevice *dev) { struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); struct video_priv *uc_priv = dev_get_uclass_priv(dev); - struct broadwell_igd_priv *priv = dev_get_priv(dev); bool is_broadwell; - GraphicDevice *gdev = &priv->ctfb; - int bits_per_pixel; int ret; if (!ll_boot_init()) { @@ -683,13 +676,9 @@ static int broadwell_igd_probe(struct udevice *dev) debug("%s: is_broadwell=%d\n", __func__, is_broadwell); ret = igd_pre_init(dev, is_broadwell); if (!ret) { - ret = dm_pci_run_vga_bios(dev, broadwell_igd_int15_handler, - PCI_ROM_USE_NATIVE | - PCI_ROM_ALLOW_FALLBACK); - if (ret) { - printf("failed to run video BIOS: %d\n", ret); - ret = -EIO; - } + ret = vbe_setup_video(dev, broadwell_igd_int15_handler); + if (ret) + debug("failed to run video BIOS: %d\n", ret); } if (!ret) ret = igd_post_init(dev, is_broadwell); @@ -697,13 +686,8 @@ static int broadwell_igd_probe(struct udevice *dev) if (ret) return ret; - if (vbe_get_video_info(gdev)) { - printf("No video mode configured\n"); - return -ENXIO; - } - - /* Use write-through for the graphics memory, 256MB */ - ret = mtrr_add_request(MTRR_TYPE_WRTHROUGH, gdev->pciBase, 256 << 20); + /* Use write-combining for the graphics memory, 256MB */ + ret = mtrr_add_request(MTRR_TYPE_WRCOMB, plat->base, 256 << 20); if (!ret) ret = mtrr_commit(true); if (ret && ret != -ENOSYS) { @@ -711,17 +695,8 @@ static int broadwell_igd_probe(struct udevice *dev) ret); } - bits_per_pixel = gdev->gdfBytesPP * 8; - sprintf(gdev->modeIdent, "%dx%dx%d", gdev->winSizeX, gdev->winSizeY, - bits_per_pixel); - printf("%s\n", gdev->modeIdent); - uc_priv->xsize = gdev->winSizeX; - uc_priv->ysize = gdev->winSizeY; - uc_priv->bpix = ilog2(bits_per_pixel); - plat->base = gdev->pciBase; - plat->size = gdev->memSize; - debug("fb=%x, size %x, display size=%d %d %d\n", gdev->pciBase, - gdev->memSize, uc_priv->xsize, uc_priv->ysize, uc_priv->bpix); + debug("fb=%lx, size %x, display size=%d %d %d\n", plat->base, + plat->size, uc_priv->xsize, uc_priv->ysize, uc_priv->bpix); return 0; } -- cgit v0.10.2 From b6409ec3027de01336da41994518f6704c61e7e5 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Wed, 5 Oct 2016 20:42:20 -0600 Subject: dm: x86: Move link to use driver model for video Update the configuration to use the new driver. Drop the existing plumbing code and unused header files. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile index 9cdb07b..498e71a 100644 --- a/arch/x86/cpu/ivybridge/Makefile +++ b/arch/x86/cpu/ivybridge/Makefile @@ -9,7 +9,6 @@ obj-y += fsp_configs.o ivybridge.o else obj-y += cpu.o obj-y += early_me.o -obj-y += gma.o obj-y += lpc.o obj-y += model_206ax.o obj-y += northbridge.o diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c index 5b58d6c..e63ea6b 100644 --- a/arch/x86/cpu/ivybridge/bd82x6x.c +++ b/arch/x86/cpu/ivybridge/bd82x6x.c @@ -9,14 +9,12 @@ #include #include #include -#include #include #include #include #include #include #include -#include #include #include #include @@ -155,22 +153,12 @@ void pch_iobp_update(struct udevice *dev, u32 address, u32 andvalue, static int bd82x6x_probe(struct udevice *dev) { - struct udevice *gma_dev; - int ret; - if (!(gd->flags & GD_FLG_RELOC)) return 0; /* Cause the SATA device to do its init */ uclass_first_device(UCLASS_AHCI, &dev); - ret = syscon_get_by_driver_data(X86_SYSCON_GMA, &gma_dev); - if (ret) - return ret; - ret = gma_func0_init(gma_dev); - if (ret) - return ret; - return 0; } #endif /* CONFIG_HAVE_FSP */ diff --git a/arch/x86/cpu/ivybridge/early_me.c b/arch/x86/cpu/ivybridge/early_me.c index cda96ab..5435a92 100644 --- a/arch/x86/cpu/ivybridge/early_me.c +++ b/arch/x86/cpu/ivybridge/early_me.c @@ -162,7 +162,6 @@ int intel_early_me_init_done(struct udevice *dev, struct udevice *me_dev, static const struct udevice_id ivybridge_syscon_ids[] = { { .compatible = "intel,me", .data = X86_SYSCON_ME }, - { .compatible = "intel,gma", .data = X86_SYSCON_GMA }, { } }; diff --git a/arch/x86/cpu/ivybridge/gma.c b/arch/x86/cpu/ivybridge/gma.c deleted file mode 100644 index 37e2e6e..0000000 --- a/arch/x86/cpu/ivybridge/gma.c +++ /dev/null @@ -1,850 +0,0 @@ -/* - * From Coreboot file of the same name - * - * Copyright (C) 2011 Chromium OS Authors - * - * SPDX-License-Identifier: GPL-2.0 - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -struct gt_powermeter { - u16 reg; - u32 value; -}; - -static const struct gt_powermeter snb_pm_gt1[] = { - { 0xa200, 0xcc000000 }, - { 0xa204, 0x07000040 }, - { 0xa208, 0x0000fe00 }, - { 0xa20c, 0x00000000 }, - { 0xa210, 0x17000000 }, - { 0xa214, 0x00000021 }, - { 0xa218, 0x0817fe19 }, - { 0xa21c, 0x00000000 }, - { 0xa220, 0x00000000 }, - { 0xa224, 0xcc000000 }, - { 0xa228, 0x07000040 }, - { 0xa22c, 0x0000fe00 }, - { 0xa230, 0x00000000 }, - { 0xa234, 0x17000000 }, - { 0xa238, 0x00000021 }, - { 0xa23c, 0x0817fe19 }, - { 0xa240, 0x00000000 }, - { 0xa244, 0x00000000 }, - { 0xa248, 0x8000421e }, - { 0 } -}; - -static const struct gt_powermeter snb_pm_gt2[] = { - { 0xa200, 0x330000a6 }, - { 0xa204, 0x402d0031 }, - { 0xa208, 0x00165f83 }, - { 0xa20c, 0xf1000000 }, - { 0xa210, 0x00000000 }, - { 0xa214, 0x00160016 }, - { 0xa218, 0x002a002b }, - { 0xa21c, 0x00000000 }, - { 0xa220, 0x00000000 }, - { 0xa224, 0x330000a6 }, - { 0xa228, 0x402d0031 }, - { 0xa22c, 0x00165f83 }, - { 0xa230, 0xf1000000 }, - { 0xa234, 0x00000000 }, - { 0xa238, 0x00160016 }, - { 0xa23c, 0x002a002b }, - { 0xa240, 0x00000000 }, - { 0xa244, 0x00000000 }, - { 0xa248, 0x8000421e }, - { 0 } -}; - -static const struct gt_powermeter ivb_pm_gt1[] = { - { 0xa800, 0x00000000 }, - { 0xa804, 0x00021c00 }, - { 0xa808, 0x00000403 }, - { 0xa80c, 0x02001700 }, - { 0xa810, 0x05000200 }, - { 0xa814, 0x00000000 }, - { 0xa818, 0x00690500 }, - { 0xa81c, 0x0000007f }, - { 0xa820, 0x01002501 }, - { 0xa824, 0x00000300 }, - { 0xa828, 0x01000331 }, - { 0xa82c, 0x0000000c }, - { 0xa830, 0x00010016 }, - { 0xa834, 0x01100101 }, - { 0xa838, 0x00010103 }, - { 0xa83c, 0x00041300 }, - { 0xa840, 0x00000b30 }, - { 0xa844, 0x00000000 }, - { 0xa848, 0x7f000000 }, - { 0xa84c, 0x05000008 }, - { 0xa850, 0x00000001 }, - { 0xa854, 0x00000004 }, - { 0xa858, 0x00000007 }, - { 0xa85c, 0x00000000 }, - { 0xa860, 0x00010000 }, - { 0xa248, 0x0000221e }, - { 0xa900, 0x00000000 }, - { 0xa904, 0x00001c00 }, - { 0xa908, 0x00000000 }, - { 0xa90c, 0x06000000 }, - { 0xa910, 0x09000200 }, - { 0xa914, 0x00000000 }, - { 0xa918, 0x00590000 }, - { 0xa91c, 0x00000000 }, - { 0xa920, 0x04002501 }, - { 0xa924, 0x00000100 }, - { 0xa928, 0x03000410 }, - { 0xa92c, 0x00000000 }, - { 0xa930, 0x00020000 }, - { 0xa934, 0x02070106 }, - { 0xa938, 0x00010100 }, - { 0xa93c, 0x00401c00 }, - { 0xa940, 0x00000000 }, - { 0xa944, 0x00000000 }, - { 0xa948, 0x10000e00 }, - { 0xa94c, 0x02000004 }, - { 0xa950, 0x00000001 }, - { 0xa954, 0x00000004 }, - { 0xa960, 0x00060000 }, - { 0xaa3c, 0x00001c00 }, - { 0xaa54, 0x00000004 }, - { 0xaa60, 0x00060000 }, - { 0 } -}; - -static const struct gt_powermeter ivb_pm_gt2[] = { - { 0xa800, 0x10000000 }, - { 0xa804, 0x00033800 }, - { 0xa808, 0x00000902 }, - { 0xa80c, 0x0c002f00 }, - { 0xa810, 0x12000400 }, - { 0xa814, 0x00000000 }, - { 0xa818, 0x00d20800 }, - { 0xa81c, 0x00000002 }, - { 0xa820, 0x03004b02 }, - { 0xa824, 0x00000600 }, - { 0xa828, 0x07000773 }, - { 0xa82c, 0x00000000 }, - { 0xa830, 0x00010032 }, - { 0xa834, 0x1520040d }, - { 0xa838, 0x00020105 }, - { 0xa83c, 0x00083700 }, - { 0xa840, 0x0000151d }, - { 0xa844, 0x00000000 }, - { 0xa848, 0x20001b00 }, - { 0xa84c, 0x0a000010 }, - { 0xa850, 0x00000000 }, - { 0xa854, 0x00000008 }, - { 0xa858, 0x00000008 }, - { 0xa85c, 0x00000000 }, - { 0xa860, 0x00020000 }, - { 0xa248, 0x0000221e }, - { 0xa900, 0x00000000 }, - { 0xa904, 0x00003500 }, - { 0xa908, 0x00000000 }, - { 0xa90c, 0x0c000000 }, - { 0xa910, 0x12000500 }, - { 0xa914, 0x00000000 }, - { 0xa918, 0x00b20000 }, - { 0xa91c, 0x00000000 }, - { 0xa920, 0x08004b02 }, - { 0xa924, 0x00000200 }, - { 0xa928, 0x07000820 }, - { 0xa92c, 0x00000000 }, - { 0xa930, 0x00030000 }, - { 0xa934, 0x050f020d }, - { 0xa938, 0x00020300 }, - { 0xa93c, 0x00903900 }, - { 0xa940, 0x00000000 }, - { 0xa944, 0x00000000 }, - { 0xa948, 0x20001b00 }, - { 0xa94c, 0x0a000010 }, - { 0xa950, 0x00000000 }, - { 0xa954, 0x00000008 }, - { 0xa960, 0x00110000 }, - { 0xaa3c, 0x00003900 }, - { 0xaa54, 0x00000008 }, - { 0xaa60, 0x00110000 }, - { 0 } -}; - -static const struct gt_powermeter ivb_pm_gt2_17w[] = { - { 0xa800, 0x20000000 }, - { 0xa804, 0x000e3800 }, - { 0xa808, 0x00000806 }, - { 0xa80c, 0x0c002f00 }, - { 0xa810, 0x0c000800 }, - { 0xa814, 0x00000000 }, - { 0xa818, 0x00d20d00 }, - { 0xa81c, 0x000000ff }, - { 0xa820, 0x03004b02 }, - { 0xa824, 0x00000600 }, - { 0xa828, 0x07000773 }, - { 0xa82c, 0x00000000 }, - { 0xa830, 0x00020032 }, - { 0xa834, 0x1520040d }, - { 0xa838, 0x00020105 }, - { 0xa83c, 0x00083700 }, - { 0xa840, 0x000016ff }, - { 0xa844, 0x00000000 }, - { 0xa848, 0xff000000 }, - { 0xa84c, 0x0a000010 }, - { 0xa850, 0x00000002 }, - { 0xa854, 0x00000008 }, - { 0xa858, 0x0000000f }, - { 0xa85c, 0x00000000 }, - { 0xa860, 0x00020000 }, - { 0xa248, 0x0000221e }, - { 0xa900, 0x00000000 }, - { 0xa904, 0x00003800 }, - { 0xa908, 0x00000000 }, - { 0xa90c, 0x0c000000 }, - { 0xa910, 0x12000800 }, - { 0xa914, 0x00000000 }, - { 0xa918, 0x00b20000 }, - { 0xa91c, 0x00000000 }, - { 0xa920, 0x08004b02 }, - { 0xa924, 0x00000300 }, - { 0xa928, 0x01000820 }, - { 0xa92c, 0x00000000 }, - { 0xa930, 0x00030000 }, - { 0xa934, 0x15150406 }, - { 0xa938, 0x00020300 }, - { 0xa93c, 0x00903900 }, - { 0xa940, 0x00000000 }, - { 0xa944, 0x00000000 }, - { 0xa948, 0x20001b00 }, - { 0xa94c, 0x0a000010 }, - { 0xa950, 0x00000000 }, - { 0xa954, 0x00000008 }, - { 0xa960, 0x00110000 }, - { 0xaa3c, 0x00003900 }, - { 0xaa54, 0x00000008 }, - { 0xaa60, 0x00110000 }, - { 0 } -}; - -static const struct gt_powermeter ivb_pm_gt2_35w[] = { - { 0xa800, 0x00000000 }, - { 0xa804, 0x00030400 }, - { 0xa808, 0x00000806 }, - { 0xa80c, 0x0c002f00 }, - { 0xa810, 0x0c000300 }, - { 0xa814, 0x00000000 }, - { 0xa818, 0x00d20d00 }, - { 0xa81c, 0x000000ff }, - { 0xa820, 0x03004b02 }, - { 0xa824, 0x00000600 }, - { 0xa828, 0x07000773 }, - { 0xa82c, 0x00000000 }, - { 0xa830, 0x00020032 }, - { 0xa834, 0x1520040d }, - { 0xa838, 0x00020105 }, - { 0xa83c, 0x00083700 }, - { 0xa840, 0x000016ff }, - { 0xa844, 0x00000000 }, - { 0xa848, 0xff000000 }, - { 0xa84c, 0x0a000010 }, - { 0xa850, 0x00000001 }, - { 0xa854, 0x00000008 }, - { 0xa858, 0x00000008 }, - { 0xa85c, 0x00000000 }, - { 0xa860, 0x00020000 }, - { 0xa248, 0x0000221e }, - { 0xa900, 0x00000000 }, - { 0xa904, 0x00003800 }, - { 0xa908, 0x00000000 }, - { 0xa90c, 0x0c000000 }, - { 0xa910, 0x12000800 }, - { 0xa914, 0x00000000 }, - { 0xa918, 0x00b20000 }, - { 0xa91c, 0x00000000 }, - { 0xa920, 0x08004b02 }, - { 0xa924, 0x00000300 }, - { 0xa928, 0x01000820 }, - { 0xa92c, 0x00000000 }, - { 0xa930, 0x00030000 }, - { 0xa934, 0x15150406 }, - { 0xa938, 0x00020300 }, - { 0xa93c, 0x00903900 }, - { 0xa940, 0x00000000 }, - { 0xa944, 0x00000000 }, - { 0xa948, 0x20001b00 }, - { 0xa94c, 0x0a000010 }, - { 0xa950, 0x00000000 }, - { 0xa954, 0x00000008 }, - { 0xa960, 0x00110000 }, - { 0xaa3c, 0x00003900 }, - { 0xaa54, 0x00000008 }, - { 0xaa60, 0x00110000 }, - { 0 } -}; - -/* - * Some vga option roms are used for several chipsets but they only have one - * PCI ID in their header. If we encounter such an option rom, we need to do - * the mapping ourselves. - */ - -u32 map_oprom_vendev(u32 vendev) -{ - u32 new_vendev = vendev; - - switch (vendev) { - case 0x80860102: /* GT1 Desktop */ - case 0x8086010a: /* GT1 Server */ - case 0x80860112: /* GT2 Desktop */ - case 0x80860116: /* GT2 Mobile */ - case 0x80860122: /* GT2 Desktop >=1.3GHz */ - case 0x80860126: /* GT2 Mobile >=1.3GHz */ - case 0x80860156: /* IVB */ - case 0x80860166: /* IVB */ - /* Set to GT1 Mobile */ - new_vendev = 0x80860106; - break; - } - - return new_vendev; -} - -static inline u32 gtt_read(void *bar, u32 reg) -{ - return readl(bar + reg); -} - -static inline void gtt_write(void *bar, u32 reg, u32 data) -{ - writel(data, bar + reg); -} - -static void gtt_write_powermeter(void *bar, const struct gt_powermeter *pm) -{ - for (; pm && pm->reg; pm++) - gtt_write(bar, pm->reg, pm->value); -} - -#define GTT_RETRY 1000 -static int gtt_poll(void *bar, u32 reg, u32 mask, u32 value) -{ - unsigned try = GTT_RETRY; - u32 data; - - while (try--) { - data = gtt_read(bar, reg); - if ((data & mask) == value) - return 1; - udelay(10); - } - - printf("GT init timeout\n"); - return 0; -} - -static int gma_pm_init_pre_vbios(void *gtt_bar, int rev) -{ - u32 reg32; - - debug("GT Power Management Init, silicon = %#x\n", rev); - - if (rev < IVB_STEP_C0) { - /* 1: Enable force wake */ - gtt_write(gtt_bar, 0xa18c, 0x00000001); - gtt_poll(gtt_bar, 0x130090, (1 << 0), (1 << 0)); - } else { - gtt_write(gtt_bar, 0xa180, 1 << 5); - gtt_write(gtt_bar, 0xa188, 0xffff0001); - gtt_poll(gtt_bar, 0x130040, (1 << 0), (1 << 0)); - } - - if ((rev & BASE_REV_MASK) == BASE_REV_SNB) { - /* 1d: Set GTT+0x42004 [15:14]=11 (SnB C1+) */ - reg32 = gtt_read(gtt_bar, 0x42004); - reg32 |= (1 << 14) | (1 << 15); - gtt_write(gtt_bar, 0x42004, reg32); - } - - if (rev >= IVB_STEP_A0) { - /* Display Reset Acknowledge Settings */ - reg32 = gtt_read(gtt_bar, 0x45010); - reg32 |= (1 << 1) | (1 << 0); - gtt_write(gtt_bar, 0x45010, reg32); - } - - /* 2: Get GT SKU from GTT+0x911c[13] */ - reg32 = gtt_read(gtt_bar, 0x911c); - if ((rev & BASE_REV_MASK) == BASE_REV_SNB) { - if (reg32 & (1 << 13)) { - debug("SNB GT1 Power Meter Weights\n"); - gtt_write_powermeter(gtt_bar, snb_pm_gt1); - } else { - debug("SNB GT2 Power Meter Weights\n"); - gtt_write_powermeter(gtt_bar, snb_pm_gt2); - } - } else { - u32 unit = readl(MCHBAR_REG(0x5938)) & 0xf; - - if (reg32 & (1 << 13)) { - /* GT1 SKU */ - debug("IVB GT1 Power Meter Weights\n"); - gtt_write_powermeter(gtt_bar, ivb_pm_gt1); - } else { - /* GT2 SKU */ - u32 tdp = readl(MCHBAR_REG(0x5930)) & 0x7fff; - tdp /= (1 << unit); - - if (tdp <= 17) { - /* <=17W ULV */ - debug("IVB GT2 17W Power Meter Weights\n"); - gtt_write_powermeter(gtt_bar, ivb_pm_gt2_17w); - } else if ((tdp >= 25) && (tdp <= 35)) { - /* 25W-35W */ - debug("IVB GT2 25W-35W Power Meter Weights\n"); - gtt_write_powermeter(gtt_bar, ivb_pm_gt2_35w); - } else { - /* All others */ - debug("IVB GT2 35W Power Meter Weights\n"); - gtt_write_powermeter(gtt_bar, ivb_pm_gt2_35w); - } - } - } - - /* 3: Gear ratio map */ - gtt_write(gtt_bar, 0xa004, 0x00000010); - - /* 4: GFXPAUSE */ - gtt_write(gtt_bar, 0xa000, 0x00070020); - - /* 5: Dynamic EU trip control */ - gtt_write(gtt_bar, 0xa080, 0x00000004); - - /* 6: ECO bits */ - reg32 = gtt_read(gtt_bar, 0xa180); - reg32 |= (1 << 26) | (1 << 31); - /* (bit 20=1 for SNB step D1+ / IVB A0+) */ - if (rev >= SNB_STEP_D1) - reg32 |= (1 << 20); - gtt_write(gtt_bar, 0xa180, reg32); - - /* 6a: for SnB step D2+ only */ - if (((rev & BASE_REV_MASK) == BASE_REV_SNB) && - (rev >= SNB_STEP_D2)) { - reg32 = gtt_read(gtt_bar, 0x9400); - reg32 |= (1 << 7); - gtt_write(gtt_bar, 0x9400, reg32); - - reg32 = gtt_read(gtt_bar, 0x941c); - reg32 &= 0xf; - reg32 |= (1 << 1); - gtt_write(gtt_bar, 0x941c, reg32); - gtt_poll(gtt_bar, 0x941c, (1 << 1), (0 << 1)); - } - - if ((rev & BASE_REV_MASK) == BASE_REV_IVB) { - reg32 = gtt_read(gtt_bar, 0x907c); - reg32 |= (1 << 16); - gtt_write(gtt_bar, 0x907c, reg32); - - /* 6b: Clocking reset controls */ - gtt_write(gtt_bar, 0x9424, 0x00000001); - } else { - /* 6b: Clocking reset controls */ - gtt_write(gtt_bar, 0x9424, 0x00000000); - } - - /* 7 */ - if (gtt_poll(gtt_bar, 0x138124, (1 << 31), (0 << 31))) { - gtt_write(gtt_bar, 0x138128, 0x00000029); /* Mailbox Data */ - /* Mailbox Cmd for RC6 VID */ - gtt_write(gtt_bar, 0x138124, 0x80000004); - if (gtt_poll(gtt_bar, 0x138124, (1 << 31), (0 << 31))) - gtt_write(gtt_bar, 0x138124, 0x8000000a); - gtt_poll(gtt_bar, 0x138124, (1 << 31), (0 << 31)); - } - - /* 8 */ - gtt_write(gtt_bar, 0xa090, 0x00000000); /* RC Control */ - gtt_write(gtt_bar, 0xa098, 0x03e80000); /* RC1e Wake Rate Limit */ - gtt_write(gtt_bar, 0xa09c, 0x0028001e); /* RC6/6p Wake Rate Limit */ - gtt_write(gtt_bar, 0xa0a0, 0x0000001e); /* RC6pp Wake Rate Limit */ - gtt_write(gtt_bar, 0xa0a8, 0x0001e848); /* RC Evaluation Interval */ - gtt_write(gtt_bar, 0xa0ac, 0x00000019); /* RC Idle Hysteresis */ - - /* 9 */ - gtt_write(gtt_bar, 0x2054, 0x0000000a); /* Render Idle Max Count */ - gtt_write(gtt_bar, 0x12054, 0x0000000a); /* Video Idle Max Count */ - gtt_write(gtt_bar, 0x22054, 0x0000000a); /* Blitter Idle Max Count */ - - /* 10 */ - gtt_write(gtt_bar, 0xa0b0, 0x00000000); /* Unblock Ack to Busy */ - gtt_write(gtt_bar, 0xa0b4, 0x000003e8); /* RC1e Threshold */ - gtt_write(gtt_bar, 0xa0b8, 0x0000c350); /* RC6 Threshold */ - gtt_write(gtt_bar, 0xa0bc, 0x000186a0); /* RC6p Threshold */ - gtt_write(gtt_bar, 0xa0c0, 0x0000fa00); /* RC6pp Threshold */ - - /* 11 */ - gtt_write(gtt_bar, 0xa010, 0x000f4240); /* RP Down Timeout */ - gtt_write(gtt_bar, 0xa014, 0x12060000); /* RP Interrupt Limits */ - gtt_write(gtt_bar, 0xa02c, 0x00015f90); /* RP Up Threshold */ - gtt_write(gtt_bar, 0xa030, 0x000186a0); /* RP Down Threshold */ - gtt_write(gtt_bar, 0xa068, 0x000186a0); /* RP Up EI */ - gtt_write(gtt_bar, 0xa06c, 0x000493e0); /* RP Down EI */ - gtt_write(gtt_bar, 0xa070, 0x0000000a); /* RP Idle Hysteresis */ - - /* 11a: Enable Render Standby (RC6) */ - if ((rev & BASE_REV_MASK) == BASE_REV_IVB) { - /* - * IvyBridge should also support DeepRenderStandby. - * - * Unfortunately it does not work reliably on all SKUs so - * disable it here and it can be enabled by the kernel. - */ - gtt_write(gtt_bar, 0xa090, 0x88040000); /* HW RC Control */ - } else { - gtt_write(gtt_bar, 0xa090, 0x88040000); /* HW RC Control */ - } - - /* 12: Normal Frequency Request */ - /* RPNFREQ_VAL comes from MCHBAR 0x5998 23:16 (8 bits!? use 7) */ - reg32 = readl(MCHBAR_REG(0x5998)); - reg32 >>= 16; - reg32 &= 0xef; - reg32 <<= 25; - gtt_write(gtt_bar, 0xa008, reg32); - - /* 13: RP Control */ - gtt_write(gtt_bar, 0xa024, 0x00000592); - - /* 14: Enable PM Interrupts */ - gtt_write(gtt_bar, 0x4402c, 0x03000076); - - /* Clear 0x6c024 [8:6] */ - reg32 = gtt_read(gtt_bar, 0x6c024); - reg32 &= ~0x000001c0; - gtt_write(gtt_bar, 0x6c024, reg32); - - return 0; -} - -int gma_pm_init_post_vbios(struct udevice *dev, int rev, void *gtt_bar) -{ - const void *blob = gd->fdt_blob; - int node = dev->of_offset; - u32 reg32, cycle_delay; - - debug("GT Power Management Init (post VBIOS)\n"); - - /* 15: Deassert Force Wake */ - if (rev < IVB_STEP_C0) { - gtt_write(gtt_bar, 0xa18c, gtt_read(gtt_bar, 0xa18c) & ~1); - gtt_poll(gtt_bar, 0x130090, (1 << 0), (0 << 0)); - } else { - gtt_write(gtt_bar, 0xa188, 0x1fffe); - if (gtt_poll(gtt_bar, 0x130040, (1 << 0), (0 << 0))) { - gtt_write(gtt_bar, 0xa188, - gtt_read(gtt_bar, 0xa188) | 1); - } - } - - /* 16: SW RC Control */ - gtt_write(gtt_bar, 0xa094, 0x00060000); - - /* Setup Digital Port Hotplug */ - reg32 = gtt_read(gtt_bar, 0xc4030); - if (!reg32) { - u32 dp_hotplug[3]; - - if (fdtdec_get_int_array(blob, node, "intel,dp_hotplug", - dp_hotplug, ARRAY_SIZE(dp_hotplug))) - return -EINVAL; - - reg32 = (dp_hotplug[0] & 0x7) << 2; - reg32 |= (dp_hotplug[0] & 0x7) << 10; - reg32 |= (dp_hotplug[0] & 0x7) << 18; - gtt_write(gtt_bar, 0xc4030, reg32); - } - - /* Setup Panel Power On Delays */ - reg32 = gtt_read(gtt_bar, 0xc7208); - if (!reg32) { - reg32 = (unsigned)fdtdec_get_int(blob, node, - "panel-port-select", 0) << 30; - reg32 |= fdtdec_get_int(blob, node, "panel-power-up-delay", 0) - << 16; - reg32 |= fdtdec_get_int(blob, node, - "panel-power-backlight-on-delay", 0); - gtt_write(gtt_bar, 0xc7208, reg32); - } - - /* Setup Panel Power Off Delays */ - reg32 = gtt_read(gtt_bar, 0xc720c); - if (!reg32) { - reg32 = fdtdec_get_int(blob, node, "panel-power-down-delay", 0) - << 16; - reg32 |= fdtdec_get_int(blob, node, - "panel-power-backlight-off-delay", 0); - gtt_write(gtt_bar, 0xc720c, reg32); - } - - /* Setup Panel Power Cycle Delay */ - cycle_delay = fdtdec_get_int(blob, node, - "intel,panel-power-cycle-delay", 0); - if (cycle_delay) { - reg32 = gtt_read(gtt_bar, 0xc7210); - reg32 &= ~0xff; - reg32 |= cycle_delay; - gtt_write(gtt_bar, 0xc7210, reg32); - } - - /* Enable Backlight if needed */ - reg32 = fdtdec_get_int(blob, node, "intel,cpu-backlight", 0); - if (reg32) { - gtt_write(gtt_bar, 0x48250, (1 << 31)); - gtt_write(gtt_bar, 0x48254, reg32); - } - reg32 = fdtdec_get_int(blob, node, "intel,pch-backlight", 0); - if (reg32) { - gtt_write(gtt_bar, 0xc8250, (1 << 31)); - gtt_write(gtt_bar, 0xc8254, reg32); - } - - return 0; -} - -/* - * Some vga option roms are used for several chipsets but they only have one - * PCI ID in their header. If we encounter such an option rom, we need to do - * the mapping ourselves. - */ - -uint32_t board_map_oprom_vendev(uint32_t vendev) -{ - switch (vendev) { - case 0x80860102: /* GT1 Desktop */ - case 0x8086010a: /* GT1 Server */ - case 0x80860112: /* GT2 Desktop */ - case 0x80860116: /* GT2 Mobile */ - case 0x80860122: /* GT2 Desktop >=1.3GHz */ - case 0x80860126: /* GT2 Mobile >=1.3GHz */ - case 0x80860156: /* IVB */ - case 0x80860166: /* IVB */ - return 0x80860106; /* GT1 Mobile */ - } - - return vendev; -} - -static int int15_handler(void) -{ - int res = 0; - - debug("%s: INT15 function %04x!\n", __func__, M.x86.R_AX); - - switch (M.x86.R_AX) { - case 0x5f34: - /* - * Set Panel Fitting Hook: - * bit 2 = Graphics Stretching - * bit 1 = Text Stretching - * bit 0 = Centering (do not set with bit1 or bit2) - * 0 = video bios default - */ - M.x86.R_AX = 0x005f; - M.x86.R_CL = 0x00; /* Use video bios default */ - res = 1; - break; - case 0x5f35: - /* - * Boot Display Device Hook: - * bit 0 = CRT - * bit 1 = TV (eDP) - * bit 2 = EFP - * bit 3 = LFP - * bit 4 = CRT2 - * bit 5 = TV2 (eDP) - * bit 6 = EFP2 - * bit 7 = LFP2 - */ - M.x86.R_AX = 0x005f; - M.x86.R_CX = 0x0000; /* Use video bios default */ - res = 1; - break; - case 0x5f51: - /* - * Hook to select active LFP configuration: - * 00h = No LVDS, VBIOS does not enable LVDS - * 01h = Int-LVDS, LFP driven by integrated LVDS decoder - * 02h = SVDO-LVDS, LFP driven by SVDO decoder - * 03h = eDP, LFP Driven by Int-DisplayPort encoder - */ - M.x86.R_AX = 0x005f; - M.x86.R_CX = 0x0003; /* eDP */ - res = 1; - break; - case 0x5f70: - switch (M.x86.R_CH) { - case 0: - /* Get Mux */ - M.x86.R_AX = 0x005f; - M.x86.R_CX = 0x0000; - res = 1; - break; - case 1: - /* Set Mux */ - M.x86.R_AX = 0x005f; - M.x86.R_CX = 0x0000; - res = 1; - break; - case 2: - /* Get SG/Non-SG mode */ - M.x86.R_AX = 0x005f; - M.x86.R_CX = 0x0000; - res = 1; - break; - default: - /* Interrupt was not handled */ - debug("Unknown INT15 5f70 function: 0x%02x\n", - M.x86.R_CH); - break; - } - break; - case 0x5fac: - res = 1; - break; - default: - debug("Unknown INT15 function %04x!\n", M.x86.R_AX); - break; - } - return res; -} - -void sandybridge_setup_graphics(struct udevice *dev, struct udevice *video_dev) -{ - u32 reg32; - u16 reg16; - u8 reg8; - - dm_pci_read_config16(video_dev, PCI_DEVICE_ID, ®16); - switch (reg16) { - case 0x0102: /* GT1 Desktop */ - case 0x0106: /* GT1 Mobile */ - case 0x010a: /* GT1 Server */ - case 0x0112: /* GT2 Desktop */ - case 0x0116: /* GT2 Mobile */ - case 0x0122: /* GT2 Desktop >=1.3GHz */ - case 0x0126: /* GT2 Mobile >=1.3GHz */ - case 0x0156: /* IvyBridge */ - case 0x0166: /* IvyBridge */ - break; - default: - debug("Graphics not supported by this CPU/chipset\n"); - return; - } - - debug("Initialising Graphics\n"); - - /* Setup IGD memory by setting GGC[7:3] = 1 for 32MB */ - dm_pci_read_config16(dev, GGC, ®16); - reg16 &= ~0x00f8; - reg16 |= 1 << 3; - /* Program GTT memory by setting GGC[9:8] = 2MB */ - reg16 &= ~0x0300; - reg16 |= 2 << 8; - /* Enable VGA decode */ - reg16 &= ~0x0002; - dm_pci_write_config16(dev, GGC, reg16); - - /* Enable 256MB aperture */ - dm_pci_read_config8(video_dev, MSAC, ®8); - reg8 &= ~0x06; - reg8 |= 0x02; - dm_pci_write_config8(video_dev, MSAC, reg8); - - /* Erratum workarounds */ - reg32 = readl(MCHBAR_REG(0x5f00)); - reg32 |= (1 << 9) | (1 << 10); - writel(reg32, MCHBAR_REG(0x5f00)); - - /* Enable SA Clock Gating */ - reg32 = readl(MCHBAR_REG(0x5f00)); - writel(reg32 | 1, MCHBAR_REG(0x5f00)); - - /* GPU RC6 workaround for sighting 366252 */ - reg32 = readl(MCHBAR_REG(0x5d14)); - reg32 |= (1 << 31); - writel(reg32, MCHBAR_REG(0x5d14)); - - /* VLW */ - reg32 = readl(MCHBAR_REG(0x6120)); - reg32 &= ~(1 << 0); - writel(reg32, MCHBAR_REG(0x6120)); - - reg32 = readl(MCHBAR_REG(0x5418)); - reg32 |= (1 << 4) | (1 << 5); - writel(reg32, MCHBAR_REG(0x5418)); -} - -int gma_func0_init(struct udevice *dev) -{ -#ifdef CONFIG_VIDEO - ulong start; -#endif - struct udevice *nbridge; - void *gtt_bar; - ulong base; - u32 reg32; - int ret; - int rev; - - /* Enable PCH Display Port */ - writew(0x0010, RCB_REG(DISPBDF)); - setbits_le32(RCB_REG(FD2), PCH_ENABLE_DBDF); - - ret = uclass_first_device_err(UCLASS_NORTHBRIDGE, &nbridge); - if (ret) - return ret; - rev = bridge_silicon_revision(nbridge); - sandybridge_setup_graphics(nbridge, dev); - - /* IGD needs to be Bus Master */ - dm_pci_read_config32(dev, PCI_COMMAND, ®32); - reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO; - dm_pci_write_config32(dev, PCI_COMMAND, reg32); - - /* Use write-combining for the graphics memory, 256MB */ - base = dm_pci_read_bar32(dev, 2); - mtrr_add_request(MTRR_TYPE_WRCOMB, base, 256 << 20); - mtrr_commit(true); - - gtt_bar = (void *)dm_pci_read_bar32(dev, 0); - debug("GT bar %p\n", gtt_bar); - ret = gma_pm_init_pre_vbios(gtt_bar, rev); - if (ret) - return ret; - -#ifdef CONFIG_VIDEO - start = get_timer(0); - ret = dm_pci_run_vga_bios(dev, int15_handler, - PCI_ROM_USE_NATIVE | PCI_ROM_ALLOW_FALLBACK); - debug("BIOS ran in %lums\n", get_timer(start)); -#endif - /* Post VBIOS init */ - ret = gma_pm_init_post_vbios(dev, rev, gtt_bar); - if (ret) - return ret; - - return 0; -} diff --git a/arch/x86/cpu/ivybridge/gma.h b/arch/x86/cpu/ivybridge/gma.h deleted file mode 100644 index e7ec649..0000000 --- a/arch/x86/cpu/ivybridge/gma.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * From Coreboot file of the same name - * - * Copyright (C) 2012 Chromium OS Authors - * - * SPDX-License-Identifier: GPL-2.0 - */ - -/* mailbox 0: header */ -__packed struct opregion_header { - u8 signature[16]; - u32 size; - u32 version; - u8 sbios_version[32]; - u8 vbios_version[16]; - u8 driver_version[16]; - u32 mailboxes; - u8 reserved[164]; -}; - -#define IGD_OPREGION_SIGNATURE "IntelGraphicsMem" -#define IGD_OPREGION_VERSION 2 - -#define IGD_MBOX1 (1 << 0) -#define IGD_MBOX2 (1 << 1) -#define IGD_MBOX3 (1 << 2) -#define IGD_MBOX4 (1 << 3) -#define IGD_MBOX5 (1 << 4) - -#define MAILBOXES_MOBILE (IGD_MBOX1 | IGD_MBOX2 | IGD_MBOX3 | \ - IGD_MBOX4 | IGD_MBOX5) -#define MAILBOXES_DESKTOP (IGD_MBOX2 | IGD_MBOX4) - -#define SBIOS_VERSION_SIZE 32 - -/* mailbox 1: public acpi methods */ -__packed struct opregion_mailbox1 { - u32 drdy; - u32 csts; - u32 cevt; - u8 reserved1[20]; - u32 didl[8]; - u32 cpdl[8]; - u32 cadl[8]; - u32 nadl[8]; - u32 aslp; - u32 tidx; - u32 chpd; - u32 clid; - u32 cdck; - u32 sxsw; - u32 evts; - u32 cnot; - u32 nrdy; - u8 reserved2[60]; -}; - -/* mailbox 2: software sci interface */ -__packed struct opregion_mailbox2 { - u32 scic; - u32 parm; - u32 dslp; - u8 reserved[244]; -}; - -/* mailbox 3: power conservation */ -__packed struct opregion_mailbox3 { - u32 ardy; - u32 aslc; - u32 tche; - u32 alsi; - u32 bclp; - u32 pfit; - u32 cblv; - u16 bclm[20]; - u32 cpfm; - u32 epfm; - u8 plut[74]; - u32 pfmb; - u32 ccdv; - u32 pcft; - u8 reserved[94]; -}; - -#define IGD_BACKLIGHT_BRIGHTNESS 0xff -#define IGD_INITIAL_BRIGHTNESS 0x64 - -#define IGD_FIELD_VALID (1 << 31) -#define IGD_WORD_FIELD_VALID (1 << 15) -#define IGD_PFIT_STRETCH 6 - -/* mailbox 4: vbt */ -__packed struct { - u8 gvd1[7168]; -} opregion_vbt_t; - -/* IGD OpRegion */ -__packed struct igd_opregion { - opregion_header_t header; - opregion_mailbox1_t mailbox1; - opregion_mailbox2_t mailbox2; - opregion_mailbox3_t mailbox3; - opregion_vbt_t vbt; -}; - -/* Intel Video BIOS (Option ROM) */ -__packed struct optionrom_header { - u16 signature; - u8 size; - u8 reserved[21]; - u16 pcir_offset; - u16 vbt_offset; -}; - -#define OPROM_SIGNATURE 0xaa55 - -__packed struct optionrom_pcir { - u32 signature; - u16 vendor; - u16 device; - u16 reserved1; - u16 length; - u8 revision; - u8 classcode[3]; - u16 imagelength; - u16 coderevision; - u8 codetype; - u8 indicator; - u16 reserved2; -}; - -__packed struct optionrom_vbt { - u8 hdr_signature[20]; - u16 hdr_version; - u16 hdr_size; - u16 hdr_vbt_size; - u8 hdr_vbt_checksum; - u8 hdr_reserved; - u32 hdr_vbt_datablock; - u32 hdr_aim[4]; - u8 datahdr_signature[16]; - u16 datahdr_version; - u16 datahdr_size; - u16 datahdr_datablocksize; - u8 coreblock_id; - u16 coreblock_size; - u16 coreblock_biossize; - u8 coreblock_biostype; - u8 coreblock_releasestatus; - u8 coreblock_hwsupported; - u8 coreblock_integratedhw; - u8 coreblock_biosbuild[4]; - u8 coreblock_biossignon[155]; -}; - -#define VBT_SIGNATURE 0x54425624 diff --git a/arch/x86/cpu/ivybridge/model_206ax.c b/arch/x86/cpu/ivybridge/model_206ax.c index 38e244b..b074367 100644 --- a/arch/x86/cpu/ivybridge/model_206ax.c +++ b/arch/x86/cpu/ivybridge/model_206ax.c @@ -20,7 +20,6 @@ #include #include #include -#include #include static void enable_vmx(void) diff --git a/arch/x86/cpu/ivybridge/sata.c b/arch/x86/cpu/ivybridge/sata.c index 1ce8195..87ff872 100644 --- a/arch/x86/cpu/ivybridge/sata.c +++ b/arch/x86/cpu/ivybridge/sata.c @@ -12,7 +12,6 @@ #include #include #include -#include DECLARE_GLOBAL_DATA_PTR; diff --git a/arch/x86/include/asm/arch-ivybridge/bd82x6x.h b/arch/x86/include/asm/arch-ivybridge/bd82x6x.h deleted file mode 100644 index e866580..0000000 --- a/arch/x86/include/asm/arch-ivybridge/bd82x6x.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (C) 2014 Google, Inc - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#ifndef _ASM_ARCH_BD82X6X_H -#define _ASM_ARCH_BD82X6X_H - -int gma_func0_init(struct udevice *dev); - -#endif diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h index 7892757..540024a 100644 --- a/arch/x86/include/asm/cpu.h +++ b/arch/x86/include/asm/cpu.h @@ -53,7 +53,6 @@ enum { enum { X86_NONE, X86_SYSCON_ME, /* Intel Management Engine */ - X86_SYSCON_GMA, /* Intel Graphics Media Accelerator */ X86_SYSCON_PINCONF, /* Intel x86 pin configuration */ }; diff --git a/configs/chromebook_link_defconfig b/configs/chromebook_link_defconfig index 8c91bfe..2475222 100644 --- a/configs/chromebook_link_defconfig +++ b/configs/chromebook_link_defconfig @@ -57,8 +57,10 @@ CONFIG_TPM_TIS_LPC=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_DM_VIDEO=y CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_11A=y +CONFIG_VIDEO_IVYBRIDGE_IGD=y CONFIG_USE_PRIVATE_LIBGCC=y CONFIG_TPM=y -- cgit v0.10.2 From 22d9574337f47d6a47f40dc1874291108ad30b41 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Sep 2016 21:33:05 -0600 Subject: Add _image_binary_end section declaration This is used in some link scripts, so add a declaration for it. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index 328bc62..d69bc60 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h @@ -82,6 +82,7 @@ extern ulong __data_end; extern ulong __rel_dyn_start; extern ulong __rel_dyn_end; extern ulong __bss_end; +extern ulong _image_binary_end; extern ulong _TEXT_BASE; /* code start */ -- cgit v0.10.2 From 2cd11a23c8e01503032df34b99d563603a54f4d9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Sep 2016 21:33:06 -0600 Subject: bios_emulator: Fix cast for 64-bit compilation Fix a cast that causes warnings on 64-bit machines. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/drivers/bios_emulator/atibios.c b/drivers/bios_emulator/atibios.c index 7717246..2d5b5dc 100644 --- a/drivers/bios_emulator/atibios.c +++ b/drivers/bios_emulator/atibios.c @@ -599,7 +599,7 @@ int biosemu_run(pci_dev_t pcidev, uchar *bios_rom, int bios_len, if (clean_up) { BE_exit(); if (vga_info->BIOSImage && - (u32)(vga_info->BIOSImage) != 0xc0000) + (ulong)(vga_info->BIOSImage) != 0xc0000) free(vga_info->BIOSImage); free(vga_info); vga_info = NULL; -- cgit v0.10.2 From 006bccbd0d757da78bfd2a244d96f61e0f7d2c66 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Sep 2016 21:33:07 -0600 Subject: board_f: Drop the extra fdtdec_prepare_fdt() This is already called earlier, from fdtdec_setup(), so drop this unnecessary call from the init sequence. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/common/board_f.c b/common/board_f.c index 1b88822..4b74835 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -912,9 +912,6 @@ static init_fnc_t init_sequence_f[] = { #ifdef CONFIG_SANDBOX sandbox_early_getopt_check, #endif -#ifdef CONFIG_OF_CONTROL - fdtdec_prepare_fdt, -#endif display_options, /* say that we are here */ display_text_info, /* show debugging info if required */ #if defined(CONFIG_MPC8260) -- cgit v0.10.2 From 2547f3ed897b0ce252db0ffb8596ec9730ea1833 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Sep 2016 21:33:09 -0600 Subject: elf: Add the Elf64_Rela type Add this so that we can support 64-bit relocation on x86. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/include/elf.h b/include/elf.h index a35e085..bcc5eb7 100644 --- a/include/elf.h +++ b/include/elf.h @@ -394,6 +394,12 @@ typedef struct { Elf64_Xword r_info; /* index and type of relocation */ } Elf64_Rel; +typedef struct { + Elf64_Addr r_offset; /* Location at which to apply the action */ + Elf64_Xword r_info; /* index and type of relocation */ + Elf64_Sxword r_addend; /* Constant addend used to compute value */ +} Elf64_Rela; + /* Extract relocation info - r_info */ #define ELF32_R_SYM(i) ((i) >> 8) #define ELF32_R_TYPE(i) ((unsigned char) (i)) -- cgit v0.10.2 From 3f14f814e79f5160e91a107fcac56d577867feac Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Sep 2016 21:33:11 -0600 Subject: rtc: Use CONFIG_X86 instead of __I386__ For 64-bit x86, __I386__ should perhaps not be defined. It is not clear from the definition, but let's use CONFIG_X86 to be sure. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c index da804d5..4df9eda 100644 --- a/drivers/rtc/mc146818.c +++ b/drivers/rtc/mc146818.c @@ -14,7 +14,7 @@ #include #include -#if defined(__I386__) || defined(CONFIG_MALTA) +#if defined(CONFIG_X86) || defined(CONFIG_MALTA) #include #define in8(p) inb(p) #define out8(p, v) outb(v, p) -- cgit v0.10.2 From 22230e916e1d57364c524058275befa380faabc3 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Sep 2016 21:33:20 -0600 Subject: tpm: Tidy up use of size_t We should consistently use %z with size_t, and avoid passing a uint32_t as a size_t value. Fix these issues to avoid warnings on 64-bit machines. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/drivers/tpm/tpm_tis_lpc.c b/drivers/tpm/tpm_tis_lpc.c index 257d035..b4efbb5 100644 --- a/drivers/tpm/tpm_tis_lpc.c +++ b/drivers/tpm/tpm_tis_lpc.c @@ -204,7 +204,7 @@ static int tis_senddata(struct udevice *dev, const u8 *data, size_t len) /* Wait till the device is ready to accept more data. */ while (!burst) { if (max_cycles++ == MAX_DELAY_US) { - printf("%s:%d failed to feed %d bytes of %d\n", + printf("%s:%d failed to feed %zd bytes of %zd\n", __FILE__, __LINE__, len - offset, len); return -ETIMEDOUT; } @@ -224,7 +224,7 @@ static int tis_senddata(struct udevice *dev, const u8 *data, size_t len) * changes to zero exactly after the last byte is fed into the * FIFO. */ - count = min((u32)burst, len - offset - 1); + count = min((size_t)burst, len - offset - 1); while (count--) tpm_write_byte(priv, data[offset++], ®s[locality].data); -- cgit v0.10.2 From b11e2984401ff8a4f53d6d4c6363af4c9a4ec336 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Sep 2016 21:33:21 -0600 Subject: usb: pci: Fix cast for 64-bit compilation Fix a cast that causes warnings on 64-bit machines. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 6fc2479..f20fc33 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c @@ -32,8 +32,8 @@ static void ehci_pci_init(struct udevice *dev, struct ehci_hccr **ret_hccr, hcor = (struct ehci_hcor *)((uintptr_t) hccr + HC_LENGTH(ehci_readl(&hccr->cr_capbase))); - debug("EHCI-PCI init hccr 0x%x and hcor 0x%x hc_length %d\n", - (u32)hccr, (u32)hcor, + debug("EHCI-PCI init hccr %#lx and hcor %#lx hc_length %d\n", + (ulong)hccr, (ulong)hcor, (u32)HC_LENGTH(ehci_readl(&hccr->cr_capbase))); *ret_hccr = hccr; -- cgit v0.10.2 From 35233da98a53eb95a28d16d3fd836801b84015a9 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Sep 2016 21:33:23 -0600 Subject: x86: Allow interrupts to be disabled in 64-bit mode Update the code to support both 32-bit and 64-bit modes. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c index dd2819a..46babe0 100644 --- a/arch/x86/cpu/interrupts.c +++ b/arch/x86/cpu/interrupts.c @@ -238,8 +238,11 @@ int disable_interrupts(void) { long flags; +#ifdef CONFIG_X86_64 + asm volatile ("pushfq ; popq %0 ; cli\n" : "=g" (flags) : ); +#else asm volatile ("pushfl ; popl %0 ; cli\n" : "=g" (flags) : ); - +#endif return flags & X86_EFLAGS_IF; } -- cgit v0.10.2 From d30b3103a56b5340f85dfadfb6ef52626700ee67 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Sep 2016 21:33:24 -0600 Subject: x86: Correct address casts in cpu code We should cast an address to unsigned long, not u32. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c index 269043d..7c1d6de 100644 --- a/arch/x86/cpu/cpu.c +++ b/arch/x86/cpu/cpu.c @@ -135,7 +135,7 @@ static void load_gdt(const u64 *boot_gdt, u16 num_entries) struct gdt_ptr gdt; gdt.len = (num_entries * X86_GDT_ENTRY_SIZE) - 1; - gdt.ptr = (u32)boot_gdt; + gdt.ptr = (ulong)boot_gdt; asm volatile("lgdtl %0\n" : : "m" (gdt)); } @@ -630,13 +630,11 @@ static void build_pagetable(uint32_t *pgtable) memset(pgtable, '\0', PAGETABLE_SIZE); /* Level 4 needs a single entry */ - pgtable[0] = (uint32_t)&pgtable[1024] + 7; + pgtable[0] = (ulong)&pgtable[1024] + 7; /* Level 3 has one 64-bit entry for each GiB of memory */ - for (i = 0; i < 4; i++) { - pgtable[1024 + i * 2] = (uint32_t)&pgtable[2048] + - 0x1000 * i + 7; - } + for (i = 0; i < 4; i++) + pgtable[1024 + i * 2] = (ulong)&pgtable[2048] + 0x1000 * i + 7; /* Level 2 has 2048 64-bit entries, each repesenting 2MiB */ for (i = 0; i < 2048; i++) -- cgit v0.10.2 From 21b3b66acece160c12166b8bcb5511af5c065cef Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Sep 2016 21:33:25 -0600 Subject: x86: Correct address casts in interrupt code We should cast an address to unsigned long, not u32. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/cpu/interrupts.c b/arch/x86/cpu/interrupts.c index 46babe0..5f6cdd3 100644 --- a/arch/x86/cpu/interrupts.c +++ b/arch/x86/cpu/interrupts.c @@ -182,8 +182,8 @@ static inline void load_idt(const struct desc_ptr *dtr) void set_vector(u8 intnum, void *routine) { - idt[intnum].base_high = (u16)((u32)(routine) >> 16); - idt[intnum].base_low = (u16)((u32)(routine) & 0xffff); + idt[intnum].base_high = (u16)((ulong)(routine) >> 16); + idt[intnum].base_low = (u16)((ulong)(routine) & 0xffff); } /* -- cgit v0.10.2 From fac3e796b915226e2dc92363826824be1589c3ef Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Sep 2016 21:33:30 -0600 Subject: x86: i2c: Fix cast of address to 32-bit value This gives a build warning on 64-bit x86. Fix it. Signed-off-by: Simon Glass Acked-by: Heiko Schocher Reviewed-by: Bin Meng diff --git a/drivers/i2c/intel_i2c.c b/drivers/i2c/intel_i2c.c index a0182dc..550a728 100644 --- a/drivers/i2c/intel_i2c.c +++ b/drivers/i2c/intel_i2c.c @@ -248,11 +248,11 @@ static int intel_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) static int intel_i2c_probe(struct udevice *dev) { struct intel_i2c *priv = dev_get_priv(dev); - u32 base; + ulong base; /* Save base address from PCI BAR */ - priv->base = (u32)dm_pci_map_bar(dev, PCI_BASE_ADDRESS_4, - PCI_REGION_IO); + priv->base = (ulong)dm_pci_map_bar(dev, PCI_BASE_ADDRESS_4, + PCI_REGION_IO); base = priv->base; /* Set SMBus enable. */ -- cgit v0.10.2 From 5d7ec3d8d3f09293824d1486b33cbe578e896996 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Sep 2016 21:33:31 -0600 Subject: x86: Don't export interrupt handlers with x86_64 We don't have a way of adjusting these at present so it is best to refuse to export these functions. This can be implemented later if the API is required. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/include/_exports.h b/include/_exports.h index 1584705..6ff4364 100644 --- a/include/_exports.h +++ b/include/_exports.h @@ -13,7 +13,7 @@ EXPORT_FUNC(putc, void, putc, const char) EXPORT_FUNC(puts, void, puts, const char *) EXPORT_FUNC(printf, int, printf, const char*, ...) -#if defined(CONFIG_X86) || defined(CONFIG_PPC) +#if (defined(CONFIG_X86) && !defined(CONFIG_X86_64)) || defined(CONFIG_PPC) EXPORT_FUNC(irq_install_handler, void, install_hdlr, int, interrupt_handler_t, void*) -- cgit v0.10.2 From 4e0318c32f01e5178f9ddd29313fcb24a1584dd6 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Sep 2016 21:33:34 -0600 Subject: x86: ivybridge: Fix PCH power setup At present pch_power_options() has the arguments to writel() around the wrong way. Fix this and update it to compile on 64-bit machines. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/cpu/ivybridge/lpc.c b/arch/x86/cpu/ivybridge/lpc.c index 4e0be2a..91c9c0e 100644 --- a/arch/x86/cpu/ivybridge/lpc.c +++ b/arch/x86/cpu/ivybridge/lpc.c @@ -213,10 +213,10 @@ static int pch_power_options(struct udevice *pch) dm_pci_read_config16(pch, 0x40, &pmbase); pmbase &= 0xfffe; - writel(pmbase + GPE0_EN, fdtdec_get_int(blob, node, - "intel,gpe0-enable", 0)); - writew(pmbase + ALT_GP_SMI_EN, fdtdec_get_int(blob, node, - "intel,alt-gp-smi-enable", 0)); + writel(fdtdec_get_int(blob, node, "intel,gpe0-enable", 0), + (ulong)pmbase + GPE0_EN); + writew(fdtdec_get_int(blob, node, "intel,alt-gp-smi-enable", 0), + (ulong)pmbase + ALT_GP_SMI_EN); /* Set up power management block and determine sleep mode */ reg32 = inl(pmbase + 0x04); /* PM1_CNT */ -- cgit v0.10.2 From 2545fa59f89294875db94f5edbd9e435cdd36c4f Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Sep 2016 21:33:35 -0600 Subject: x86: ivybridge: Tidy up enable_clock_gating() for 64-bit Fix the hex case and remove unused brackets. Use ~0U instead of ~0UL to allow compilation on 64-bit machines. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/cpu/ivybridge/lpc.c b/arch/x86/cpu/ivybridge/lpc.c index 91c9c0e..4af89b3 100644 --- a/arch/x86/cpu/ivybridge/lpc.c +++ b/arch/x86/cpu/ivybridge/lpc.c @@ -355,10 +355,10 @@ static void enable_clock_gating(struct udevice *pch) reg16 |= (1 << 2) | (1 << 11); dm_pci_write_config16(pch, GEN_PMCON_1, reg16); - pch_iobp_update(pch, 0xEB007F07, ~0UL, (1 << 31)); - pch_iobp_update(pch, 0xEB004000, ~0UL, (1 << 7)); - pch_iobp_update(pch, 0xEC007F07, ~0UL, (1 << 31)); - pch_iobp_update(pch, 0xEC004000, ~0UL, (1 << 7)); + pch_iobp_update(pch, 0xeb007f07, ~0U, 1 << 31); + pch_iobp_update(pch, 0xeb004000, ~0U, 1 << 7); + pch_iobp_update(pch, 0xec007f07, ~0U, 1 << 31); + pch_iobp_update(pch, 0xec004000, ~0U, 1 << 7); reg32 = readl(RCB_REG(CG)); reg32 |= (1 << 31); -- cgit v0.10.2 From 9b43dbfb91e0884b817405b3b2985259cabb4ce8 Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Sep 2016 21:33:38 -0600 Subject: x86: Drop unused init_helper functions Drop init_bd_struct_r() which is no-longer used. Also drop the declaration for init_func_spi() since this is now handled by generic board init. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/include/asm/init_helpers.h b/arch/x86/include/asm/init_helpers.h index c689a63..ef05ac4 100644 --- a/arch/x86/include/asm/init_helpers.h +++ b/arch/x86/include/asm/init_helpers.h @@ -9,7 +9,5 @@ #define _INIT_HELPERS_H_ int init_cache_f_r(void); -int init_bd_struct_r(void); -int init_func_spi(void); #endif /* !_INIT_HELPERS_H_ */ diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c index bac671d..2a186fc 100644 --- a/arch/x86/lib/init_helpers.c +++ b/arch/x86/lib/init_helpers.c @@ -30,13 +30,3 @@ int init_cache_f_r(void) /* Initialise the CPU cache(s) */ return init_cache(); } - -bd_t bd_data; - -int init_bd_struct_r(void) -{ - gd->bd = &bd_data; - memset(gd->bd, 0, sizeof(bd_t)); - - return 0; -} -- cgit v0.10.2 From 54cd240731f904b5632e384e6d5b21777e36d86a Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Sun, 25 Sep 2016 21:33:40 -0600 Subject: x86: mrccache: Fix error handling in mrccache_get_region() This should return normal errors, not device-tree errors. Fix it. Signed-off-by: Simon Glass Reviewed-by: Bin Meng diff --git a/arch/x86/lib/mrccache.c b/arch/x86/lib/mrccache.c index 67bace4..eca88ac 100644 --- a/arch/x86/lib/mrccache.c +++ b/arch/x86/lib/mrccache.c @@ -198,11 +198,13 @@ int mrccache_get_region(struct udevice **devp, struct mrc_region *entry) /* Find the flash chip within the SPI controller node */ node = fdtdec_next_compatible(blob, 0, COMPAT_GENERIC_SPI_FLASH); - if (node < 0) + if (node < 0) { + debug("%s: Cannot find SPI flash\n", __func__); return -ENOENT; + } if (fdtdec_get_int_array(blob, node, "memory-map", reg, 2)) - return -FDT_ERR_NOTFOUND; + return -EINVAL; entry->base = reg[0]; /* Find the place where we put the MRC cache */ @@ -211,7 +213,7 @@ int mrccache_get_region(struct udevice **devp, struct mrc_region *entry) return -EPERM; if (fdtdec_get_int_array(blob, mrc_node, "reg", reg, 2)) - return -FDT_ERR_NOTFOUND; + return -EINVAL; entry->offset = reg[0]; entry->length = reg[1]; -- cgit v0.10.2 From 4dc5e54da31c810c988a0122fcd50b7d6f70354a Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 9 Oct 2016 04:14:10 -0700 Subject: x86: doc: Document coreboot framebuffer driver issue on QEMU For some unknown reason, coreboot framebuffer driver never works on QEMU since day 1. It seems the driver only works on real hardware. Document this issue. Signed-off-by: Bin Meng Reviewed-by: Simon Glass diff --git a/doc/README.x86 b/doc/README.x86 index ba5bb99..437dc29 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -385,6 +385,9 @@ At present it seems that for Minnowboard Max, coreboot does not pass through the video information correctly (it always says the resolution is 0x0). This works correctly for link though. +Note: coreboot framebuffer driver does not work on QEMU. The reason is unknown +at this point. Patches are welcome if you figure out anything wrong. + Test with QEMU for bare mode ---------------------------- QEMU is a fancy emulator that can enable us to test U-Boot without access to -- cgit v0.10.2 From 02c57abd5079dec2311cf51e785bd2090b7bb440 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 9 Oct 2016 04:14:11 -0700 Subject: dm: video: Add driver for VESA-compatible device This adds a DM driver for VESA-compatible device. Signed-off-by: Bin Meng Reviewed-by: Simon Glass diff --git a/drivers/video/vesa.c b/drivers/video/vesa.c new file mode 100644 index 0000000..ddf8df8 --- /dev/null +++ b/drivers/video/vesa.c @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2016, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include + +static int vesa_video_probe(struct udevice *dev) +{ + return vbe_setup_video(dev, NULL); +} + +static const struct udevice_id vesa_video_ids[] = { + { .compatible = "vesa-fb" }, + { } +}; + +U_BOOT_DRIVER(vesa_video) = { + .name = "vesa_video", + .id = UCLASS_VIDEO, + .of_match = vesa_video_ids, + .probe = vesa_video_probe, +}; + +static struct pci_device_id vesa_video_supported[] = { + { PCI_DEVICE_CLASS(PCI_CLASS_DISPLAY_VGA << 8, ~0) }, + { }, +}; + +U_BOOT_PCI_DEVICE(vesa_video, vesa_video_supported); -- cgit v0.10.2 From f0920e4a4498294bf8328db37638f47bccf04b3f Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 9 Oct 2016 04:14:12 -0700 Subject: dm: video: Output verbose information in vbe_setup_video() With DM conversion, information like "Video: 1024x768x16" is not shown anymore. Now add these verbose output back. Signed-off-by: Bin Meng Reviewed-by: Simon Glass diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 21ed17c..5746c3d 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -382,9 +382,13 @@ int vbe_setup_video(struct udevice *dev, int (*int15_handler)(void)) struct video_priv *uc_priv = dev_get_uclass_priv(dev); int ret; + printf("Video: "); + /* If we are running from EFI or coreboot, this can't work */ - if (!ll_boot_init()) + if (!ll_boot_init()) { + printf("Not available (previous bootloader prevents it)\n"); return -EPERM; + } bootstage_start(BOOTSTAGE_ID_ACCUM_LCD, "vesa display"); ret = dm_pci_run_vga_bios(dev, int15_handler, PCI_ROM_USE_NATIVE | PCI_ROM_ALLOW_FALLBACK); @@ -400,6 +404,9 @@ int vbe_setup_video(struct udevice *dev, int (*int15_handler)(void)) return ret; } + printf("%dx%dx%d\n", uc_priv->xsize, uc_priv->ysize, + mode_info.vesa.bits_per_pixel); + return 0; } #endif -- cgit v0.10.2 From fcda8c388699d8602158aa16a1e9c607dac93df9 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 9 Oct 2016 04:14:13 -0700 Subject: x86: Convert to use DM VESA video driver At present only chromebook boards are converted to DM video. Other x86 boards are still using the legacy cfb_console driver. This switches to use DM version drivers. Signed-off-by: Bin Meng Reviewed-by: Simon Glass diff --git a/configs/bayleybay_defconfig b/configs/bayleybay_defconfig index 64e3d31..f8f5f5c 100644 --- a/configs/bayleybay_defconfig +++ b/configs/bayleybay_defconfig @@ -53,6 +53,7 @@ CONFIG_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_DM_VIDEO=y CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_11A=y diff --git a/configs/chromebox_panther_defconfig b/configs/chromebox_panther_defconfig index 2557d35..6df4d4c 100644 --- a/configs/chromebox_panther_defconfig +++ b/configs/chromebox_panther_defconfig @@ -49,6 +49,7 @@ CONFIG_TPM_TIS_LPC=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_DM_VIDEO=y CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_11A=y diff --git a/configs/conga-qeval20-qa3-e3845-internal-uart_defconfig b/configs/conga-qeval20-qa3-e3845-internal-uart_defconfig index f0da176..6bee9c6 100644 --- a/configs/conga-qeval20-qa3-e3845-internal-uart_defconfig +++ b/configs/conga-qeval20-qa3-e3845-internal-uart_defconfig @@ -61,6 +61,7 @@ CONFIG_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_DM_VIDEO=y CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_114=y diff --git a/configs/conga-qeval20-qa3-e3845_defconfig b/configs/conga-qeval20-qa3-e3845_defconfig index 63c2cbd..76ff904 100644 --- a/configs/conga-qeval20-qa3-e3845_defconfig +++ b/configs/conga-qeval20-qa3-e3845_defconfig @@ -60,6 +60,7 @@ CONFIG_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_DM_VIDEO=y CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_114=y diff --git a/configs/crownbay_defconfig b/configs/crownbay_defconfig index d0cd9db..b37fce7 100644 --- a/configs/crownbay_defconfig +++ b/configs/crownbay_defconfig @@ -47,6 +47,7 @@ CONFIG_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_DM_VIDEO=y CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_USE_PRIVATE_LIBGCC=y diff --git a/configs/dfi-bt700-q7x-151_defconfig b/configs/dfi-bt700-q7x-151_defconfig index 245d0c7..3931896 100644 --- a/configs/dfi-bt700-q7x-151_defconfig +++ b/configs/dfi-bt700-q7x-151_defconfig @@ -58,6 +58,7 @@ CONFIG_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_DM_VIDEO=y CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_114=y diff --git a/configs/minnowmax_defconfig b/configs/minnowmax_defconfig index 3d3a30d..1446ab6 100644 --- a/configs/minnowmax_defconfig +++ b/configs/minnowmax_defconfig @@ -57,6 +57,7 @@ CONFIG_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_DM_VIDEO=y CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_11A=y diff --git a/configs/qemu-x86_defconfig b/configs/qemu-x86_defconfig index 769adf6..4cf0866 100644 --- a/configs/qemu-x86_defconfig +++ b/configs/qemu-x86_defconfig @@ -44,6 +44,7 @@ CONFIG_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_DM_VIDEO=y CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_111=y diff --git a/configs/qemu-x86_efi_payload32_defconfig b/configs/qemu-x86_efi_payload32_defconfig index 75e7203..fd6afb8 100644 --- a/configs/qemu-x86_efi_payload32_defconfig +++ b/configs/qemu-x86_efi_payload32_defconfig @@ -41,6 +41,7 @@ CONFIG_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_DM_VIDEO=y CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_111=y diff --git a/configs/qemu-x86_efi_payload64_defconfig b/configs/qemu-x86_efi_payload64_defconfig index 4bcd0dc..c6664b0 100644 --- a/configs/qemu-x86_efi_payload64_defconfig +++ b/configs/qemu-x86_efi_payload64_defconfig @@ -41,6 +41,7 @@ CONFIG_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_DM_VIDEO=y CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_111=y diff --git a/configs/som-db5800-som-6867_defconfig b/configs/som-db5800-som-6867_defconfig index 4cfaeda..9fc169d 100644 --- a/configs/som-db5800-som-6867_defconfig +++ b/configs/som-db5800-som-6867_defconfig @@ -55,6 +55,7 @@ CONFIG_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_DM_VIDEO=y CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_11A=y diff --git a/configs/theadorable-x86-dfi-bt700_defconfig b/configs/theadorable-x86-dfi-bt700_defconfig index cea91b6..43dc2fa 100644 --- a/configs/theadorable-x86-dfi-bt700_defconfig +++ b/configs/theadorable-x86-dfi-bt700_defconfig @@ -55,6 +55,7 @@ CONFIG_TIMER=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_DM_VIDEO=y CONFIG_VIDEO_VESA=y CONFIG_FRAMEBUFFER_SET_VESA_MODE=y CONFIG_FRAMEBUFFER_VESA_MODE_114=y diff --git a/drivers/video/Makefile b/drivers/video/Makefile index b888e99..8a99d24 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -58,7 +58,7 @@ obj-$(CONFIG_VIDEO_SMI_LYNXEM) += smiLynxEM.o videomodes.o obj-$(CONFIG_VIDEO_SUNXI) += sunxi_display.o videomodes.o obj-$(CONFIG_VIDEO_TEGRA20) += tegra.o obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o -obj-$(CONFIG_VIDEO_VESA) += vesa_fb.o +obj-$(CONFIG_VIDEO_VESA) += vesa.o obj-$(CONFIG_FORMIKE) += formike.o obj-$(CONFIG_LG4573) += lg4573.o obj-$(CONFIG_AM335X_LCD) += am335x-fb.o diff --git a/include/configs/bayleybay.h b/include/configs/bayleybay.h index 8f31436..40b13d1 100644 --- a/include/configs/bayleybay.h +++ b/include/configs/bayleybay.h @@ -18,9 +18,9 @@ #define CONFIG_PCI_PNP -#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,vga,usbkbd\0" \ - "stdout=serial,vga\0" \ - "stderr=serial,vga\0" +#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,usbkbd\0" \ + "stdout=serial,vidconsole\0" \ + "stderr=serial,vidconsole\0" #define CONFIG_SCSI_DEV_LIST \ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA}, \ diff --git a/include/configs/crownbay.h b/include/configs/crownbay.h index 49ed3ef..64ad736 100644 --- a/include/configs/crownbay.h +++ b/include/configs/crownbay.h @@ -22,8 +22,8 @@ #define CONFIG_PCI_PNP #define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,i8042-kbd,usbkbd\0" \ - "stdout=serial,vga\0" \ - "stderr=serial,vga\0" + "stdout=serial,vidconsole\0" \ + "stderr=serial,vidconsole\0" #define CONFIG_SCSI_DEV_LIST \ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TCF_SATA} diff --git a/include/configs/minnowmax.h b/include/configs/minnowmax.h index 95ad128..935c88d 100644 --- a/include/configs/minnowmax.h +++ b/include/configs/minnowmax.h @@ -20,9 +20,9 @@ #define CONFIG_SMSC_LPC47M #define CONFIG_PCI_PNP -#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \ - "stdout=vga,serial\0" \ - "stderr=vga,serial\0" +#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,serial\0" \ + "stdout=vidconsole,serial\0" \ + "stderr=vidconsole,serial\0" #define CONFIG_SCSI_DEV_LIST \ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA}, \ diff --git a/include/configs/qemu-x86.h b/include/configs/qemu-x86.h index 476d37d..a2dd79b 100644 --- a/include/configs/qemu-x86.h +++ b/include/configs/qemu-x86.h @@ -19,8 +19,8 @@ #define CONFIG_PCI_PNP #define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,i8042-kbd\0" \ - "stdout=serial,vga\0" \ - "stderr=serial,vga\0" + "stdout=serial,vidconsole\0" \ + "stderr=serial,vidconsole\0" /* * ATA/SATA support for QEMU x86 targets diff --git a/include/configs/som-db5800-som-6867.h b/include/configs/som-db5800-som-6867.h index a4b343e..a13be14 100644 --- a/include/configs/som-db5800-som-6867.h +++ b/include/configs/som-db5800-som-6867.h @@ -19,9 +19,9 @@ #define CONFIG_ARCH_MISC_INIT #define CONFIG_PCI_PNP -#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,usbkbd,vga\0" \ - "stdout=serial,vga\0" \ - "stderr=serial,vga\0" +#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,usbkbd\0" \ + "stdout=serial,vidconsole\0" \ + "stderr=serial,vidconsole\0" #define CONFIG_SCSI_DEV_LIST \ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_VALLEYVIEW_SATA}, \ -- cgit v0.10.2 From 10491c838ebed4d5e1fec4655b8bf2de48c6328e Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 9 Oct 2016 04:14:14 -0700 Subject: x86: doc: Correct qfw command example The kernel load address for zboot should be 0x1000000. Signed-off-by: Bin Meng Reviewed-by: Simon Glass diff --git a/doc/README.x86 b/doc/README.x86 index 437dc29..c34f455 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -449,7 +449,7 @@ loading kernel to address 01000000 size 5d9d30 initrd 04000000 size 1b1ab50 Here the kernel (bzImage) is loaded to 01000000 and initrd is to 04000000. Then, 'zboot' can be used to boot the kernel: -=> zboot 02000000 - 04000000 1b1ab50 +=> zboot 01000000 - 04000000 1b1ab50 CPU Microcode ------------- -- cgit v0.10.2 From 5f6ad029f31e897fa8bd62d3f42092e051932bc2 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 9 Oct 2016 04:14:15 -0700 Subject: vbe: Make vbe_setup_video_priv() public vbe_setup_video_priv() might be useful to other drivers. Signed-off-by: Bin Meng Reviewed-by: Simon Glass diff --git a/drivers/pci/pci_rom.c b/drivers/pci/pci_rom.c index 5746c3d..cd083f7 100644 --- a/drivers/pci/pci_rom.c +++ b/drivers/pci/pci_rom.c @@ -351,9 +351,9 @@ err: } #ifdef CONFIG_DM_VIDEO -static int vbe_setup_video_priv(struct vesa_mode_info *vesa, - struct video_priv *uc_priv, - struct video_uc_platdata *plat) +int vbe_setup_video_priv(struct vesa_mode_info *vesa, + struct video_priv *uc_priv, + struct video_uc_platdata *plat) { if (!vesa->x_resolution) return -ENXIO; diff --git a/include/vbe.h b/include/vbe.h index a743892..16bb096 100644 --- a/include/vbe.h +++ b/include/vbe.h @@ -107,6 +107,10 @@ extern struct vbe_mode_info mode_info; struct graphic_device; int vbe_get_video_info(struct graphic_device *gdev); struct video_priv; +struct video_uc_platdata; +int vbe_setup_video_priv(struct vesa_mode_info *vesa, + struct video_priv *uc_priv, + struct video_uc_platdata *plat); int vbe_setup_video(struct udevice *dev, int (*int15_handler)(void)); #endif -- cgit v0.10.2 From 13b2bfce5104ad7b4243025554a354a2000b352b Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 9 Oct 2016 04:14:16 -0700 Subject: dm: video: Add driver for coreboot framebuffer device This adds a DM driver for coreboot framebuffer device. Signed-off-by: Bin Meng Reviewed-by: Simon Glass diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index fd26690..86db0da 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -101,6 +101,15 @@ config VIDCONSOLE_AS_LCD to update the environment, the breakage may be confusing for users. This option will be removed around the end of 2016. +config VIDEO_COREBOOT + bool "Enable coreboot framebuffer driver support" + depends on X86 && SYS_COREBOOT + help + Turn on this option to enable a framebuffer driver when U-Boot is + loaded by coreboot where the graphics device is configured by + coreboot already. This can in principle be used with any platform + that coreboot supports. + config VIDEO_VESA bool "Enable VESA video driver support" default n diff --git a/drivers/video/coreboot.c b/drivers/video/coreboot.c new file mode 100644 index 0000000..3a94aa1 --- /dev/null +++ b/drivers/video/coreboot.c @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2016, Bin Meng + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include + +static int save_vesa_mode(struct cb_framebuffer *fb, + struct vesa_mode_info *vesa) +{ + /* + * If there is no framebuffer structure, bail out and keep + * running on the serial console. + */ + if (!fb) + return -ENXIO; + + vesa->x_resolution = fb->x_resolution; + vesa->y_resolution = fb->y_resolution; + vesa->bits_per_pixel = fb->bits_per_pixel; + vesa->bytes_per_scanline = fb->bytes_per_line; + vesa->phys_base_ptr = fb->physical_address; + vesa->red_mask_size = fb->red_mask_size; + vesa->red_mask_pos = fb->red_mask_pos; + vesa->green_mask_size = fb->green_mask_size; + vesa->green_mask_pos = fb->green_mask_pos; + vesa->blue_mask_size = fb->blue_mask_size; + vesa->blue_mask_pos = fb->blue_mask_pos; + vesa->reserved_mask_size = fb->reserved_mask_size; + vesa->reserved_mask_pos = fb->reserved_mask_pos; + + return 0; +} + +static int coreboot_video_probe(struct udevice *dev) +{ + struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); + struct video_priv *uc_priv = dev_get_uclass_priv(dev); + struct cb_framebuffer *fb = lib_sysinfo.framebuffer; + struct vesa_mode_info *vesa = &mode_info.vesa; + int ret; + + printf("Video: "); + + /* Initialize vesa_mode_info structure */ + ret = save_vesa_mode(fb, vesa); + if (ret) + goto err; + + ret = vbe_setup_video_priv(vesa, uc_priv, plat); + if (ret) + goto err; + + printf("%dx%dx%d\n", uc_priv->xsize, uc_priv->ysize, + vesa->bits_per_pixel); + + return 0; + +err: + printf("No video mode configured in coreboot!\n"); + return ret; +} + +static const struct udevice_id coreboot_video_ids[] = { + { .compatible = "coreboot-fb" }, + { } +}; + +U_BOOT_DRIVER(coreboot_video) = { + .name = "coreboot_video", + .id = UCLASS_VIDEO, + .of_match = coreboot_video_ids, + .probe = coreboot_video_probe, +}; -- cgit v0.10.2 From 3968398eb2d974b4840d7210d8503d7cbd8f4c48 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 9 Oct 2016 04:14:17 -0700 Subject: dm: video: Don't do anything in alloc_fb() when plat->size is zero With DM VESA driver on x86 boards, plat->base/size/align are all zeroes and starting address passed to alloc_fb() happens to be 1MB aligned, so this routine does not trigger any issue. On QEMU with U-Boot as coreboot payload, the starting address is within 1MB range (eg: 0x7fb0000), thus causes failure in video_post_bind(). Actually if plat->size is zero, it makes no sense to do anything in this routine. Add such check there. Signed-off-by: Bin Meng Reviewed-by: Simon Glass diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index b6dd0f5..11ca793 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -54,6 +54,9 @@ static ulong alloc_fb(struct udevice *dev, ulong *addrp) struct video_uc_platdata *plat = dev_get_uclass_platdata(dev); ulong base, align, size; + if (!plat->size) + return 0; + align = plat->align ? plat->align : 1 << 20; base = *addrp - plat->size; base &= ~(align - 1); -- cgit v0.10.2 From 2d3c573ee6373f4521491f1a38e81245c3a6be57 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 9 Oct 2016 04:14:18 -0700 Subject: x86: coreboot: Convert to use DM coreboot video driver This converts coreboot to use DM framebuffer driver. Signed-off-by: Bin Meng Reviewed-by: Simon Glass diff --git a/arch/x86/cpu/coreboot/Kconfig b/arch/x86/cpu/coreboot/Kconfig index e0e3c64..4b3601f 100644 --- a/arch/x86/cpu/coreboot/Kconfig +++ b/arch/x86/cpu/coreboot/Kconfig @@ -8,8 +8,4 @@ config CBMEM_CONSOLE bool default y -config VIDEO_COREBOOT - bool - default y - endif diff --git a/arch/x86/dts/bayleybay.dts b/arch/x86/dts/bayleybay.dts index c8907ce..18b310d 100644 --- a/arch/x86/dts/bayleybay.dts +++ b/arch/x86/dts/bayleybay.dts @@ -14,6 +14,7 @@ /include/ "serial.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" +/include/ "coreboot_fb.dtsi" / { model = "Intel Bayley Bay"; diff --git a/arch/x86/dts/broadwell_som-6896.dts b/arch/x86/dts/broadwell_som-6896.dts index 4bb0a34..3966199 100644 --- a/arch/x86/dts/broadwell_som-6896.dts +++ b/arch/x86/dts/broadwell_som-6896.dts @@ -4,6 +4,7 @@ /include/ "serial.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" +/include/ "coreboot_fb.dtsi" / { model = "Advantech SOM-6896"; diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts index fb1b31d..b932340 100644 --- a/arch/x86/dts/chromebook_link.dts +++ b/arch/x86/dts/chromebook_link.dts @@ -7,6 +7,7 @@ /include/ "serial.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" +/include/ "coreboot_fb.dtsi" / { model = "Google Link"; diff --git a/arch/x86/dts/chromebook_samus.dts b/arch/x86/dts/chromebook_samus.dts index 5dd3e57..52a9ea6 100644 --- a/arch/x86/dts/chromebook_samus.dts +++ b/arch/x86/dts/chromebook_samus.dts @@ -7,6 +7,7 @@ /include/ "serial.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" +/include/ "coreboot_fb.dtsi" / { model = "Google Samus"; diff --git a/arch/x86/dts/chromebox_panther.dts b/arch/x86/dts/chromebox_panther.dts index 480b366..b25c919 100644 --- a/arch/x86/dts/chromebox_panther.dts +++ b/arch/x86/dts/chromebox_panther.dts @@ -4,6 +4,7 @@ /include/ "serial.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" +/include/ "coreboot_fb.dtsi" / { model = "Google Panther"; diff --git a/arch/x86/dts/coreboot_fb.dtsi b/arch/x86/dts/coreboot_fb.dtsi new file mode 100644 index 0000000..7d72f18 --- /dev/null +++ b/arch/x86/dts/coreboot_fb.dtsi @@ -0,0 +1,5 @@ +/ { + coreboot-fb { + compatible = "coreboot-fb"; + }; +}; diff --git a/arch/x86/dts/minnowmax.dts b/arch/x86/dts/minnowmax.dts index 1a8a8cc..d51318b 100644 --- a/arch/x86/dts/minnowmax.dts +++ b/arch/x86/dts/minnowmax.dts @@ -13,6 +13,7 @@ /include/ "serial.dtsi" /include/ "rtc.dtsi" /include/ "tsc_timer.dtsi" +/include/ "coreboot_fb.dtsi" / { model = "Intel Minnowboard Max"; diff --git a/configs/coreboot-x86_defconfig b/configs/coreboot-x86_defconfig index 378d75f..b33c5c4 100644 --- a/configs/coreboot-x86_defconfig +++ b/configs/coreboot-x86_defconfig @@ -40,5 +40,7 @@ CONFIG_TPM_TIS_LPC=y CONFIG_USB=y CONFIG_DM_USB=y CONFIG_USB_STORAGE=y +CONFIG_DM_VIDEO=y +CONFIG_VIDEO_COREBOOT=y CONFIG_USE_PRIVATE_LIBGCC=y CONFIG_TPM=y diff --git a/doc/README.x86 b/doc/README.x86 index c34f455..6799559 100644 --- a/doc/README.x86 +++ b/doc/README.x86 @@ -381,6 +381,10 @@ To enable video you must enable these options in coreboot: - Set framebuffer graphics resolution (1280x1024 32k-color (1:5:5)) - Keep VESA framebuffer +And include coreboot_fb.dtsi in your board's device tree source file, like: + + /include/ "coreboot_fb.dtsi" + At present it seems that for Minnowboard Max, coreboot does not pass through the video information correctly (it always says the resolution is 0x0). This works correctly for link though. diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 8a99d24..4a42417 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -37,7 +37,7 @@ obj-$(CONFIG_S6E63D6) += s6e63d6.o obj-$(CONFIG_LD9040) += ld9040.o obj-$(CONFIG_SED156X) += sed156x.o obj-$(CONFIG_VIDEO_BCM2835) += bcm2835.o -obj-$(CONFIG_VIDEO_COREBOOT) += coreboot_fb.o +obj-$(CONFIG_VIDEO_COREBOOT) += coreboot.o obj-$(CONFIG_VIDEO_CT69000) += ct69000.o videomodes.o obj-$(CONFIG_VIDEO_DA8XX) += da8xx-fb.o videomodes.o obj-$(CONFIG_VIDEO_IMX25LCDC) += imx25lcdc.o videomodes.o diff --git a/include/configs/som-6896.h b/include/configs/som-6896.h index 43a9623..d058603 100644 --- a/include/configs/som-6896.h +++ b/include/configs/som-6896.h @@ -27,9 +27,9 @@ #define CONFIG_ARCH_EARLY_INIT_R -#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,vga,usbkbd\0" \ - "stdout=serial,vga\0" \ - "stderr=serial,vga\0" +#define CONFIG_STD_DEVICES_SETTINGS "stdin=serial,usbkbd\0" \ + "stdout=serial,vidconsole\0" \ + "stderr=serial,vidconsole\0" #define CONFIG_ENV_SECT_SIZE 0x1000 #define CONFIG_ENV_OFFSET 0x00ff0000 -- cgit v0.10.2 From 21c9bcebd0e388a7acc2b1a3dc38127e0fd6182c Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 9 Oct 2016 04:14:19 -0700 Subject: video: Remove legacy VESA and coreboot framebuffer drivers Now that all x86 boards have been converted to DM video, drop the legacy drivers. Signed-off-by: Bin Meng Reviewed-by: Simon Glass diff --git a/drivers/video/coreboot_fb.c b/drivers/video/coreboot_fb.c deleted file mode 100644 index feb5463..0000000 --- a/drivers/video/coreboot_fb.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * coreboot Framebuffer driver. - * - * Copyright (C) 2011 The Chromium OS authors - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include -#include "videomodes.h" - -/* - * The Graphic Device - */ -GraphicDevice ctfb; - -static void save_vesa_mode(void) -{ - struct vesa_mode_info *vesa = &mode_info.vesa; - struct cb_framebuffer *fb = lib_sysinfo.framebuffer; - - vesa->x_resolution = fb->x_resolution; - vesa->y_resolution = fb->y_resolution; - vesa->bits_per_pixel = fb->bits_per_pixel; - vesa->bytes_per_scanline = fb->bytes_per_line; - vesa->phys_base_ptr = fb->physical_address; - vesa->red_mask_size = fb->red_mask_size; - vesa->red_mask_pos = fb->red_mask_pos; - vesa->green_mask_size = fb->green_mask_size; - vesa->green_mask_pos = fb->green_mask_pos; - vesa->blue_mask_size = fb->blue_mask_size; - vesa->blue_mask_pos = fb->blue_mask_pos; - vesa->reserved_mask_size = fb->reserved_mask_size; - vesa->reserved_mask_pos = fb->reserved_mask_pos; -} - -static int parse_coreboot_table_fb(GraphicDevice *gdev) -{ - struct cb_framebuffer *fb = lib_sysinfo.framebuffer; - - /* If there is no framebuffer structure, bail out and keep - * running on the serial console. - */ - if (!fb) - return 0; - - gdev->winSizeX = fb->x_resolution; - gdev->winSizeY = fb->y_resolution; - - gdev->plnSizeX = fb->x_resolution; - gdev->plnSizeY = fb->y_resolution; - - gdev->gdfBytesPP = fb->bits_per_pixel / 8; - - switch (fb->bits_per_pixel) { - case 24: - gdev->gdfIndex = GDF_32BIT_X888RGB; - break; - case 16: - gdev->gdfIndex = GDF_16BIT_565RGB; - break; - default: - gdev->gdfIndex = GDF__8BIT_INDEX; - break; - } - - gdev->isaBase = CONFIG_SYS_ISA_IO_BASE_ADDRESS; - gdev->pciBase = (unsigned int)fb->physical_address; - - gdev->frameAdrs = (unsigned int)fb->physical_address; - gdev->memSize = fb->bytes_per_line * fb->y_resolution; - - gdev->vprBase = (unsigned int)fb->physical_address; - gdev->cprBase = (unsigned int)fb->physical_address; - - return 1; -} - -void *video_hw_init(void) -{ - GraphicDevice *gdev = &ctfb; - int bits_per_pixel; - - printf("Video: "); - - if (!parse_coreboot_table_fb(gdev)) { - printf("No video mode configured in coreboot!\n"); - return NULL; - } - - bits_per_pixel = gdev->gdfBytesPP * 8; - - /* fill in Graphic device struct */ - sprintf(gdev->modeIdent, "%dx%dx%d", gdev->winSizeX, gdev->winSizeY, - bits_per_pixel); - printf("%s\n", gdev->modeIdent); - - memset((void *)gdev->pciBase, 0, - gdev->winSizeX * gdev->winSizeY * gdev->gdfBytesPP); - - /* Initialize vesa_mode_info structure */ - save_vesa_mode(); - - return (void *)gdev; -} diff --git a/drivers/video/vesa_fb.c b/drivers/video/vesa_fb.c deleted file mode 100644 index 021c1d6..0000000 --- a/drivers/video/vesa_fb.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * VESA frame buffer driver - * - * Copyright (C) 2014 Google, Inc - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include -#include -#include -#include - -/* - * The Graphic Device - */ -GraphicDevice ctfb; - -void *video_hw_init(void) -{ - GraphicDevice *gdev = &ctfb; - struct udevice *dev; - int bits_per_pixel; - int ret; - - printf("Video: "); - if (!ll_boot_init()) { - /* - * If we are running from EFI or coreboot, this driver can't - * work. - */ - printf("Not available (previous bootloader prevents it)\n"); - return NULL; - } - if (vbe_get_video_info(gdev)) { - ret = dm_pci_find_class(PCI_CLASS_DISPLAY_VGA << 8, 0, &dev); - if (ret) { - printf("no card detected\n"); - return NULL; - } - bootstage_start(BOOTSTAGE_ID_ACCUM_LCD, "vesa display"); - ret = dm_pci_run_vga_bios(dev, NULL, PCI_ROM_USE_NATIVE | - PCI_ROM_ALLOW_FALLBACK); - bootstage_accum(BOOTSTAGE_ID_ACCUM_LCD); - if (ret) { - printf("failed to run video BIOS: %d\n", ret); - return NULL; - } - } - - if (vbe_get_video_info(gdev)) { - printf("No video mode configured\n"); - return NULL; - } - - bits_per_pixel = gdev->gdfBytesPP * 8; - sprintf(gdev->modeIdent, "%dx%dx%d", gdev->winSizeX, gdev->winSizeY, - bits_per_pixel); - printf("%s\n", gdev->modeIdent); - debug("Frame buffer at %x\n", gdev->pciBase); - - return (void *)gdev; -} -- cgit v0.10.2 From 00bcaedd5c4063c677d16af264bbcb991fb9675c Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sun, 9 Oct 2016 04:14:20 -0700 Subject: x86: Clean up unused macros in the configuration headers Legacy video driver macros are not needed. Clean them up. Signed-off-by: Bin Meng Reviewed-by: Simon Glass diff --git a/include/configs/cougarcanyon2.h b/include/configs/cougarcanyon2.h index 88845dc..d20ad96 100644 --- a/include/configs/cougarcanyon2.h +++ b/include/configs/cougarcanyon2.h @@ -27,8 +27,4 @@ #define CONFIG_ENV_SECT_SIZE 0x1000 #define CONFIG_ENV_OFFSET 0x5ff000 -/* Video is not supported for now */ -#undef CONFIG_VIDEO -#undef CONFIG_CFB_CONSOLE - #endif /* __CONFIG_H */ diff --git a/include/configs/efi-x86.h b/include/configs/efi-x86.h index 95e46c5..5626061 100644 --- a/include/configs/efi-x86.h +++ b/include/configs/efi-x86.h @@ -15,8 +15,6 @@ #undef CONFIG_ENV_IS_IN_SPI_FLASH #define CONFIG_ENV_IS_NOWHERE -#undef CONFIG_VIDEO -#undef CONFIG_CFB_CONSOLE #undef CONFIG_SCSI_AHCI #undef CONFIG_SCSI #undef CONFIG_INTEL_ICH6_GPIO diff --git a/include/configs/galileo.h b/include/configs/galileo.h index 40f7fba..034142c 100644 --- a/include/configs/galileo.h +++ b/include/configs/galileo.h @@ -31,10 +31,6 @@ #undef CONFIG_SCSI_AHCI #undef CONFIG_SCSI -/* Video is not supported in Quark SoC */ -#undef CONFIG_VIDEO -#undef CONFIG_CFB_CONSOLE - /* SD/MMC support */ #define CONFIG_MMC #define CONFIG_SDHCI diff --git a/include/configs/x86-chromebook.h b/include/configs/x86-chromebook.h index 7fba716..4bcebfc 100644 --- a/include/configs/x86-chromebook.h +++ b/include/configs/x86-chromebook.h @@ -53,14 +53,8 @@ #define CONFIG_SYS_WHITE_ON_BLACK -#ifdef CONFIG_DM_VIDEO -#define VIDEO_DEV "vidconsole" -#else -#define VIDEO_DEV "vga" -#endif - -#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,i8042-kbd,serial\0" \ - "stdout=" VIDEO_DEV ",serial\0" \ - "stderr=" VIDEO_DEV ",serial\0" +#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,i8042-kbd,serial\0" \ + "stdout=vidconsole,serial\0" \ + "stderr=vidconsole,serial\0" #endif diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h index 96c53b8..3926541 100644 --- a/include/configs/x86-common.h +++ b/include/configs/x86-common.h @@ -131,13 +131,6 @@ /*----------------------------------------------------------------------- * Video Configuration */ -#ifndef CONFIG_DM_VIDEO -#define CONFIG_VIDEO -#define CONFIG_VIDEO_SW_CURSOR -#define VIDEO_FB_16BPP_WORD_SWAP -#define CONFIG_VGA_AS_SINGLE_DEVICE -#define CONFIG_CFB_CONSOLE -#endif #define CONFIG_CONSOLE_SCROLL_LINES 5 /*----------------------------------------------------------------------- -- cgit v0.10.2