merge
This commit is contained in:
commit
51f76ae999
1 changed files with 94 additions and 31 deletions
|
@ -89,6 +89,8 @@ struct Fdi {
|
||||||
|
|
||||||
Reg rxctl; /* FDI_RX_CTL */
|
Reg rxctl; /* FDI_RX_CTL */
|
||||||
Reg rxmisc; /* FDI_RX_MISC */
|
Reg rxmisc; /* FDI_RX_MISC */
|
||||||
|
Reg rxiir; /* FDI_RX_IIR */
|
||||||
|
Reg rximr; /* FDI_RX_IMR */
|
||||||
Reg rxtu[2]; /* FDI_RX_TUSIZE */
|
Reg rxtu[2]; /* FDI_RX_TUSIZE */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -276,6 +278,10 @@ snarfpipe(Igfx *igfx, int x)
|
||||||
|
|
||||||
p->fdi->rxctl = snarfreg(igfx, o + 0x1000c);
|
p->fdi->rxctl = snarfreg(igfx, o + 0x1000c);
|
||||||
p->fdi->rxmisc = snarfreg(igfx, o + 0x10010);
|
p->fdi->rxmisc = snarfreg(igfx, o + 0x10010);
|
||||||
|
|
||||||
|
p->fdi->rxiir = snarfreg(igfx, o + 0x10014);
|
||||||
|
p->fdi->rximr = snarfreg(igfx, o + 0x10018);
|
||||||
|
|
||||||
p->fdi->rxtu[0] = snarfreg(igfx, o + 0x10030);
|
p->fdi->rxtu[0] = snarfreg(igfx, o + 0x10030);
|
||||||
p->fdi->rxtu[1] = snarfreg(igfx, o + 0x10038);
|
p->fdi->rxtu[1] = snarfreg(igfx, o + 0x10038);
|
||||||
|
|
||||||
|
@ -297,7 +303,6 @@ snarfpipe(Igfx *igfx, int x)
|
||||||
/* cursor plane */
|
/* cursor plane */
|
||||||
switch(igfx->type){
|
switch(igfx->type){
|
||||||
case TypeIVB:
|
case TypeIVB:
|
||||||
case TypeSNB:
|
|
||||||
p->cur->cntr = snarfreg(igfx, 0x70080 + x*0x1000);
|
p->cur->cntr = snarfreg(igfx, 0x70080 + x*0x1000);
|
||||||
p->cur->base = snarfreg(igfx, 0x70084 + x*0x1000);
|
p->cur->base = snarfreg(igfx, 0x70084 + x*0x1000);
|
||||||
p->cur->pos = snarfreg(igfx, 0x70088 + x*0x1000);
|
p->cur->pos = snarfreg(igfx, 0x70088 + x*0x1000);
|
||||||
|
@ -305,7 +310,8 @@ snarfpipe(Igfx *igfx, int x)
|
||||||
case TypeG45:
|
case TypeG45:
|
||||||
p->dsp->pos = snarfreg(igfx, 0x7018C + x*0x1000);
|
p->dsp->pos = snarfreg(igfx, 0x7018C + x*0x1000);
|
||||||
p->dsp->size = snarfreg(igfx, 0x70190 + x*0x1000);
|
p->dsp->size = snarfreg(igfx, 0x70190 + x*0x1000);
|
||||||
|
/* wet floor */
|
||||||
|
case TypeSNB:
|
||||||
p->cur->cntr = snarfreg(igfx, 0x70080 + x*0x40);
|
p->cur->cntr = snarfreg(igfx, 0x70080 + x*0x40);
|
||||||
p->cur->base = snarfreg(igfx, 0x70084 + x*0x40);
|
p->cur->base = snarfreg(igfx, 0x70084 + x*0x40);
|
||||||
p->cur->pos = snarfreg(igfx, 0x70088 + x*0x40);
|
p->cur->pos = snarfreg(igfx, 0x70088 + x*0x40);
|
||||||
|
@ -320,10 +326,13 @@ devtype(Igfx *igfx)
|
||||||
return -1;
|
return -1;
|
||||||
switch(igfx->pci->did){
|
switch(igfx->pci->did){
|
||||||
case 0x0166: /* 3rd Gen Core - ThinkPad X230 */
|
case 0x0166: /* 3rd Gen Core - ThinkPad X230 */
|
||||||
|
case 0x0152: /* 2nd/3rd Gen Core - Core-i3 */
|
||||||
return TypeIVB;
|
return TypeIVB;
|
||||||
|
case 0x0102: /* Dell Optiplex 790 */
|
||||||
case 0x0126: /* Thinkpad X220 */
|
case 0x0126: /* Thinkpad X220 */
|
||||||
return TypeSNB;
|
return TypeSNB;
|
||||||
case 0x27a2: /* GM945/82940GML - ThinkPad X60 Tablet */
|
case 0x27a2: /* GM945/82940GML - ThinkPad X60 Tablet */
|
||||||
|
case 0x29a2: /* 82P965/G965 HECI desktop */
|
||||||
case 0x2a02: /* GM965/GL960/X3100 - ThinkPad X61 Tablet */
|
case 0x2a02: /* GM965/GL960/X3100 - ThinkPad X61 Tablet */
|
||||||
case 0x2a42: /* 4 Series Mobile - ThinkPad X200 */
|
case 0x2a42: /* 4 Series Mobile - ThinkPad X200 */
|
||||||
return TypeG45;
|
return TypeG45;
|
||||||
|
@ -689,6 +698,18 @@ initdpll(Igfx *igfx, int x, int freq, int port)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
needlanes(int freq, int lsclk, int bpp)
|
||||||
|
{
|
||||||
|
vlong v;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
v = ((vlong)freq * bpp) / 8;
|
||||||
|
for(n=1; n<4 && v>lsclk; n<<=1, v>>=1)
|
||||||
|
;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
initdatalinkmn(Trans *t, int freq, int lsclk, int lanes, int tu, int bpp)
|
initdatalinkmn(Trans *t, int freq, int lsclk, int lanes, int tu, int bpp)
|
||||||
{
|
{
|
||||||
|
@ -734,10 +755,10 @@ inittrans(Trans *t, Mode *m)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
initpipe(Pipe *p, Mode *m)
|
initpipe(Pipe *p, Mode *m, int bpc)
|
||||||
{
|
{
|
||||||
static uchar bpctab[4] = { 8, 10, 6, 12 };
|
static uchar bpctab[4] = { 8, 10, 6, 12 };
|
||||||
int i, tu, bpc, lanes;
|
int i, tu, lanes;
|
||||||
Fdi *fdi;
|
Fdi *fdi;
|
||||||
|
|
||||||
/* source image size */
|
/* source image size */
|
||||||
|
@ -754,9 +775,8 @@ initpipe(Pipe *p, Mode *m)
|
||||||
inittrans(p, m);
|
inittrans(p, m);
|
||||||
|
|
||||||
/* default for displayport */
|
/* default for displayport */
|
||||||
|
lanes = needlanes(m->frequency, 270*MHz, 3*bpc);
|
||||||
tu = 64;
|
tu = 64;
|
||||||
bpc = 6; /* why */
|
|
||||||
lanes = 1;
|
|
||||||
|
|
||||||
fdi = p->fdi;
|
fdi = p->fdi;
|
||||||
if(fdi->rxctl.a != 0){
|
if(fdi->rxctl.a != 0){
|
||||||
|
@ -805,7 +825,7 @@ initpipe(Pipe *p, Mode *m)
|
||||||
static void
|
static void
|
||||||
init(Vga* vga, Ctlr* ctlr)
|
init(Vga* vga, Ctlr* ctlr)
|
||||||
{
|
{
|
||||||
int x, port;
|
int x, port, bpc;
|
||||||
char *val;
|
char *val;
|
||||||
Igfx *igfx;
|
Igfx *igfx;
|
||||||
Pipe *p;
|
Pipe *p;
|
||||||
|
@ -816,6 +836,8 @@ init(Vga* vga, Ctlr* ctlr)
|
||||||
if(m->z != 32)
|
if(m->z != 32)
|
||||||
error("%s: unsupported color depth %d\n", ctlr->name, m->z);
|
error("%s: unsupported color depth %d\n", ctlr->name, m->z);
|
||||||
|
|
||||||
|
bpc = 8; /* bits per color channel */
|
||||||
|
|
||||||
igfx = vga->private;
|
igfx = vga->private;
|
||||||
|
|
||||||
/* disable vga */
|
/* disable vga */
|
||||||
|
@ -858,10 +880,10 @@ init(Vga* vga, Ctlr* ctlr)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PortVGA:
|
case PortVGA:
|
||||||
if(igfx->npipe > 2)
|
if(igfx->type == TypeG45)
|
||||||
x = (igfx->adpa.v >> 29) & 3;
|
|
||||||
else
|
|
||||||
x = (igfx->adpa.v >> 30) & 1;
|
x = (igfx->adpa.v >> 30) & 1;
|
||||||
|
else
|
||||||
|
x = (igfx->adpa.v >> 29) & 3;
|
||||||
igfx->adpa.v |= (1<<31);
|
igfx->adpa.v |= (1<<31);
|
||||||
if(igfx->type == TypeG45){
|
if(igfx->type == TypeG45){
|
||||||
igfx->adpa.v &= ~(3<<10); /* Monitor DPMS: on */
|
igfx->adpa.v &= ~(3<<10); /* Monitor DPMS: on */
|
||||||
|
@ -876,10 +898,10 @@ init(Vga* vga, Ctlr* ctlr)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PortLCD:
|
case PortLCD:
|
||||||
if(igfx->npipe > 2)
|
if(igfx->type == TypeG45)
|
||||||
x = (igfx->lvds.v >> 29) & 3;
|
|
||||||
else
|
|
||||||
x = (igfx->lvds.v >> 30) & 1;
|
x = (igfx->lvds.v >> 30) & 1;
|
||||||
|
else
|
||||||
|
x = (igfx->lvds.v >> 29) & 3;
|
||||||
igfx->lvds.v |= (1<<31);
|
igfx->lvds.v |= (1<<31);
|
||||||
igfx->ppcontrol.v |= 5;
|
igfx->ppcontrol.v |= 5;
|
||||||
|
|
||||||
|
@ -905,8 +927,9 @@ init(Vga* vga, Ctlr* ctlr)
|
||||||
goto Badport;
|
goto Badport;
|
||||||
/* port enable */
|
/* port enable */
|
||||||
r->v |= 1<<31;
|
r->v |= 1<<31;
|
||||||
/* port width selection: x1 Mode */
|
/* port width selection */
|
||||||
r->v &= ~(7<<19);
|
r->v &= ~(7<<19);
|
||||||
|
r->v |= needlanes(m->frequency, 270*MHz, 3*bpc)-1 << 19;
|
||||||
|
|
||||||
/* port reversal: off */
|
/* port reversal: off */
|
||||||
r->v &= ~(1<<15);
|
r->v &= ~(1<<15);
|
||||||
|
@ -975,7 +998,7 @@ init(Vga* vga, Ctlr* ctlr)
|
||||||
if(initdpll(igfx, x, m->frequency, port) < 0)
|
if(initdpll(igfx, x, m->frequency, port) < 0)
|
||||||
error("%s: frequency %d out of range\n", ctlr->name, m->frequency);
|
error("%s: frequency %d out of range\n", ctlr->name, m->frequency);
|
||||||
|
|
||||||
initpipe(p, m);
|
initpipe(p, m, bpc);
|
||||||
|
|
||||||
ctlr->flag |= Finit;
|
ctlr->flag |= Finit;
|
||||||
}
|
}
|
||||||
|
@ -1053,8 +1076,8 @@ enablepipe(Igfx *igfx, int x)
|
||||||
loadreg(igfx, p->fdi->rxctl);
|
loadreg(igfx, p->fdi->rxctl);
|
||||||
sleep(5);
|
sleep(5);
|
||||||
p->fdi->txctl.v &= ~(7<<8 | 1); /* clear auto training bits */
|
p->fdi->txctl.v &= ~(7<<8 | 1); /* clear auto training bits */
|
||||||
p->fdi->txctl.v &= ~(1<<31);
|
p->fdi->txctl.v &= ~(1<<31); /* disable */
|
||||||
p->fdi->rxctl.v |= (1<<14); /* enable pll */
|
p->fdi->txctl.v |= (1<<14); /* enable pll */
|
||||||
loadreg(igfx, p->fdi->txctl);
|
loadreg(igfx, p->fdi->txctl);
|
||||||
sleep(5);
|
sleep(5);
|
||||||
}
|
}
|
||||||
|
@ -1102,21 +1125,61 @@ enablepipe(Igfx *igfx, int x)
|
||||||
loadreg(igfx, p->fdi->rxtu[0]);
|
loadreg(igfx, p->fdi->rxtu[0]);
|
||||||
loadreg(igfx, p->fdi->rxmisc);
|
loadreg(igfx, p->fdi->rxmisc);
|
||||||
|
|
||||||
p->fdi->rxctl.v &= ~(3<<8); /* link train pattern 00 */
|
if(igfx->type == TypeSNB){
|
||||||
p->fdi->rxctl.v |= 1<<10; /* auto train enable */
|
/* unmask bit lock and symbol lock bits */
|
||||||
p->fdi->rxctl.v |= 1<<31; /* enable */
|
csr(igfx, p->fdi->rximr.a, 3<<8, 0);
|
||||||
loadreg(igfx, p->fdi->rxctl);
|
|
||||||
|
|
||||||
p->fdi->txctl.v &= ~(3<<8); /* link train pattern 00 */
|
p->fdi->rxctl.v &= ~(3<<8); /* link train pattern1 */
|
||||||
p->fdi->txctl.v |= 1<<10; /* auto train enable */
|
p->fdi->rxctl.v |= 1<<31; /* enable */
|
||||||
p->fdi->txctl.v |= 1<<31; /* enable */
|
loadreg(igfx, p->fdi->rxctl);
|
||||||
loadreg(igfx, p->fdi->txctl);
|
|
||||||
|
|
||||||
/* wait for link training done */
|
p->fdi->txctl.v &= ~(3<<8); /* link train pattern1 */
|
||||||
for(i=0; i<200; i++){
|
p->fdi->txctl.v |= 1<<31; /* enable */
|
||||||
|
loadreg(igfx, p->fdi->txctl);
|
||||||
|
|
||||||
|
/* wait for bit lock */
|
||||||
|
for(i=0; i<10; i++){
|
||||||
|
sleep(1);
|
||||||
|
if(rr(igfx, p->fdi->rxiir.a) & (1<<8))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
csr(igfx, p->fdi->rxiir.a, 0, 1<<8);
|
||||||
|
|
||||||
|
/* switch to link train pattern2 */
|
||||||
|
csr(igfx, p->fdi->rxctl.a, 3<<8, 1<<8);
|
||||||
|
csr(igfx, p->fdi->txctl.a, 3<<8, 1<<8);
|
||||||
|
|
||||||
|
/* wait for symbol lock */
|
||||||
|
for(i=0; i<10; i++){
|
||||||
|
sleep(1);
|
||||||
|
if(rr(igfx, p->fdi->rxiir.a) & (1<<9))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
csr(igfx, p->fdi->rxiir.a, 0, 1<<9);
|
||||||
|
|
||||||
|
/* switch to link train normal */
|
||||||
|
csr(igfx, p->fdi->rxctl.a, 0, 3<<8);
|
||||||
|
csr(igfx, p->fdi->txctl.a, 0, 3<<8);
|
||||||
|
|
||||||
|
/* wait idle pattern time */
|
||||||
sleep(5);
|
sleep(5);
|
||||||
if(rr(igfx, p->fdi->txctl.a) & 2)
|
} else {
|
||||||
break;
|
p->fdi->rxctl.v &= ~(3<<8); /* link train pattern 00 */
|
||||||
|
p->fdi->rxctl.v |= 1<<10; /* auto train enable */
|
||||||
|
p->fdi->rxctl.v |= 1<<31; /* enable */
|
||||||
|
loadreg(igfx, p->fdi->rxctl);
|
||||||
|
|
||||||
|
p->fdi->txctl.v &= ~(3<<8); /* link train pattern 00 */
|
||||||
|
p->fdi->txctl.v |= 1<<10; /* auto train enable */
|
||||||
|
p->fdi->txctl.v |= 1<<31; /* enable */
|
||||||
|
loadreg(igfx, p->fdi->txctl);
|
||||||
|
|
||||||
|
/* wait for link training done */
|
||||||
|
for(i=0; i<200; i++){
|
||||||
|
sleep(5);
|
||||||
|
if(rr(igfx, p->fdi->txctl.a) & 2)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1626,8 +1689,8 @@ enabledp(Igfx *igfx, Dp *dp)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* Link configuration */
|
/* Link configuration */
|
||||||
wdpaux(igfx, dp, 0x100, 0x0A); /* 270Mhz */
|
wdpaux(igfx, dp, 0x100, (270*MHz) / 27000000);
|
||||||
wdpaux(igfx, dp, 0x101, 0x01); /* one lane */
|
wdpaux(igfx, dp, 0x101, ((dp->ctl.v>>19)&7)+1);
|
||||||
|
|
||||||
r = 0;
|
r = 0;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue