summaryrefslogtreecommitdiff
path: root/sys/src/9
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2015-01-09 22:23:25 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2015-01-09 22:23:25 +0100
commit15590e39c6be92d8a9ecb2f00b015dbb9a3dc0b0 (patch)
tree1ecc8859409aae2446f7cb23ca8ad672878846a3 /sys/src/9
parentcf76346b37ddbd54b8d1fe5580ab813a8165392b (diff)
igfx: implement hardware cursor
this can even be used with the vesa driver, just enable the cursor after mode switch like: echo hwgc igfxhwgc >/dev/vgactl
Diffstat (limited to 'sys/src/9')
-rw-r--r--sys/src/9/pc/pccpuf2
-rw-r--r--sys/src/9/pc/pcf2
-rw-r--r--sys/src/9/pc/vgaigfx.c115
-rw-r--r--sys/src/9/pc64/pc642
4 files changed, 117 insertions, 4 deletions
diff --git a/sys/src/9/pc/pccpuf b/sys/src/9/pc/pccpuf
index 89d726b8c..0b06f4192 100644
--- a/sys/src/9/pc/pccpuf
+++ b/sys/src/9/pc/pccpuf
@@ -113,7 +113,7 @@ misc
vgageode +cur
vgahiqvideo +cur
vgai81x +cur
- vgaigfx
+ vgaigfx +cur
vgamach64xx +cur
vgamga2164w +cur
vgamga4xx +cur
diff --git a/sys/src/9/pc/pcf b/sys/src/9/pc/pcf
index f4166027d..b05bf0cd6 100644
--- a/sys/src/9/pc/pcf
+++ b/sys/src/9/pc/pcf
@@ -114,7 +114,7 @@ misc
vgageode +cur
vgahiqvideo +cur
vgai81x +cur
- vgaigfx
+ vgaigfx +cur
vgamach64xx +cur
vgamga2164w +cur
vgamga4xx +cur
diff --git a/sys/src/9/pc/vgaigfx.c b/sys/src/9/pc/vgaigfx.c
index a8184041a..17eede39f 100644
--- a/sys/src/9/pc/vgaigfx.c
+++ b/sys/src/9/pc/vgaigfx.c
@@ -28,11 +28,124 @@ igfxenable(VGAscr* scr)
addvgaseg("igfxmmio", p->mem[0].bar&~0x0F, p->mem[1].size);
if(scr->paddr == 0)
vgalinearpci(scr);
- if(scr->apsize)
+ if(scr->apsize){
addvgaseg("igfxscreen", scr->paddr, scr->apsize);
+ scr->storage = (scr->apsize - 64*64*4) & ~(BY2PG-1);
+ if(scr->storage > 0x1000000)
+ scr->storage = 0x1000000;
+ }
}
VGAdev vgaigfxdev = {
"igfx",
igfxenable,
};
+
+static void
+igfxcurload(VGAscr* scr, Cursor* curs)
+{
+ uchar set, clr;
+ u32int *p;
+ int i, j;
+
+ p = (u32int*)((uchar*)scr->vaddr + scr->storage);
+ memset(p, 0, 64*64*4);
+ for(i=0;i<32;i++) {
+ set = curs->set[i];
+ clr = curs->clr[i];
+ for(j=0x80; j; j>>=1){
+ if((set|clr)&j)
+ *p++ = (0xFF<<24) | (set&j ? 0x000000 : 0xFFFFFF);
+ else
+ *p++ = 0;
+ }
+ if(i & 1)
+ p += 64-16;
+ }
+ scr->offset = curs->offset;
+}
+
+enum {
+ CURCTL = 0,
+ CURBASE,
+ CURPOS,
+
+ NPIPE = 3,
+};
+
+static u32int*
+igfxcurregs(VGAscr* scr, int pipe)
+{
+ u32int o;
+
+ if(scr->mmio == nil || scr->storage == 0)
+ return nil;
+ o = pipe*0x1000;
+ /* check PIPExCONF if enabled */
+ if((scr->mmio[(0x70008 | o)/4] & (1<<31)) == 0)
+ return nil;
+ if(scr->pci->did == 0x2a42){ /* G45 */
+ if(pipe > 1)
+ return nil;
+ o = pipe*0x40;
+ }
+ return (u32int*)((uchar*)scr->mmio + (0x70080 + o));
+}
+
+static int
+igfxcurmove(VGAscr* scr, Point p)
+{
+ int i, x, y;
+ u32int *r;
+
+ for(i=0; i<NPIPE; i++){
+ if((r = igfxcurregs(scr, i)) != nil){
+ x = p.x + scr->offset.x;
+ if(x < 0) x = -x | 0x8000;
+ y = p.y + scr->offset.y;
+ if(y < 0) y = -y | 0x8000;
+ r[CURPOS] = (y << 16) | x;
+ }
+ }
+ return 0;
+}
+
+static void
+igfxcurenable(VGAscr* scr)
+{
+ u32int *r;
+ int i;
+
+ igfxenable(scr);
+ igfxcurload(scr, &arrow);
+ igfxcurmove(scr, ZP);
+
+ for(i=0; i<NPIPE; i++){
+ if((r = igfxcurregs(scr, i)) != nil){
+ r[CURCTL] = (r[CURCTL] & ~(3<<28 | 1<<5)) | (i<<28) | 7;
+ r[CURBASE] = scr->storage;
+ }
+ }
+}
+
+static void
+igfxcurdisable(VGAscr* scr)
+{
+ u32int *r;
+ int i;
+
+ for(i=0; i<NPIPE; i++){
+ if((r = igfxcurregs(scr, i)) != nil){
+ r[CURCTL] &= ~(1<<5 | 7);
+ r[CURBASE] = 0;
+ }
+ }
+}
+
+VGAcur vgaigfxcur = {
+ "igfxhwgc",
+ igfxcurenable,
+ igfxcurdisable,
+ igfxcurload,
+ igfxcurmove,
+};
diff --git a/sys/src/9/pc64/pc64 b/sys/src/9/pc64/pc64
index f61c10beb..a5f971967 100644
--- a/sys/src/9/pc64/pc64
+++ b/sys/src/9/pc64/pc64
@@ -112,6 +112,7 @@ misc
# vgageode +cur
# vgahiqvideo +cur
# vgai81x +cur
+ vgaigfx +cur
# vgamach64xx +cur
# vgamga2164w +cur
# vgamga4xx +cur
@@ -124,7 +125,6 @@ misc
# vgatvp3020 =cur
# vgatvp3026 =cur
vgavesa
- vgaigfx
# vgavmware +cur
ip