]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/pc/vgaigfx.c
kernel: cleanup the software mouse cursor mess
[plan9front.git] / sys / src / 9 / pc / vgaigfx.c
index 41ea91966f7f02619bcc46683348f644f04e24b6..34bc424e20c3c1dcb360b5b497b96208bf1fc7a7 100644 (file)
 #include <cursor.h>
 #include "screen.h"
 
-#define MB     0x100000
-
-static ulong
-preallocsize(Pcidev *p)
+static uintptr
+igfxcuralloc(Pcidev *pci, void *mmio, int apsize)
 {
-       switch(p->did){
-       case 0x0166:    /* Ivy Bridge */
-               switch((pcicfgr16(p, 0x50) >> 3) & 0x1f){
-               case 0x01:      return 32*MB    - 2*MB;
-               case 0x02:      return 64*MB    - 2*MB;
-               case 0x03:      return 96*MB    - 2*MB;
-               case 0x04:      return 128*MB   - 2*MB;
-               case 0x05:      return 32*MB    - 2*MB;
-               case 0x06:      return 48*MB    - 2*MB;
-               case 0x07:      return 64*MB    - 2*MB;
-               case 0x08:      return 128*MB   - 2*MB;
-               case 0x09:      return 256*MB   - 2*MB;
-               case 0x0A:      return 96*MB    - 2*MB;
-               case 0x0B:      return 160*MB   - 2*MB;
-               case 0x0C:      return 224*MB   - 2*MB;
-               case 0x0D:      return 352*MB   - 2*MB;
-               case 0x0E:      return 448*MB   - 2*MB;
-               case 0x0F:      return 480*MB   - 2*MB;
-               case 0x10:      return 512*MB   - 2*MB;
-               }
-               break;
-       case 0x27a2:    /* X60t */
-       case 0x2a42:    /* X200 */
-               switch((pcicfgr16(p, 0x52) >> 4) & 7){
-               case 0x01:      return 1*MB;
-               case 0x02:      return 4*MB;
-               case 0x03:      return 8*MB;
-               case 0x04:      return 16*MB;
-               case 0x05:      return 32*MB;
-               case 0x06:      return 48*MB;
-               case 0x07:      return 64*MB;
-               }
-               break;
+       int n;
+       u32int pa, *buf, *p, *e;
+
+       buf = mallocalign(64*64*4, BY2PG, 0, 0);
+       if(buf == nil){
+               print("igfx: no memory for cursor image\n");
+               return 0;
        }
-       return 0;
+       n = (apsize > 128*MB ? 128*1024 : apsize/1024) / 4 - 4;
+       p = (u32int*)((uchar*)mmio + pci->mem[0].size/2) + n;
+       *(u32int*)((uchar*)mmio + 0x2170) = 0;  /* flush write buffers */
+       for(e=p+4, pa=PADDR(buf); p<e; p++, pa+=1<<12)
+               *p = pa | 1;
+       *(u32int*)((uchar*)mmio + 0x2170) = 0;  /* flush write buffers */
+       return (uintptr)n << 12;
 }
 
 static void
@@ -72,17 +50,52 @@ igfxenable(VGAscr* scr)
                vgalinearpci(scr);
        if(scr->apsize){
                addvgaseg("igfxscreen", scr->paddr, scr->apsize);
-               scr->storage = preallocsize(p);
-               if(scr->storage > scr->apsize)
-                       scr->storage = scr->apsize;
-               if(scr->storage != 0)
-                       scr->storage -= PGROUND(64*64*4);
+               scr->storage = igfxcuralloc(p, scr->mmio, scr->apsize);
+       }
+       scr->softscreen = 1;
+}
+
+static void
+igfxblank(VGAscr *scr, int blank)
+{
+       u32int off;
+
+       switch(scr->pci->did){
+       default:
+               return;
+
+       case 0x2a02:    /* GM965 */
+       case 0x2a42:    /* GM45 */
+       case 0x2592:    /* GM915 */
+               off = 0x61204;
+               break;
+
+       case 0x0126:    /* SNB */
+       case 0x0166:    /* IVB */
+               off = 0xC7204;
+               break;
        }
+
+       /* toggle PP_CONTROL backlight & power state */
+       if(blank)
+               scr->mmio[off/4] &= ~0x5;
+       else
+               scr->mmio[off/4] |= 0x5;
+}
+
+static void
+igfxdrawinit(VGAscr *scr)
+{
+       scr->blank = igfxblank;
 }
 
 VGAdev vgaigfxdev = {
        "igfx",
        igfxenable,
+       nil,
+       nil,
+       nil,
+       igfxdrawinit,
 };
 
 static void
@@ -116,7 +129,7 @@ enum {
        CURBASE,
        CURPOS,
 
-       NPIPE = 3,
+       NPIPE = 4,
 };
 
 static u32int*
@@ -126,17 +139,29 @@ igfxcurregs(VGAscr* scr, int pipe)
 
        if(scr->mmio == nil || scr->storage == 0)
                return nil;
-       o = pipe*0x1000;
+       o = pipe == 3 ? 0xf000 : pipe*0x1000;
        /* check PIPExCONF if enabled */
        if((scr->mmio[(0x70008 | o)/4] & (1<<31)) == 0)
                return nil;
        switch(scr->pci->did){
-       case 0x0116:    /* Ivy Bridge */
+       case 0x0412:    /* Haswell HD Graphics 4600 */
+       case 0x0a16:    /* Haswell HD Graphics 4400 */
+               if(pipe > 3)
+                       return nil;
+               if(pipe == 3)
+                       o = 0;
+               break;
+       case 0x0166:    /* Ivy Bridge */
+       case 0x0152:    /* Core-i3 */
+       case 0x0126:    /* Sandy Bridge HD Graphics 3000 */
                if(pipe > 2)
                        return nil;
                break;
-       case 0x27a2:    /* X60t */
+       case 0x2592:    /* GM915 */
        case 0x2a42:    /* X200 */
+       case 0x29a2:    /* 82P965/G965 HECI desktop */
+       case 0x2a02:    /* CF-R7 */
+       case 0x0102:    /* Sndy Bridge */
                if(pipe > 1)
                        return nil;
                o = pipe*0x40;
@@ -173,7 +198,7 @@ igfxcurenable(VGAscr* scr)
        int i;
 
        igfxenable(scr);
-       igfxcurload(scr, &arrow);
+       igfxcurload(scr, &cursor);
        igfxcurmove(scr, ZP);
 
        for(i=0; i<NPIPE; i++){