diff options
-rw-r--r-- | sys/src/9/pc/pccpuf | 2 | ||||
-rw-r--r-- | sys/src/9/pc/pcf | 2 | ||||
-rw-r--r-- | sys/src/9/pc/vgaigfx.c | 115 | ||||
-rw-r--r-- | sys/src/9/pc64/pc64 | 2 | ||||
-rw-r--r-- | sys/src/cmd/aux/vga/data.c | 3 | ||||
-rw-r--r-- | sys/src/cmd/aux/vga/igfx.c | 60 | ||||
-rw-r--r-- | sys/src/cmd/aux/vga/vga.h | 1 |
7 files changed, 159 insertions, 26 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 diff --git a/sys/src/cmd/aux/vga/data.c b/sys/src/cmd/aux/vga/data.c index 306a5c010..f55ac5efd 100644 --- a/sys/src/cmd/aux/vga/data.c +++ b/sys/src/cmd/aux/vga/data.c @@ -41,6 +41,8 @@ Ctlr* ctlrs[] = { &ics2494, /* clock */ &ics2494a, /* clock */ &ics534x, /* gendac */ + &igfx, /* ctlr */ + &igfxhwgc, /* hwgc */ &mach32, /* ctlr */ &mach64, /* ctlr */ &mach64xx, /* ctlr */ @@ -87,7 +89,6 @@ Ctlr* ctlrs[] = { &w30c516, /* ctlr */ &mga4xx, &mga4xxhwgc, - &igfx, /* ctlr */ 0, }; diff --git a/sys/src/cmd/aux/vga/igfx.c b/sys/src/cmd/aux/vga/igfx.c index e650d385f..86a7bd25e 100644 --- a/sys/src/cmd/aux/vga/igfx.c +++ b/sys/src/cmd/aux/vga/igfx.c @@ -11,6 +11,7 @@ typedef struct Hdmi Hdmi; typedef struct Dp Dp; typedef struct Fdi Fdi; typedef struct Pfit Pfit; +typedef struct Curs Curs; typedef struct Plane Plane; typedef struct Trans Trans; typedef struct Pipe Pipe; @@ -93,6 +94,12 @@ struct Plane { Reg tileoff; /* DSPxTILEOFF */ }; +struct Curs { + Reg cntr; + Reg base; + Reg pos; +}; + struct Pipe { Trans; @@ -101,7 +108,7 @@ struct Pipe { Fdi fdi[1]; /* fdi/dp transcoder */ Plane dsp[1]; /* display plane */ - Plane cur[1]; /* cursor plane */ + Curs cur[1]; /* hardware cursor */ Pfit *pfit; /* selected panel fitter */ }; @@ -266,11 +273,13 @@ snarfpipe(Igfx *igfx, int x) switch(igfx->type){ case TypeIVB: p->cur->cntr = snarfreg(igfx, 0x70080 | x*0x1000); - p->cur->surf = snarfreg(igfx, 0x70084 | x*0x1000); + p->cur->base = snarfreg(igfx, 0x70084 | x*0x1000); + p->cur->pos = snarfreg(igfx, 0x70088 | x*0x1000); break; case TypeG45: p->cur->cntr = snarfreg(igfx, 0x70080 | x*0x40); - p->cur->surf = snarfreg(igfx, 0x70084 | x*0x40); + p->cur->base = snarfreg(igfx, 0x70084 | x*0x40); + p->cur->pos = snarfreg(igfx, 0x7008C | x*0x40); break; } } @@ -734,8 +743,9 @@ init(Vga* vga, Ctlr* ctlr) p->dsp->tileoff.v = 0; /* cursor plane off */ - p->cur->cntr.v = 0; - p->cur->surf.v = 0; + p->cur->cntr.v = x<<28; + p->cur->pos.v = 0; + p->cur->base.v = 0; if(initdpll(igfx, x, m->frequency, islvds, 0) < 0) error("%s: frequency %d out of range\n", ctlr->name, m->frequency); @@ -841,8 +851,10 @@ enablepipe(Igfx *igfx, int x) loadreg(igfx, p->dsp->tileoff); loadreg(igfx, p->dsp->surf); /* arm */ + /* program cursor */ loadreg(igfx, p->cur->cntr); - loadreg(igfx, p->cur->surf); /* arm */ + loadreg(igfx, p->cur->pos); + loadreg(igfx, p->cur->base); /* arm */ if(0){ /* enable fdi */ @@ -897,8 +909,9 @@ disablepipe(Igfx *igfx, int x) /* planes off */ csr(igfx, p->dsp->cntr.a, 1<<31, 0); csr(igfx, p->dsp->surf.a, ~0, 0); /* arm */ - csr(igfx, p->cur->cntr.a, 1<<31, 0); - csr(igfx, p->cur->surf.a, ~0, 0); /* arm */ + /* cursor off */ + csr(igfx, p->cur->cntr.a, 1<<5 | 7, 0); + csr(igfx, p->cur->base.a, ~0, 0); /* arm */ /* disable cpu pipe */ disabletrans(igfx, p); @@ -1088,7 +1101,8 @@ dumppipe(Igfx *igfx, int x) snprint(name, sizeof(name), "%s cur %c", igfx->ctlr->name, 'a'+x); dumpreg(name, "cntr", p->cur->cntr); - dumpreg(name, "surf", p->cur->surf); + dumpreg(name, "base", p->cur->base); + dumpreg(name, "pos", p->cur->pos); } static void @@ -1118,25 +1132,25 @@ dump(Vga* vga, Ctlr* ctlr) dumpreg(ctlr->name, "ssc4params", igfx->ssc4params); for(x=0; x<nelem(igfx->dp); x++){ - snprint(name, sizeof(name), "dp %c ctl", 'a'+x); - dumpreg(ctlr->name, name, igfx->dp[x].ctl); + snprint(name, sizeof(name), "%s dp %c", ctlr->name, 'a'+x); + dumpreg(name, "ctl", igfx->dp[x].ctl); } for(x=0; x<nelem(igfx->hdmi); x++){ - snprint(name, sizeof(name), "hdmi %c ctl ", 'a'+x); - dumpreg(ctlr->name, name, igfx->hdmi[x].ctl); + snprint(name, sizeof(name), "%s hdmi %c", ctlr->name, 'a'+x); + dumpreg(name, "ctl", igfx->hdmi[x].ctl); } for(x=0; x<nelem(igfx->pfit); x++){ - snprint(name, sizeof(name), "pfit %c ctrl", 'a'+x); - dumpreg(ctlr->name, name, igfx->pfit[x].ctrl); - snprint(name, sizeof(name), "pfit %c winpos", 'a'+x); - dumpreg(ctlr->name, name, igfx->pfit[x].winpos); - snprint(name, sizeof(name), "pfit %c winsize", 'a'+x); - dumpreg(ctlr->name, name, igfx->pfit[x].winsize); - snprint(name, sizeof(name), "pfit %c pwrgate", 'a'+x); - dumpreg(ctlr->name, name, igfx->pfit[x].pwrgate); + snprint(name, sizeof(name), "%s pfit %c", ctlr->name, 'a'+x); + dumpreg(name, "ctrl", igfx->pfit[x].ctrl); + dumpreg(name, "winpos", igfx->pfit[x].winpos); + dumpreg(name, "winsize", igfx->pfit[x].winsize); + dumpreg(name, "pwrgate", igfx->pfit[x].pwrgate); } + dumpreg(ctlr->name, "ppcontrol", igfx->ppcontrol); + dumpreg(ctlr->name, "ppstatus", igfx->ppstatus); + dumpreg(ctlr->name, "adpa", igfx->adpa); dumpreg(ctlr->name, "lvds", igfx->lvds); dumpreg(ctlr->name, "sdvob", igfx->sdvob); @@ -1153,3 +1167,7 @@ Ctlr igfx = { load, /* load */ dump, /* dump */ }; + +Ctlr igfxhwgc = { + "igfxhwgc", +}; diff --git a/sys/src/cmd/aux/vga/vga.h b/sys/src/cmd/aux/vga/vga.h index 51efa2438..f479edf30 100644 --- a/sys/src/cmd/aux/vga/vga.h +++ b/sys/src/cmd/aux/vga/vga.h @@ -311,6 +311,7 @@ extern Ctlr geodehwgc; /* igfx.c */ extern Ctlr igfx; +extern Ctlr igfxhwgc; /* mach32.c */ extern Ctlr mach32; |