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: