[U-Boot] [PATCH v2 00/12] dm: x86: Improve vesa driver-model support

At present samus uses driver model but link does not. This series fixes this and adds a few features to make it easier to support driver-model video on other machines that use vesa.
It also includes a faster memmove() function which speeds up scrolling dramatically.
Changes in v2: - Move the code into string.c - Fix multi-line comments that should not be - Fix typo drive -> driver - Drop invalid '1' at start of file - Comment that no details are available about the magic values - Add comment as to why we need #ifndef CONFIG_SYS_CONSOLE_IS_IN_ENV - Add comment as to why we check for "," in stdio_get_by_name() - Make vbe_setup_video_priv() static
Simon Glass (12): Revert "x86: broadwell: gpio: Remove the codes to set up pin control" x86: Add an accelerated memmove() function Fix return value in trailing_strtoln() list: Add list_last_entry() to find the last entry dm: core: Add a function to get a uclass name x86: video: Fix typo in broadwell Kconfig dm: x86: video: Add a driver-model driver for ivybridge graphics dm: stdio: Allow lazy probing of video devices dm: video: Add driver-model support to vesa graphics x86: Adjust config to support DM_VIDEO dm: x86: Move samus to use new driver model support dm: x86: Move link to use driver model for video
arch/x86/cpu/broadwell/sdram.c | 1 - arch/x86/cpu/ivybridge/Makefile | 1 - arch/x86/cpu/ivybridge/bd82x6x.c | 12 -- arch/x86/cpu/ivybridge/early_me.c | 1 - arch/x86/cpu/ivybridge/gma.h | 156 -------------------- arch/x86/cpu/ivybridge/model_206ax.c | 1 - arch/x86/cpu/ivybridge/sata.c | 1 - arch/x86/include/asm/arch-ivybridge/bd82x6x.h | 12 -- arch/x86/include/asm/cpu.h | 1 - arch/x86/include/asm/string.h | 2 +- arch/x86/lib/string.c | 161 +++++++++++++++++++++ common/stdio.c | 87 ++++++++++- configs/chromebook_link_defconfig | 2 + drivers/core/uclass.c | 9 ++ drivers/gpio/intel_broadwell_gpio.c | 7 + drivers/pci/pci_rom.c | 55 +++++++ drivers/video/Kconfig | 14 +- drivers/video/Makefile | 1 + drivers/video/broadwell_igd.c | 39 +---- .../gma.c => drivers/video/ivybridge_igd.c | 77 +++++----- include/configs/x86-chromebook.h | 10 +- include/configs/x86-common.h | 2 + include/dm/uclass.h | 8 + include/linux/list.h | 11 ++ include/vbe.h | 2 + lib/strto.c | 8 +- 26 files changed, 410 insertions(+), 271 deletions(-) delete mode 100644 arch/x86/cpu/ivybridge/gma.h delete mode 100644 arch/x86/include/asm/arch-ivybridge/bd82x6x.h rename arch/x86/cpu/ivybridge/gma.c => drivers/video/ivybridge_igd.c (94%)

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 sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
---
Changes in v2: None
drivers/gpio/intel_broadwell_gpio.c | 7 +++++++ 1 file changed, 7 insertions(+)
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 <fdtdec.h> #include <pch.h> #include <pci.h> +#include <syscon.h> #include <asm/cpu.h> #include <asm/gpio.h> #include <asm/io.h> @@ -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;

On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
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 sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Changes in v2: None
drivers/gpio/intel_broadwell_gpio.c | 7 +++++++ 1 file changed, 7 insertions(+)
applied to u-boot-x86, thanks!

Bring in a faster memmove() from Linux 4.7. This speeds up scrolling on the display.
Signed-off-by: Simon Glass sjg@chromium.org ---
Changes in v2: - Move the code into string.c - Fix multi-line comments that should not be
arch/x86/include/asm/string.h | 2 +- arch/x86/lib/string.c | 161 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 1 deletion(-)
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; +}

Hi Simon,
On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
Bring in a faster memmove() from Linux 4.7. This speeds up scrolling on the display.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Move the code into string.c
- Fix multi-line comments that should not be
arch/x86/include/asm/string.h | 2 +- arch/x86/lib/string.c | 161 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 1 deletion(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
Tested on Crown Bay with an external PCIe graphics card Tested-by: Bin Meng bmeng.cn@gmail.com
However, I did not see significant speed up on screen scrolling...
Regards, Bin

On Sat, Oct 8, 2016 at 10:25 AM, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
Bring in a faster memmove() from Linux 4.7. This speeds up scrolling on the display.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Move the code into string.c
- Fix multi-line comments that should not be
arch/x86/include/asm/string.h | 2 +- arch/x86/lib/string.c | 161 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 1 deletion(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
Tested on Crown Bay with an external PCIe graphics card Tested-by: Bin Meng bmeng.cn@gmail.com
However, I did not see significant speed up on screen scrolling...
applied to u-boot-x86, thanks!

Hi Simon,
On Sat, Oct 8, 2016 at 10:25 AM, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
Bring in a faster memmove() from Linux 4.7. This speeds up scrolling on the display.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Move the code into string.c
- Fix multi-line comments that should not be
arch/x86/include/asm/string.h | 2 +- arch/x86/lib/string.c | 161 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 1 deletion(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
Tested on Crown Bay with an external PCIe graphics card Tested-by: Bin Meng bmeng.cn@gmail.com
However, I did not see significant speed up on screen scrolling...
Crown Bay is still using cfb_console.c, which is the legacy driver that does not use memmove(). Looks the new console_xxx driver is using memmove(). I guess I will need convert Crown Bay to use DM video.
Regards, Bin

On Sat, Oct 8, 2016 at 1:53 PM, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Sat, Oct 8, 2016 at 10:25 AM, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
Bring in a faster memmove() from Linux 4.7. This speeds up scrolling on the display.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Move the code into string.c
- Fix multi-line comments that should not be
arch/x86/include/asm/string.h | 2 +- arch/x86/lib/string.c | 161 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 1 deletion(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
Tested on Crown Bay with an external PCIe graphics card Tested-by: Bin Meng bmeng.cn@gmail.com
However, I did not see significant speed up on screen scrolling...
Crown Bay is still using cfb_console.c, which is the legacy driver that does not use memmove(). Looks the new console_xxx driver is using memmove(). I guess I will need convert Crown Bay to use DM video.
Testing shows that on Crown Bay, the DM driver with the optimized memmove() does not improve the performance compared to legacy cfb_console driver. But on Bayleybay, memmove() indeed helps the screen scrolling.
Regards, Bin

Hi Bin,
On 9 October 2016 at 20:05, Bin Meng bmeng.cn@gmail.com wrote:
On Sat, Oct 8, 2016 at 1:53 PM, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Sat, Oct 8, 2016 at 10:25 AM, Bin Meng bmeng.cn@gmail.com wrote:
Hi Simon,
On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
Bring in a faster memmove() from Linux 4.7. This speeds up scrolling on the display.
Signed-off-by: Simon Glass sjg@chromium.org
Changes in v2:
- Move the code into string.c
- Fix multi-line comments that should not be
arch/x86/include/asm/string.h | 2 +- arch/x86/lib/string.c | 161 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 1 deletion(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
Tested on Crown Bay with an external PCIe graphics card Tested-by: Bin Meng bmeng.cn@gmail.com
However, I did not see significant speed up on screen scrolling...
Crown Bay is still using cfb_console.c, which is the legacy driver that does not use memmove(). Looks the new console_xxx driver is using memmove(). I guess I will need convert Crown Bay to use DM video.
Testing shows that on Crown Bay, the DM driver with the optimized memmove() does not improve the performance compared to legacy cfb_console driver. But on Bayleybay, memmove() indeed helps the screen scrolling.
That's interesting. What is the difference between those two platforms? It is slow on Crown Bay?
Regards, Simon

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 sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v2: None
lib/strto.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
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;

On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
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 sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Changes in v2: None
lib/strto.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
applied to u-boot-x86, thanks!

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 sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v2: None
include/linux/list.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
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.

On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
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 sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Changes in v2: None
include/linux/list.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
applied to u-boot-x86, thanks!

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 sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v2: - Fix typo drive -> driver
drivers/core/uclass.c | 9 +++++++++ include/dm/uclass.h | 8 ++++++++ 2 files changed, 17 insertions(+)
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.

On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
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 sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Changes in v2:
- Fix typo drive -> driver
drivers/core/uclass.c | 9 +++++++++ include/dm/uclass.h | 8 ++++++++ 2 files changed, 17 insertions(+)
applied to u-boot-x86, thanks!

'enabled' should be 'enables'. Fix it.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v2: None
drivers/video/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
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.

On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
'enabled' should be 'enables'. Fix it.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Changes in v2: None
drivers/video/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
applied to u-boot-x86, thanks!

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 sjg@chromium.org ---
Changes in v2: - Drop invalid '1' at start of file - Comment that no details are available about the magic values
drivers/video/Kconfig | 12 + drivers/video/Makefile | 1 + drivers/video/ivybridge_igd.c | 843 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 856 insertions(+) create mode 100644 drivers/video/ivybridge_igd.c
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 <common.h> +#include <bios_emul.h> +#include <dm.h> +#include <errno.h> +#include <fdtdec.h> +#include <pci_rom.h> +#include <vbe.h> +#include <asm/intel_regs.h> +#include <asm/io.h> +#include <asm/mtrr.h> +#include <asm/pci.h> +#include <asm/arch/pch.h> +#include <asm/arch/sandybridge.h> + +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, +};

On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
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 sjg@chromium.org
Changes in v2:
- Drop invalid '1' at start of file
- Comment that no details are available about the magic values
drivers/video/Kconfig | 12 + drivers/video/Makefile | 1 + drivers/video/ivybridge_igd.c | 843 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 856 insertions(+) create mode 100644 drivers/video/ivybridge_igd.c
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Sat, Oct 8, 2016 at 10:33 AM, Bin Meng bmeng.cn@gmail.com wrote:
On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
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 sjg@chromium.org
Changes in v2:
- Drop invalid '1' at start of file
- Comment that no details are available about the magic values
drivers/video/Kconfig | 12 + drivers/video/Makefile | 1 + drivers/video/ivybridge_igd.c | 843 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 856 insertions(+) create mode 100644 drivers/video/ivybridge_igd.c
Reviewed-by: Bin Meng bmeng.cn@gmail.com
Move this patch after patch#9 in this series, and applied to u-boot-x86, thanks!

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 sjg@chromium.org ---
Changes in v2: - Add comment as to why we need #ifndef CONFIG_SYS_CONSOLE_IS_IN_ENV - Add comment as to why we check for "," in stdio_get_by_name()
common/stdio.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 4 deletions(-)
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 ();

On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
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 sjg@chromium.org
Changes in v2:
- Add comment as to why we need #ifndef CONFIG_SYS_CONSOLE_IS_IN_ENV
- Add comment as to why we check for "," in stdio_get_by_name()
common/stdio.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 4 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com

On Sat, Oct 8, 2016 at 10:32 AM, Bin Meng bmeng.cn@gmail.com wrote:
On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
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 sjg@chromium.org
Changes in v2:
- Add comment as to why we need #ifndef CONFIG_SYS_CONSOLE_IS_IN_ENV
- Add comment as to why we check for "," in stdio_get_by_name()
common/stdio.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 4 deletions(-)
Reviewed-by: Bin Meng bmeng.cn@gmail.com
applied to u-boot-x86, thanks!

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 sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v2: - Make vbe_setup_video_priv() static
drivers/pci/pci_rom.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/vbe.h | 2 ++ 2 files changed, 57 insertions(+)
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 <pci.h> #include <pci_rom.h> #include <vbe.h> +#include <video.h> #include <video_fb.h> #include <linux/screen_info.h>
@@ -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

On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
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 sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Changes in v2:
- Make vbe_setup_video_priv() static
drivers/pci/pci_rom.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ include/vbe.h | 2 ++ 2 files changed, 57 insertions(+)
applied to u-boot-x86, thanks!

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 sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v2: None
include/configs/x86-chromebook.h | 10 ++++++++-- include/configs/x86-common.h | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-)
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
/*-----------------------------------------------------------------------

On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
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 sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Changes in v2: None
include/configs/x86-chromebook.h | 10 ++++++++-- include/configs/x86-common.h | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-)
applied to u-boot-x86, thanks!

Update the samus driver to avoid the direct call to the video BIOS setup.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v2: None
arch/x86/cpu/broadwell/sdram.c | 1 - drivers/video/broadwell_igd.c | 39 +++++++-------------------------------- 2 files changed, 7 insertions(+), 33 deletions(-)
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 <common.h> #include <bios_emul.h> #include <dm.h> -#include <pci_rom.h> #include <vbe.h> #include <video.h> -#include <video_fb.h> #include <asm/cpu.h> #include <asm/intel_regs.h> #include <asm/io.h> @@ -20,11 +18,9 @@ #include <asm/arch/cpu.h> #include <asm/arch/iomap.h> #include <asm/arch/pch.h> -#include <linux/log2.h> #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; }

On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
Update the samus driver to avoid the direct call to the video BIOS setup.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Changes in v2: None
arch/x86/cpu/broadwell/sdram.c | 1 - drivers/video/broadwell_igd.c | 39 +++++++-------------------------------- 2 files changed, 7 insertions(+), 33 deletions(-)
applied to u-boot-x86, thanks!

Update the configuration to use the new driver. Drop the existing plumbing code and unused header files.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com ---
Changes in v2: None
arch/x86/cpu/ivybridge/Makefile | 1 - arch/x86/cpu/ivybridge/bd82x6x.c | 12 - arch/x86/cpu/ivybridge/early_me.c | 1 - arch/x86/cpu/ivybridge/gma.c | 850 -------------------------- arch/x86/cpu/ivybridge/gma.h | 156 ----- arch/x86/cpu/ivybridge/model_206ax.c | 1 - arch/x86/cpu/ivybridge/sata.c | 1 - arch/x86/include/asm/arch-ivybridge/bd82x6x.h | 12 - arch/x86/include/asm/cpu.h | 1 - configs/chromebook_link_defconfig | 2 + 10 files changed, 2 insertions(+), 1035 deletions(-) delete mode 100644 arch/x86/cpu/ivybridge/gma.c delete mode 100644 arch/x86/cpu/ivybridge/gma.h delete mode 100644 arch/x86/include/asm/arch-ivybridge/bd82x6x.h
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 <fdtdec.h> #include <malloc.h> #include <pch.h> -#include <syscon.h> #include <asm/cpu.h> #include <asm/intel_regs.h> #include <asm/io.h> #include <asm/lapic.h> #include <asm/lpc_common.h> #include <asm/pci.h> -#include <asm/arch/bd82x6x.h> #include <asm/arch/model_206ax.h> #include <asm/arch/pch.h> #include <asm/arch/sandybridge.h> @@ -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 <common.h> -#include <bios_emul.h> -#include <dm.h> -#include <errno.h> -#include <fdtdec.h> -#include <pci_rom.h> -#include <asm/intel_regs.h> -#include <asm/io.h> -#include <asm/mtrr.h> -#include <asm/pci.h> -#include <asm/arch/pch.h> -#include <asm/arch/sandybridge.h> - -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 <asm/processor.h> #include <asm/speedstep.h> #include <asm/turbo.h> -#include <asm/arch/bd82x6x.h> #include <asm/arch/model_206ax.h>
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 <asm/pch_common.h> #include <asm/pci.h> #include <asm/arch/pch.h> -#include <asm/arch/bd82x6x.h>
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

On Thu, Oct 6, 2016 at 10:42 AM, Simon Glass sjg@chromium.org wrote:
Update the configuration to use the new driver. Drop the existing plumbing code and unused header files.
Signed-off-by: Simon Glass sjg@chromium.org Reviewed-by: Bin Meng bmeng.cn@gmail.com
Changes in v2: None
arch/x86/cpu/ivybridge/Makefile | 1 - arch/x86/cpu/ivybridge/bd82x6x.c | 12 - arch/x86/cpu/ivybridge/early_me.c | 1 - arch/x86/cpu/ivybridge/gma.c | 850 -------------------------- arch/x86/cpu/ivybridge/gma.h | 156 ----- arch/x86/cpu/ivybridge/model_206ax.c | 1 - arch/x86/cpu/ivybridge/sata.c | 1 - arch/x86/include/asm/arch-ivybridge/bd82x6x.h | 12 - arch/x86/include/asm/cpu.h | 1 - configs/chromebook_link_defconfig | 2 + 10 files changed, 2 insertions(+), 1035 deletions(-) delete mode 100644 arch/x86/cpu/ivybridge/gma.c delete mode 100644 arch/x86/cpu/ivybridge/gma.h delete mode 100644 arch/x86/include/asm/arch-ivybridge/bd82x6x.h
applied to u-boot-x86, thanks!
participants (2)
-
Bin Meng
-
Simon Glass