changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: igfx: implement hardware cursor

changeset 4186: 57a248708321
parent 4185: 3c381fe21634
child 4187: 8fb78de1301d
author: cinap_lenrek@felloff.net
date: Fri, 09 Jan 2015 22:23:25 +0100
files: sys/src/9/pc/pccpuf sys/src/9/pc/pcf sys/src/9/pc/vgaigfx.c sys/src/9/pc64/pc64 sys/src/cmd/aux/vga/data.c sys/src/cmd/aux/vga/igfx.c sys/src/cmd/aux/vga/vga.h
description: 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
     1.1--- a/sys/src/9/pc/pccpuf
     1.2+++ b/sys/src/9/pc/pccpuf
     1.3@@ -113,7 +113,7 @@ misc
     1.4 	vgageode	+cur
     1.5 	vgahiqvideo	+cur
     1.6 	vgai81x		+cur
     1.7-	vgaigfx
     1.8+	vgaigfx		+cur
     1.9 	vgamach64xx	+cur
    1.10 	vgamga2164w	+cur
    1.11 	vgamga4xx	+cur
     2.1--- a/sys/src/9/pc/pcf
     2.2+++ b/sys/src/9/pc/pcf
     2.3@@ -114,7 +114,7 @@ misc
     2.4 	vgageode	+cur
     2.5 	vgahiqvideo	+cur
     2.6 	vgai81x		+cur
     2.7-	vgaigfx
     2.8+	vgaigfx		+cur
     2.9 	vgamach64xx	+cur
    2.10 	vgamga2164w	+cur
    2.11 	vgamga4xx	+cur
     3.1--- a/sys/src/9/pc/vgaigfx.c
     3.2+++ b/sys/src/9/pc/vgaigfx.c
     3.3@@ -28,11 +28,124 @@ igfxenable(VGAscr* scr)
     3.4 	addvgaseg("igfxmmio", p->mem[0].bar&~0x0F, p->mem[1].size);
     3.5 	if(scr->paddr == 0)
     3.6 		vgalinearpci(scr);
     3.7-	if(scr->apsize)
     3.8+	if(scr->apsize){
     3.9 		addvgaseg("igfxscreen", scr->paddr, scr->apsize);
    3.10+		scr->storage = (scr->apsize - 64*64*4) & ~(BY2PG-1);
    3.11+		if(scr->storage > 0x1000000)
    3.12+			scr->storage = 0x1000000;
    3.13+	}
    3.14 }
    3.15 
    3.16 VGAdev vgaigfxdev = {
    3.17 	"igfx",
    3.18 	igfxenable,
    3.19 };
    3.20+
    3.21+static void
    3.22+igfxcurload(VGAscr* scr, Cursor* curs)
    3.23+{
    3.24+	uchar set, clr;
    3.25+	u32int *p;
    3.26+	int i, j;
    3.27+
    3.28+	p = (u32int*)((uchar*)scr->vaddr + scr->storage);
    3.29+	memset(p, 0, 64*64*4);
    3.30+	for(i=0;i<32;i++) {
    3.31+		set = curs->set[i];
    3.32+		clr = curs->clr[i];
    3.33+		for(j=0x80; j; j>>=1){
    3.34+			if((set|clr)&j)
    3.35+				*p++ = (0xFF<<24) | (set&j ? 0x000000 : 0xFFFFFF);
    3.36+			else
    3.37+				*p++ = 0;
    3.38+		}
    3.39+		if(i & 1)
    3.40+			p += 64-16;
    3.41+	}
    3.42+	scr->offset = curs->offset;
    3.43+}
    3.44+
    3.45+enum {
    3.46+	CURCTL = 0,
    3.47+	CURBASE,
    3.48+	CURPOS,
    3.49+
    3.50+	NPIPE = 3,
    3.51+};
    3.52+
    3.53+static u32int*
    3.54+igfxcurregs(VGAscr* scr, int pipe)
    3.55+{
    3.56+	u32int o;
    3.57+
    3.58+	if(scr->mmio == nil || scr->storage == 0)
    3.59+		return nil;
    3.60+	o = pipe*0x1000;
    3.61+	/* check PIPExCONF if enabled */
    3.62+	if((scr->mmio[(0x70008 | o)/4] & (1<<31)) == 0)
    3.63+		return nil;
    3.64+	if(scr->pci->did == 0x2a42){	/* G45 */
    3.65+		if(pipe > 1)
    3.66+			return nil;
    3.67+		o = pipe*0x40;
    3.68+	}
    3.69+	return (u32int*)((uchar*)scr->mmio + (0x70080 + o));
    3.70+}
    3.71+
    3.72+static int
    3.73+igfxcurmove(VGAscr* scr, Point p)
    3.74+{
    3.75+	int i, x, y;
    3.76+	u32int *r;
    3.77+
    3.78+	for(i=0; i<NPIPE; i++){
    3.79+		if((r = igfxcurregs(scr, i)) != nil){
    3.80+			x = p.x + scr->offset.x;
    3.81+			if(x < 0) x = -x | 0x8000;
    3.82+			y = p.y + scr->offset.y;
    3.83+			if(y < 0) y = -y | 0x8000;
    3.84+			r[CURPOS] = (y << 16) | x;
    3.85+		}
    3.86+	}
    3.87+	return 0;
    3.88+}
    3.89+
    3.90+static void
    3.91+igfxcurenable(VGAscr* scr)
    3.92+{
    3.93+	u32int *r;
    3.94+	int i;
    3.95+
    3.96+	igfxenable(scr);
    3.97+	igfxcurload(scr, &arrow);
    3.98+	igfxcurmove(scr, ZP);
    3.99+
   3.100+	for(i=0; i<NPIPE; i++){
   3.101+		if((r = igfxcurregs(scr, i)) != nil){
   3.102+			r[CURCTL] = (r[CURCTL] & ~(3<<28 | 1<<5)) | (i<<28) | 7;
   3.103+			r[CURBASE] = scr->storage;
   3.104+		}
   3.105+	}
   3.106+}
   3.107+
   3.108+static void
   3.109+igfxcurdisable(VGAscr* scr)
   3.110+{
   3.111+	u32int *r;
   3.112+	int i;
   3.113+
   3.114+	for(i=0; i<NPIPE; i++){
   3.115+		if((r = igfxcurregs(scr, i)) != nil){
   3.116+			r[CURCTL] &= ~(1<<5 | 7);
   3.117+			r[CURBASE] = 0;
   3.118+		}
   3.119+	}
   3.120+}
   3.121+
   3.122+VGAcur vgaigfxcur = {
   3.123+	"igfxhwgc",
   3.124+	igfxcurenable,
   3.125+	igfxcurdisable,
   3.126+	igfxcurload,
   3.127+	igfxcurmove,
   3.128+};
     4.1--- a/sys/src/9/pc64/pc64
     4.2+++ b/sys/src/9/pc64/pc64
     4.3@@ -112,6 +112,7 @@ misc
     4.4 #	vgageode	+cur
     4.5 #	vgahiqvideo	+cur
     4.6 #	vgai81x		+cur
     4.7+	vgaigfx		+cur
     4.8 #	vgamach64xx	+cur
     4.9 #	vgamga2164w	+cur
    4.10 #	vgamga4xx	+cur
    4.11@@ -124,7 +125,6 @@ misc
    4.12 #	vgatvp3020	=cur
    4.13 #	vgatvp3026	=cur
    4.14 	vgavesa
    4.15-	vgaigfx
    4.16 #	vgavmware	+cur
    4.17 
    4.18 ip
     5.1--- a/sys/src/cmd/aux/vga/data.c
     5.2+++ b/sys/src/cmd/aux/vga/data.c
     5.3@@ -41,6 +41,8 @@ Ctlr* ctlrs[] = {
     5.4 	&ics2494,				/* clock */
     5.5 	&ics2494a,				/* clock */
     5.6 	&ics534x,				/* gendac */
     5.7+	&igfx,					/* ctlr */
     5.8+	&igfxhwgc,				/* hwgc */
     5.9 	&mach32,				/* ctlr */
    5.10 	&mach64,				/* ctlr */
    5.11 	&mach64xx,				/* ctlr */
    5.12@@ -87,7 +89,6 @@ Ctlr* ctlrs[] = {
    5.13 	&w30c516,				/* ctlr */
    5.14 	&mga4xx,
    5.15 	&mga4xxhwgc,
    5.16-	&igfx,					/* ctlr */
    5.17 	0,
    5.18 };
    5.19 
     6.1--- a/sys/src/cmd/aux/vga/igfx.c
     6.2+++ b/sys/src/cmd/aux/vga/igfx.c
     6.3@@ -11,6 +11,7 @@ typedef struct Hdmi Hdmi;
     6.4 typedef struct Dp Dp;
     6.5 typedef struct Fdi Fdi;
     6.6 typedef struct Pfit Pfit;
     6.7+typedef struct Curs Curs;
     6.8 typedef struct Plane Plane;
     6.9 typedef struct Trans Trans;
    6.10 typedef struct Pipe Pipe;
    6.11@@ -93,6 +94,12 @@ struct Plane {
    6.12 	Reg	tileoff;	/* DSPxTILEOFF */
    6.13 };
    6.14 
    6.15+struct Curs {
    6.16+	Reg	cntr;
    6.17+	Reg	base;
    6.18+	Reg	pos;
    6.19+};
    6.20+
    6.21 struct Pipe {
    6.22 	Trans;
    6.23 
    6.24@@ -101,7 +108,7 @@ struct Pipe {
    6.25 	Fdi	fdi[1];		/* fdi/dp transcoder */
    6.26 
    6.27 	Plane	dsp[1];		/* display plane */
    6.28-	Plane	cur[1];		/* cursor plane */
    6.29+	Curs	cur[1];		/* hardware cursor */
    6.30 
    6.31 	Pfit	*pfit;		/* selected panel fitter */
    6.32 };
    6.33@@ -266,11 +273,13 @@ snarfpipe(Igfx *igfx, int x)
    6.34 	switch(igfx->type){
    6.35 	case TypeIVB:
    6.36 		p->cur->cntr	= snarfreg(igfx, 0x70080 | x*0x1000);
    6.37-		p->cur->surf	= snarfreg(igfx, 0x70084 | x*0x1000);
    6.38+		p->cur->base	= snarfreg(igfx, 0x70084 | x*0x1000);
    6.39+		p->cur->pos	= snarfreg(igfx, 0x70088 | x*0x1000);
    6.40 		break;
    6.41 	case TypeG45:
    6.42 		p->cur->cntr	= snarfreg(igfx, 0x70080 | x*0x40);
    6.43-		p->cur->surf	= snarfreg(igfx, 0x70084 | x*0x40);
    6.44+		p->cur->base	= snarfreg(igfx, 0x70084 | x*0x40);
    6.45+		p->cur->pos	= snarfreg(igfx, 0x7008C | x*0x40);
    6.46 		break;
    6.47 	}
    6.48 }
    6.49@@ -734,8 +743,9 @@ init(Vga* vga, Ctlr* ctlr)
    6.50 	p->dsp->tileoff.v = 0;
    6.51 
    6.52 	/* cursor plane off */
    6.53-	p->cur->cntr.v = 0;
    6.54-	p->cur->surf.v = 0;
    6.55+	p->cur->cntr.v = x<<28;
    6.56+	p->cur->pos.v = 0;
    6.57+	p->cur->base.v = 0;
    6.58 
    6.59 	if(initdpll(igfx, x, m->frequency, islvds, 0) < 0)
    6.60 		error("%s: frequency %d out of range\n", ctlr->name, m->frequency);
    6.61@@ -841,8 +851,10 @@ enablepipe(Igfx *igfx, int x)
    6.62 	loadreg(igfx, p->dsp->tileoff);
    6.63 	loadreg(igfx, p->dsp->surf);	/* arm */
    6.64 
    6.65+	/* program cursor */
    6.66 	loadreg(igfx, p->cur->cntr);
    6.67-	loadreg(igfx, p->cur->surf);	/* arm */
    6.68+	loadreg(igfx, p->cur->pos);
    6.69+	loadreg(igfx, p->cur->base);	/* arm */
    6.70 
    6.71 	if(0){
    6.72 		/* enable fdi */
    6.73@@ -897,8 +909,9 @@ disablepipe(Igfx *igfx, int x)
    6.74 	/* planes off */
    6.75 	csr(igfx, p->dsp->cntr.a, 1<<31, 0);
    6.76 	csr(igfx, p->dsp->surf.a, ~0, 0);	/* arm */
    6.77-	csr(igfx, p->cur->cntr.a, 1<<31, 0);
    6.78-	csr(igfx, p->cur->surf.a, ~0, 0);	/* arm */
    6.79+	/* cursor off */
    6.80+	csr(igfx, p->cur->cntr.a, 1<<5 | 7, 0);
    6.81+	csr(igfx, p->cur->base.a, ~0, 0);	/* arm */
    6.82 
    6.83 	/* disable cpu pipe */
    6.84 	disabletrans(igfx, p);
    6.85@@ -1088,7 +1101,8 @@ dumppipe(Igfx *igfx, int x)
    6.86 
    6.87 	snprint(name, sizeof(name), "%s cur %c", igfx->ctlr->name, 'a'+x);
    6.88 	dumpreg(name, "cntr", p->cur->cntr);
    6.89-	dumpreg(name, "surf", p->cur->surf);
    6.90+	dumpreg(name, "base", p->cur->base);
    6.91+	dumpreg(name, "pos", p->cur->pos);
    6.92 }
    6.93 
    6.94 static void
    6.95@@ -1118,25 +1132,25 @@ dump(Vga* vga, Ctlr* ctlr)
    6.96 	dumpreg(ctlr->name, "ssc4params", igfx->ssc4params);
    6.97 
    6.98 	for(x=0; x<nelem(igfx->dp); x++){
    6.99-		snprint(name, sizeof(name), "dp %c ctl", 'a'+x);
   6.100-		dumpreg(ctlr->name, name, igfx->dp[x].ctl);
   6.101+		snprint(name, sizeof(name), "%s dp %c", ctlr->name, 'a'+x);
   6.102+		dumpreg(name, "ctl", igfx->dp[x].ctl);
   6.103 	}
   6.104 	for(x=0; x<nelem(igfx->hdmi); x++){
   6.105-		snprint(name, sizeof(name), "hdmi %c ctl ", 'a'+x);
   6.106-		dumpreg(ctlr->name, name, igfx->hdmi[x].ctl);
   6.107+		snprint(name, sizeof(name), "%s hdmi %c", ctlr->name, 'a'+x);
   6.108+		dumpreg(name, "ctl", igfx->hdmi[x].ctl);
   6.109 	}
   6.110 
   6.111 	for(x=0; x<nelem(igfx->pfit); x++){
   6.112-		snprint(name, sizeof(name), "pfit %c ctrl", 'a'+x);
   6.113-		dumpreg(ctlr->name, name, igfx->pfit[x].ctrl);
   6.114-		snprint(name, sizeof(name), "pfit %c winpos", 'a'+x);
   6.115-		dumpreg(ctlr->name, name, igfx->pfit[x].winpos);
   6.116-		snprint(name, sizeof(name), "pfit %c winsize", 'a'+x);
   6.117-		dumpreg(ctlr->name, name, igfx->pfit[x].winsize);
   6.118-		snprint(name, sizeof(name), "pfit %c pwrgate", 'a'+x);
   6.119-		dumpreg(ctlr->name, name, igfx->pfit[x].pwrgate);
   6.120+		snprint(name, sizeof(name), "%s pfit %c", ctlr->name, 'a'+x);
   6.121+		dumpreg(name, "ctrl", igfx->pfit[x].ctrl);
   6.122+		dumpreg(name, "winpos", igfx->pfit[x].winpos);
   6.123+		dumpreg(name, "winsize", igfx->pfit[x].winsize);
   6.124+		dumpreg(name, "pwrgate", igfx->pfit[x].pwrgate);
   6.125 	}
   6.126 
   6.127+	dumpreg(ctlr->name, "ppcontrol", igfx->ppcontrol);
   6.128+	dumpreg(ctlr->name, "ppstatus", igfx->ppstatus);
   6.129+
   6.130 	dumpreg(ctlr->name, "adpa", igfx->adpa);
   6.131 	dumpreg(ctlr->name, "lvds", igfx->lvds);
   6.132 	dumpreg(ctlr->name, "sdvob", igfx->sdvob);
   6.133@@ -1153,3 +1167,7 @@ Ctlr igfx = {
   6.134 	load,			/* load */
   6.135 	dump,			/* dump */
   6.136 };
   6.137+
   6.138+Ctlr igfxhwgc = {
   6.139+	"igfxhwgc",
   6.140+};
     7.1--- a/sys/src/cmd/aux/vga/vga.h
     7.2+++ b/sys/src/cmd/aux/vga/vga.h
     7.3@@ -311,6 +311,7 @@ extern Ctlr geodehwgc;
     7.4 
     7.5 /* igfx.c */
     7.6 extern Ctlr igfx;
     7.7+extern Ctlr igfxhwgc;
     7.8 
     7.9 /* mach32.c */
    7.10 extern Ctlr mach32;