Dear coreboot folks,
since Linux 3.12+ graphics stolen memory seems to be used, which causes
a regression with coreboot and native graphics init at least on the
Intel 945 based Lenovo X60 [1].
This seems to be solved by properly setting register `PGETBL_CTL` [2],
but the Linux kernel Intel graphics driver still reports a GTT (Graphics
Translation Table) related error during start-up, but everything else
seems to work.
[ 1.235640] [drm] GPU crash dump saved to /sys/class/drm/card0/error
[ 1.236583] [drm] GPU hangs can indicate a bug anywhere in the
entire gfx stack, including userspace.
[ 1.236583] [drm] Please file a _new_ bug report on
bugs.freedesktop.org against DRI -> DRM/Intel
[ 1.236583] [drm] drm/i915 developers can then reassign to the right
component if it's not a kernel issue.
[ 1.236583] [drm] The gpu crash dump is required to analyze gpu
hangs, so please always attach it.
[ 1.236583] i915: render error detected, EIR: 0x00000010
[ 1.236583] i915: page table error
[ 1.236583] i915: PGTBL_ER: 0x00000013
[ 1.236583] [drm:i915_report_and_clear_eir] *ERROR* EIR stuck:
0x00000010, masking
[ 1.236583] i915: render error detected, EIR: 0x00000010
[ 1.236583] i915: page table error
[ 1.236583] i915: PGTBL_ER: 0x00000013
Looking further into the native graphics init code for Intel IGDs, I
wonder what `setgtt()` does.
Looking at Google Link, where this was introduced, there is the code
below.
$ nl -ba src/mainboard/google/link/i915.c
[…]
95 void io_i915_WRITE32(unsigned long val, unsigned long addr)
96 {
97 if (verbose & vio)
98 printk(BIOS_SPEW, "%s: outl %08lx\n",
regname(addr), val);
99 outl(addr, addrport);
100 outl(val, dataport);
101 }
102
103
104 /*
105 2560
106 4 words per
107 4 *p
108 10240
109 4k bytes per page
110 4096/p
111 2.50
112 1700 lines
113 1700 * p
114 4250.00
115 PTEs
116 */
117 static void
118 setgtt(int start, int end, unsigned long base, int inc)
119 {
120 int i;
121
122 for(i = start; i < end; i++){
123 u32 word = base + i*inc;
124 WRITE32(word|1,(i*4)|1);
125 }
126 }
[…]
349 /* GTT is the Global Translation Table for the graphics
pipeline.
350 * It is used to translate graphics addresses to
physical
351 * memory addresses. As in the CPU, GTTs map 4K pages.
352 * There are 32 bits per pixel, or 4 bytes,
353 * which means 1024 pixels per page.
354 * There are 4250 GTTs on Link:
355 * 2650 (X) * 1700 (Y) pixels / 1024 pixels per page.
356 * The setgtt function adds a further bit of
flexibility:
357 * it allows you to set a range (the first two
parameters) to point
358 * to a physical address (third parameter);the physical
address is
359 * incremented by a count (fourth parameter) for each
GTT in the
360 * range.
361 * Why do it this way? For ultrafast startup,
362 * we can point all the GTT entries to point to one
page,
363 * and set that page to 0s:
364 * memset(physbase, 0, 4096);
365 * setgtt(0, 4250, physbase, 0);
366 * this takes about 2 ms, and is a win because zeroing
367 * the page takes a up to 200 ms. We will be exploiting
this
368 * trick in a later rev of this code.
369 * This call sets the GTT to point to a linear range of
pages
370 * starting at physbase.
371 */
372 setgtt(0, FRAME_BUFFER_PAGES, physbase, 4096);
373 printk(BIOS_SPEW, "memset %p to 0 for %d bytes\n",
374 (void *)graphics, FRAME_BUFFER_BYTES);
[…]
$ git grep FRAME_BUFFER src/mainboard/google/link/i915io.h
src/mainboard/google/link/i915io.h:#define FRAME_BUFFER_PAGES
((2560*1700)/1024)
src/mainboard/google/link/i915io.h:#define FRAME_BUFFER_BYTES
(FRAME_BUFFER_PAGES*4096)
Looking at the code of the Lenovo X60 with the resolution of 1024×768,
instead of `FRAME_BUFFER_PAGES` = 768 it is the higher number 800.
Otherwise there are graphical corruptions on the GRUB screen.
Furthermore Vladimir’s native graphics patch up for review in Gerrit [3]
uses the code below [3].
/* Setup GTT. */
for (i = 0; i < 0x2000; i++)
{
outl((i << 2) | 1, piobase);
outl(pphysbase + (i << 12) + 1, piobase + 4);
}
This is equivalent to `setgtt(0, 8192, physbase, 4096)`. As the code
should be not hardcoded to one resolution (for example the Lenovo T60
has a different one than the Lenovo X60), the code should be dynamic.
Unfortunately, I did not find anything in the datasheet [4][5]
explaining, why this `setgtt()` is needed at all. I guess this was
figured out by tracing the Video BIOS? Ron, Denis, Peter, Vladimir, it’d
be great if you could explain that to me?
At least on Intel 945, the GTT is 256 KB big and is placed below TOLUD
into the graphics stolen memory, which is currently hardcoded to 8 MB.
So how should the pages be setup then?
Thanks,
Paul
[1] https://bugs.freedesktop.org/show_bug.cgi?id=79038
[2] http://review.coreboot.org/5927
[3] http://review.coreboot.org/#/c/5320/9/src/northbridge/intel/i945/gma.c
[4]
http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/mobile-945-express-chipset-datasheet.pdf
[5]
https://01.org/linuxgraphics/sites/default/files/documentation/965_g35_vol_1_graphics_core_0.pdf
signature.asc
Description: This is a digitally signed message part
-- coreboot mailing list: [email protected] http://www.coreboot.org/mailman/listinfo/coreboot

