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

Attachment: signature.asc
Description: This is a digitally signed message part

-- 
coreboot mailing list: [email protected]
http://www.coreboot.org/mailman/listinfo/coreboot

Reply via email to