ref: cfdbf5977b2b0b74f02c3b5bbeddde570fa75aee
parent: 25c260fde5a5ee9ca01bd805e88e89f0f508f803
author: qwx <qwx@sciops.net>
date: Sun Jun 19 05:23:04 EDT 2022
add igfx: fix dp link training, bogus kludges; now works on x240 external monitors still don't quite work, but i only have two shitty ones that are buggy and don't work anyway with anything
--- /dev/null
+++ b/igfx-linktraining-fix
@@ -1,0 +1,161 @@
+diff 990ceeef3bfd9d56e2e6dd39cf5ac185b1a2de08 uncommitted
+--- a/sys/src/cmd/aux/vga/igfx.c
++++ b/sys/src/cmd/aux/vga/igfx.c
+@@ -1133,8 +1133,6 @@
+
+ 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
+@@ -1217,7 +1215,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;
+@@ -1434,6 +1432,20 @@
+ sleep(5);
+ }
+
++ /* program plane */
++ loadreg(igfx, p->dsp->cntr);
++ loadreg(igfx, p->dsp->linoff);
++ loadreg(igfx, p->dsp->stride);
++ loadreg(igfx, p->dsp->tileoff);
++ loadreg(igfx, p->dsp->size);
++ loadreg(igfx, p->dsp->pos);
++ loadreg(igfx, p->dsp->surf); /* arm */
++ loadreg(igfx, p->dsp->leftsurf);
++
++ /* enable planes */
++ p->conf.v &= ~(3<<18);
++ loadreg(igfx, p->conf);
++
+ /* image size (vga needs to be off) */
+ loadreg(igfx, p->src);
+
+@@ -1451,27 +1463,11 @@
+ /* enable cpu pipe */
+ loadtrans(igfx, p);
+
+- /* program plane */
+- loadreg(igfx, p->dsp->cntr);
+- loadreg(igfx, p->dsp->linoff);
+- loadreg(igfx, p->dsp->stride);
+- loadreg(igfx, p->dsp->tileoff);
+- loadreg(igfx, p->dsp->size);
+- loadreg(igfx, p->dsp->pos);
+- loadreg(igfx, p->dsp->surf); /* arm */
+- loadreg(igfx, p->dsp->leftsurf);
+-
+ /* program cursor */
+ loadreg(igfx, p->cur->cntr);
+ loadreg(igfx, p->cur->pos);
+ loadreg(igfx, p->cur->base); /* arm */
+
+- /* enable planes */
+- if(igfx->type == TypeG45) {
+- p->conf.v &= ~(3<<18);
+- loadreg(igfx, p->conf);
+- }
+-
+ if(p->fdi->rxctl.a != 0){
+ /* enable fdi */
+ loadreg(igfx, p->fdi->rxtu[1]);
+@@ -1755,7 +1751,6 @@
+ wr(igfx, igfx->pipe[0].dsp->surf.a, 0); /* arm */
+ csr(igfx, igfx->pipe[0].conf.a, 0, 3<<18);
+ }
+-
+ if(igfx->type == TypeHSW){
+ /* deselect port clock */
+ for(x=0; x<nelem(igfx->dpllsel); x++)
+@@ -1782,6 +1777,22 @@
+ for(x=0; x<nelem(igfx->dpllsel); x++)
+ loadreg(igfx, igfx->dpllsel[x]);
+
++ for(x = 0; x < nelem(igfx->dp); x++){
++ if(igfx->dp[x].ctl.a == 0 || (igfx->dp[x].ctl.v & 1<<31) == 0)
++ continue;
++ 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(100);
++ loadreg(igfx, igfx->dp[x].bufctl);
++ sleep(500);
++ if(enabledp(igfx, &igfx->dp[x]) < 0)
++ ctlr->flag |= Ferror;
++ igfx->dp[x].ctl.v |= 3<<8;
++ loadreg(igfx, igfx->dp[x].ctl);
++ }
++
+ /* program all pipes */
+ for(x = 0; x < igfx->npipe; x++)
+ enablepipe(igfx, x);
+@@ -1793,13 +1804,6 @@
+ loadreg(igfx, igfx->adpa);
+ loadreg(igfx, igfx->sdvob);
+ loadreg(igfx, igfx->sdvoc);
+- for(x = 0; x < nelem(igfx->dp); x++){
+- for(y=0; y<nelem(igfx->dp[x].buftrans); y++)
+- loadreg(igfx, igfx->dp[x].buftrans[y]);
+- loadreg(igfx, igfx->dp[x].bufctl);
+- if(enabledp(igfx, &igfx->dp[x]) < 0)
+- ctlr->flag |= Ferror;
+- }
+
+ /* program lcd power */
+ loadreg(igfx, igfx->ppcontrol);
+@@ -2138,7 +2142,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 +2192,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,11 +2248,12 @@
+ break;
+ }
+ }
+-Skip:
+ /* stop training */
+- dp->ctl.v &= ~(7<<8);
+- dp->ctl.v |= 3<<8;
+- loadreg(igfx, dp->ctl);
++ if(dp != &igfx->dp[0]){ // eDP: done later
++ dp->ctl.v &= ~(7<<8);
++ dp->ctl.v |= 3<<8;
++ loadreg(igfx, dp->ctl);
++ }
+ wdpaux(igfx, dp, 0x102, 0x00);
+ return 1;
+