ref: f68296383c70173976f2dc32581884868aac0252
parent: 1f46b5b9cd0d9688cb15d60c8f1a06e9471768a4
author: qwx <qwx@sciops.net>
date: Sun Jun 26 06:26:21 EDT 2022
igfx: coerce x250 display to work one wants bpc=8, the other bpc=6, not sure what to do there x250: hwgc doesn't work, checkgtt fails, modesetting multiple times will garble picture, edid gets snarfed sometimes, most times not; brightness seg(1) hack doesn't work. x240: all works, except minidp (no way to be sure, same for x250 and desktop) desktop: hdmi still good, minidp doesn't work
--- a/igfx-linktraining-fix
+++ b/igfx-linktraining-fix
@@ -1,7 +1,50 @@
-diff 7ca997bf7efdca16416b22488ebc7b70c419fd44 uncommitted
+diff 10afa189d5ee84e1935ead905b3bbe38060a92e8 uncommitted
--- a/sys/src/cmd/aux/vga/igfx.c
+++ b/sys/src/cmd/aux/vga/igfx.c
-@@ -1090,8 +1090,6 @@
+@@ -372,12 +372,12 @@
+ if(igfx->pci->vid != 0x8086)
+ return -1;
+ switch(igfx->pci->did){
++ case 0x1616: /* HD 5500 - 5th Gen Core (ULT) */
+ case 0x0a16: /* HD 4400 - 4th Gen Core (ULT) */
+ igfx->isult = 1;
+ /* wet floor */
+ case 0x0a06:
+ case 0x3185: /* UHD 600 - 9.5 Gen Core */
+- case 0x1616: /* HD 5500 - 5th Gen Core */
+ case 0x0412: /* HD 4600 - 4th Gen Core */
+ return TypeHSW;
+ case 0x0166: /* 3rd Gen Core - ThinkPad X230 */
+@@ -523,6 +523,8 @@
+ case TypeHSW:
+ igfx->npipe = 4; /* A,B,C,eDP */
+ igfx->cdclk = igfx->isult ? 450 : 540; /* MHz */
++ if(igfx->pci->did == 0x1616) // ?
++ igfx->cdclk = 540;
+
+ igfx->dpll[0].ctrl = snarfreg(igfx, 0x130040); /* LCPLL_CTL */
+ igfx->dpll[1].ctrl = snarfreg(igfx, 0x46040); /* WRPLL_CTL1 */
+@@ -927,9 +929,11 @@
+ vlong v;
+ int n;
+
++ trace("needlanes %d %d %d\n", freq, lsclk, bpp);
+ v = ((vlong)freq * bpp) / 8;
+ for(n=1; n<4 && v>lsclk; n<<=1, v>>=1)
+ ;
++ trace("needlanes %d v %llud lsclk %d\n", n, v, lsclk);
+ return n;
+ }
+
+@@ -1063,6 +1067,7 @@
+ /* bits per color for cpu pipe */
+ for(i=0; i<nelem(bpctab); i++){
+ if(bpctab[i] == bpc){
++ // FIXME: csr, etc.
+ if(igfx->type == TypeHSW){
+ p->dpctl.v &= ~(7<<20);
+ p->dpctl.v |= i<<20;
+@@ -1090,8 +1095,6 @@
if(m->z != 32)
error("%s: unsupported color depth %d\n", ctlr->name, m->z);
@@ -10,7 +53,7 @@
igfx = vga->private;
/* disable vga */
-@@ -1133,12 +1131,11 @@
+@@ -1133,12 +1136,11 @@
if((val = dbattr(m->attr, "display")) != nil){
port = atoi(val)-1;
@@ -24,16 +67,67 @@
trace("%s: display #%d\n", ctlr->name, port+1);
-@@ -1217,7 +1214,7 @@
+@@ -1206,10 +1208,15 @@
+
+ if(igfx->type == TypeHSW){
+ if(port == PortDPA){
++ int c;
++
+ /* only enable panel for eDP */
+ igfx->ppcontrol.v |= 5;
+ /* use eDP pipe */
+ x = 3;
++ c = rr(igfx, igfx->pipe[x].dpctl.a);
++ if((c & 7<<20) == 2<<20) /* 0 is bpc=8 */
++ bpc = 6;
+ }
+
+ /* reserved MBZ */
+@@ -1216,8 +1223,8 @@
+ r->v &= ~(7<<28) & ~(1<<26) & ~(63<<19) & ~(3<<16) & ~(15<<11) & ~(1<<7) & ~31;
/* displayport SST mode */
r->v &= ~(1<<27);
- /* link not in training, send normal pixels */
+- /* link not in training, send normal pixels */
- r->v |= 3<<8;
-+ r->v &= ~(7<<8); /* enable with pat1 armed */
++ /* enable with training pattern 1 armed */
++ r->v &= ~(7<<8);
if(igfx->dp[port-PortDPA].hdmi){
/* hdmi: do not configure displayport */
r->a = 0;
-@@ -1556,9 +1553,6 @@
+@@ -1229,11 +1236,6 @@
+ r->v |= 1<<31;
+ /* reserved MBZ */
+ r->v &= ~(7<<28) & ~(127<<17) & ~(255<<8) & ~(3<<5);
+- /* grab lanes shared with port e when using port a */
+- if(port == PortDPA)
+- r->v |= 1<<4;
+- else if(port == PortDPE)
+- igfx->dp[0].bufctl.v &= ~(1<<4);
+ /* dp port width */
+ r->v &= ~(15<<1);
+ if(!igfx->dp[port-PortDPA].hdmi){
+@@ -1243,6 +1245,11 @@
+ goto Badport;
+ r->v |= nl-1 << 1;
+ }
++ /* grab lanes shared with port e when using port a */
++ if(port == PortDPA) // FIXME: shoudn't be touched?
++ r->v |= 1<<4;
++ else if(port == PortDPE)
++ igfx->dp[0].bufctl.v &= ~(1<<4);
+ /* port reversal: off */
+ r->v &= ~(1<<16);
+
+@@ -1306,7 +1313,7 @@
+ }
+ p = &igfx->pipe[x];
+
+- /* plane enable, 32bpp */
++ /* plane enable, 32bit BGRX 8:8:8 */
+ p->dsp->cntr.v = (1<<31) | (6<<26);
+ if(igfx->type == TypeG45)
+ p->dsp->cntr.v |= x<<24; /* pipe assign */
+@@ -1556,9 +1563,6 @@
{
int i;
@@ -43,7 +137,7 @@
/* disable displayport transcoder */
if(igfx->type == TypeHSW){
csr(igfx, t->dpctl.a, 15<<28, 0);
-@@ -1582,6 +1576,9 @@
+@@ -1582,6 +1586,9 @@
/* workaround: clear timing override bit */
csr(igfx, t->chicken.a, 1<<31, 0);
@@ -53,7 +147,16 @@
/* disable dpll */
if(igfx->type != TypeHSW && t->dpll != nil)
csr(igfx, t->dpll->ctrl.a, 1<<31, 0);
-@@ -1766,6 +1763,9 @@
+@@ -1644,6 +1651,8 @@
+ if((gtt[i] & ~((1<<11)-1<<1)) != pa)
+ break;
+ n = m->x * m->y * m->z / 8;
++ trace("checkgtt %d %d %d = %lud >=? %ud (%d)\n",
++ m->x, m->y, m->z, n, i<<12, i);
+ if(i<<12 >= n)
+ return;
+
+@@ -1766,6 +1775,9 @@
csr(igfx, igfx->dpll[x].ctrl.a, 1<<31, 0);
}
@@ -63,7 +166,7 @@
/* program new clock sources */
loadreg(igfx, igfx->rawclkfreq);
loadreg(igfx, igfx->drefctl);
-@@ -1781,6 +1781,7 @@
+@@ -1781,6 +1793,7 @@
/* new dpll setting */
for(x=0; x<nelem(igfx->dpllsel); x++)
loadreg(igfx, igfx->dpllsel[x]);
@@ -71,7 +174,7 @@
/* program all pipes */
for(x = 0; x < igfx->npipe; x++)
-@@ -1794,16 +1795,25 @@
+@@ -1794,16 +1807,25 @@
loadreg(igfx, igfx->sdvob);
loadreg(igfx, igfx->sdvoc);
for(x = 0; x < nelem(igfx->dp); x++){
@@ -100,7 +203,7 @@
ctlr->flag |= Fload;
}
-@@ -2138,7 +2148,7 @@
+@@ -2138,7 +2160,7 @@
buf[1] = addr >> 8;
buf[2] = addr;
buf[3] = len-1;
@@ -109,7 +212,7 @@
if(data != nil && len > 0){
if((cmd & CmdRead) == 0)
memmove(buf+4, data, len);
-@@ -2188,13 +2198,13 @@
+@@ -2188,13 +2210,13 @@
if((dp->ctl.v & (1<<31)) == 0)
return 0;
@@ -129,7 +232,7 @@
wdpaux(igfx, dp, 0x101, w+1);
r = 0;
-@@ -2244,11 +2254,8 @@
+@@ -2244,11 +2266,8 @@
break;
}
}