#include <cursor.h>
#include "screen.h"
-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 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
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
CURBASE,
CURPOS,
- NPIPE = 3,
+ NPIPE = 4,
};
static u32int*
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 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 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;
int i;
igfxenable(scr);
- igfxcurload(scr, &arrow);
+ igfxcurload(scr, &cursor);
igfxcurmove(scr, ZP);
for(i=0; i<NPIPE; i++){