ref: 6fbb3c30e1e9643a93fee95eaf0943f4e06328dc
dir: /igfx-linktraining-fix/
diff f0fc84aba3a40557539e7c014454b916a101759d uncommitted --- a/sys/src/cmd/aux/vga/igfx.c +++ b/sys/src/cmd/aux/vga/igfx.c @@ -1090,8 +1090,6 @@ if(m->z != 32) error("%s: unsupported color depth %d\n", ctlr->name, m->z); - bpc = 8; /* bits per color channel */ - igfx = vga->private; /* disable vga */ @@ -1133,12 +1131,11 @@ if((val = dbattr(m->attr, "display")) != nil){ port = atoi(val)-1; - if(igfx->type == TypeHSW && !igfx->dp[port-PortDPA].hdmi) - bpc = 6; }else if(dbattr(m->attr, "lcd") != nil) port = PortLCD; else port = PortVGA; + bpc = 8; /* bits per color channel */ trace("%s: display #%d\n", ctlr->name, port+1); @@ -1217,7 +1214,7 @@ /* displayport SST mode */ r->v &= ~(1<<27); /* link not in training, send normal pixels */ - r->v |= 3<<8; + r->v &= ~(7<<8); /* enable with pat1 armed */ if(igfx->dp[port-PortDPA].hdmi){ /* hdmi: do not configure displayport */ r->a = 0; @@ -1556,12 +1553,11 @@ { int i; - /* deselect pipe clock */ - csr(igfx, t->clksel.a, 7<<29, 0); - /* disable displayport transcoder */ if(igfx->type == TypeHSW){ csr(igfx, t->dpctl.a, 15<<28, 0); + csr(igfx, t->dpctl.a, 0, 1<<31); /* workaround */ + csr(igfx, t->dpctl.a, 1<<31, 0); csr(igfx, t->ht.a, ~0, 0); csr(igfx, t->hb.a, ~0, 0); csr(igfx, t->hs.a, ~0, 0); @@ -1582,6 +1578,9 @@ /* workaround: clear timing override bit */ csr(igfx, t->chicken.a, 1<<31, 0); + /* deselect pipe clock */ + csr(igfx, t->clksel.a, 7<<29, 0); + /* disable dpll */ if(igfx->type != TypeHSW && t->dpll != nil) csr(igfx, t->dpll->ctrl.a, 1<<31, 0); @@ -1781,6 +1780,7 @@ /* new dpll setting */ for(x=0; x<nelem(igfx->dpllsel); x++) loadreg(igfx, igfx->dpllsel[x]); + sleep(10); /* program all pipes */ for(x = 0; x < igfx->npipe; x++) @@ -1794,11 +1794,23 @@ loadreg(igfx, igfx->sdvob); loadreg(igfx, igfx->sdvoc); for(x = 0; x < nelem(igfx->dp); x++){ + if((igfx->dp[x].ctl.a == 0 || (igfx->dp[x].ctl.v & 1<<31) == 0) && !igfx->dp[x].hdmi) + continue; + if(!igfx->dp[x].hdmi){ + igfx->dp[x].ctl.v &= ~(7<<8); /* arm pattern 1 */ + loadreg(igfx, igfx->dp[x].ctl); + } for(y=0; y<nelem(igfx->dp[x].buftrans); y++) loadreg(igfx, igfx->dp[x].buftrans[y]); + sleep(500); loadreg(igfx, igfx->dp[x].bufctl); + sleep(1000); if(enabledp(igfx, &igfx->dp[x]) < 0) ctlr->flag |= Ferror; + if(!igfx->dp[x].hdmi){ + igfx->dp[x].ctl.v |= 3<<8; /* send normal pixels */ + loadreg(igfx, igfx->dp[x].ctl); + } } /* program lcd power */ @@ -2138,7 +2150,7 @@ buf[1] = addr >> 8; buf[2] = addr; buf[3] = len-1; - r = 3; + r = 3; if(data != nil && len > 0){ if((cmd & CmdRead) == 0) memmove(buf+4, data, len); @@ -2188,13 +2200,13 @@ if((dp->ctl.v & (1<<31)) == 0) return 0; - /* FIXME: always times out */ - if(igfx->type == TypeHSW && dp == &igfx->dp[0]) - goto Skip; - + int try2 = 0; /* Link configuration */ - wdpaux(igfx, dp, 0x100, (270*MHz) / 27000000); - w = dp->ctl.v >> (igfx->type == TypeHSW ? 1 : 19) & 7; + while(try2 < 32 && wdpaux(igfx, dp, 0x100, (270*MHz) / 27000000) < 0){ + try2++; + sleep(100); + } + w = dp->bufctl.v >> (igfx->type == TypeHSW ? 1 : 19) & 7; wdpaux(igfx, dp, 0x101, w+1); r = 0; @@ -2244,12 +2256,10 @@ break; } } -Skip: + /* stop training */ - dp->ctl.v &= ~(7<<8); - dp->ctl.v |= 3<<8; - loadreg(igfx, dp->ctl); wdpaux(igfx, dp, 0x102, 0x00); + fprint(2, "ctl %08#p a %08#ux v %08#ux\n", &dp->ctl, dp->ctl.a, dp->ctl.v); return 1; Fail: