User:Greasemonkey/Intel GenX: Difference between revisions

→‎Getting a display: Gen6-compatible code, and a few fixes
(references are safer than replicating the manuals. also, updated VGA disabling method.)
(→‎Getting a display: Gen6-compatible code, and a few fixes)
Line 35:
Tested on:
* GM45 1366x768 CQ60-210TU
* HD3000 1366x768 dv6-6c35tx
 
===Proper mode switch methodology===
Line 43 ⟶ 44:
 
===Simplified version===
This assumes that the BIOS configured the LVDS panel properly and/or in a way that we can just take its values and run with them. If it does, you can avoid an awful lot of pain. It also assumes that it's on the default setup of Pipe B, Display B.
 
This code works on a GM45. It does not quite work on an HD3000, although the VGA compatibility mode is successfully disabled.
 
This also assumes that your panel is less than 2048 pixels wide, but that can be fixed by adding a few "if" statements. However, the 1366x768 assumption is dropped from this version.
 
There is a chance that this will work on systems that don't have an LVDS panel, but you will be limited to whatever resolution the BIOS spews out.
If you want a non-native resolution, enable the panelfitter and adjust PIPEBSRC to suit. Note, the panelfitter does love to blur everything.
 
If you want a non-native resolution, enable the panelfitter and adjust PIPEBSRCPIPEnSRC to suit. Note, the GMA panelfitter does love to blur everything. (HD 3000 seems fine.)
Here's how you get from VGA text mode to native 32bpp full-res BGRX mode the easy way, and by easy we mean this is very much empirical, about as risky, and assumes the BIOS doesn't have stupid bugs in it - but may be more reliable than the version above:
 
Here's how you get from VGA text mode to native 32bpp full-res BGRX mode the easy way, and by easy we mean this is very much empirical, about as risky, and assumes the BIOS doesn't have stupid bugs in it - but may be more reliable than the version above:
 
<pre>
Line 61 ⟶ 62:
wait_us(100);
 
// DisableGet correct VGA pipe
// WARNING: Gen5 changes the location of this register!
// IfPre-Gen5 youuses intend0x71400, to support pre-Gen5+ anduses Gen5+,0x41000.
int real_VGACNTRL = (genx_typ < 0x5000 ? VGACNTRL : VGACNTRL_ILK);
// select the right location for the architecture version.
genx_pipe = (genx_reg32[real_VGACNTRL]>>29)&1;
genx_reg32[VGACNTRL] |= (1<<31);
 
// Disable VGA
genx_reg32[VGACNTRLreal_VGACNTRL] |= (1<<31);
 
// Disable Display n
genx_reg32[PIPEBCONFDSPnCNTR(genx_pipe)] &= ~(1<<31); // Disable Pipe B
 
// Set PIPEBSRCPIPEnSRC to screen resolution
uint32_t vis_w = (genx_reg32[HTOTAL_BHTOTAL_n(genx_pipe)] & 0xFFFF)+1;
uint32_t vis_h = (genx_reg32[VTOTAL_BVTOTAL_n(genx_pipe)] & 0xFFFF)+1;
genx_reg32[PIPEBSRCPIPEnSRC(genx_pipe)] = ((vis_w-1)<<16)|(vis_h-1);
 
// XXX: Lacking information on DevSNB's panelfitter.
genx_reg32[DSPBCNTR] &= ~(1<<31); // Disable Display B
// Seems to work fine without disabling it.
genx_reg32[PIPEBCONF] &= ~(1<<31); // Disable Pipe B
// For Gen4.5, however, disabling it is pretty much mandatory,
while((genx_reg32[PIPEBCONF] & (1<<30))) {} // Wait for Pipe B to stop
// unless you can't stand GPUs that lack antialiasing.
if(genx_typ >= 0x5000)
{
genx_reg32[PIPEnCONF(genx_pipe)] &= ~(1<<31); // Disable Pipe n
while((genx_reg32[PIPEBCONFPIPEnCONF(genx_pipe)] & (1<<30))) {} // Wait for Pipe Bn to stop
 
genx_reg32[DSPBCNTRPFIT_CONTROL] &= ~(1<<31); // Disable Display Bpanelfitter
// Set PIPEBSRC to screen resolution
uint32_t vis_w = (genx_reg32[HTOTAL_B] & 0xFFFF)+1;
uint32_t vis_h = (genx_reg32[VTOTAL_B] & 0xFFFF)+1;
genx_reg32[PIPEBSRC] = ((vis_w-1)<<16)|(vis_h-1);
 
genx_reg32[PIPEBCONFPIPEnCONF(genx_pipe)] |= (1<<31); // Enable Pipe Bn
// XXX: Panelfitter location unknown for DevSNB.
}
// It mentions a spreadsheet which appears to be publically unavailable.
genx_reg32[PFIT_CONTROL] &= ~(1<<31); // Disable panelfitter
genx_reg32[PIPEBCONF] |= (1<<31); // Enable Pipe B
 
// Set up Display Bn and enable
genx_reg32[DSPBLINOFFDSPnLINOFF(genx_pipe)] = 0x00000000; // linear offset
genx_reg32[DSPBSTRIDEDSPnSTRIDE(genx_pipe)] = 2048*4; // scanline pitch
genx_reg32[DSPBSURFDSPnSURF(genx_pipe)] = 0x00000000; // surface base
genx_reg32[DSPBCNTRDSPnCNTR(genx_pipe)] = (genx_reg32[DSPBCNTRDSPnCNTR(genx_pipe)] & ~(15<<26)) | (6<<26); // bit depth select, 6 = 32bpp BGRX
genx_reg32[DSPBCNTRDSPnCNTR(genx_pipe)] = (genx_reg32[DSPBCNTRDSPnCNTR(genx_pipe)] & ~(3<<20)) | (0<<20); // pixel multiply
genx_reg32[DSPBCNTRDSPnCNTR(genx_pipe)] = (genx_reg32[DSPBCNTRDSPnCNTR(genx_pipe)] & ~(1<<10)) | (0<<10); // tiling flag
genx_reg32[DSPBCNTRDSPnCNTR(genx_pipe)] |= (1<<31); // enable
</pre>
 
Line 94 ⟶ 106:
 
===Setting monitor timings===
Not tested on the dv6-6c35tx.
 
If you need to set the monitor timings, this code should be useful for a start. These timings work on the CQ60-210TU's surprisingly tolerant LVDS panel:
Line 112 ⟶ 125:
uint32_t vis_blank_w = vis_sblank_w + vis_sync_w + vis_eblank_w;
uint32_t vis_blank_h = vis_sblank_h + vis_sync_h + vis_eblank_h;
genx_reg32[HTOTAL_BHTOTAL_n(genx_pipe)] = ((vis_w+vis_blank_w-1)<<16) | (vis_w-1);
genx_reg32[HBLANK_BHBLANK_n(genx_pipe)] = ((vis_w+vis_blank_w-1)<<16) | (vis_w-1);
genx_reg32[HSYNC_BHSYNC_n(genx_pipe)] = ((vis_w+vis_sblank_w+vis_sync_w-1)<<16) | (vis_w+vis_sblank_w-1);
genx_reg32[VTOTAL_BVTOTAL_n(genx_pipe)] = ((vis_h+vis_blank_h-1)<<16) | (vis_h-1);
genx_reg32[VBLANK_BVBLANK_n(genx_pipe)] = ((vis_h+vis_blank_h-1)<<16) | (vis_h-1);
genx_reg32[VSYNC_BVSYNC_n(genx_pipe)] = ((vis_h+vis_sblank_h+vis_sync_h-1)<<16) | (vis_h+vis_sblank_h-1);
genx_reg32[PIPEBSRCPIPEnSRC(genx_pipe)] = ((vis_stretch_w-1)<<16)|(vis_stretch_h-1);
</pre>
 
Anonymous user