void runio(u32 aux_ctl, u32 aux_data, int verbose) { int i; WRITE32(0x80000000,0x45400); WRITE32(0x00000000,_CURACNTR); WRITE32( DISPPLANE_GAMMA_ENABLE |( DISPPLANE_32BPP_NO_ALPHA &0x18000000)|(/* DISPPLANE_SEL_PIPE(0=A,1=B) */0x0<<24)| DISPPLANE_TRICKLE_FEED_DISABLE /* Ironlake */ |0xd8004000,_DSPACNTR); WRITE32(0x00000000,_DSPBCNTR); WRITE32(0x80000000,CPU_VGACNTRL); WRITE32(0x74000/*0x00000000*/,_DSPASIZE+0xc); WRITE32(0x00000000,_DSPBSURF); WRITE32(0x00000000,0x4f050); WRITE32( DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_PLL_FREQ_270MHZ | DP_SCRAMBLING_DISABLE_IRONLAKE | DP_SYNC_VS_HIGH |0x00000091,DP_A); WRITE32(0x00200090,_FDI_RXA_MISC); WRITE32(0x0a000000,_FDI_RXA_MISC); WRITE32(0x00000070,0x46408); WRITE32(0x04000000,0x42090); WRITE32(0x40000000,0x4f050); WRITE32(0x00000000,0x9840); WRITE32(0xa4000000,0x42090); WRITE32(0x00004000,0x42080); WRITE32(0x00ffffff,0x64f80); WRITE32(0x0007000e,0x64f84); WRITE32(0x00d75fff,0x64f88); WRITE32(0x000f000a,0x64f8c); WRITE32(0x00c30fff,0x64f90); WRITE32(0x00060006,0x64f94); WRITE32(0x00aaafff,0x64f98); WRITE32(0x001e0000,0x64f9c); WRITE32(0x00ffffff,0x64fa0); WRITE32(0x000f000a,0x64fa4); WRITE32(0x00d75fff,0x64fa8); WRITE32(0x00160004,0x64fac); WRITE32(0x00c30fff,0x64fb0); WRITE32(0x001e0000,0x64fb4); WRITE32(0x00ffffff,0x64fb8); WRITE32(0x00060006,0x64fbc); WRITE32(0x00d75fff,0x64fc0); WRITE32(0x001e0000,0x64fc4); WRITE32(0x00ffffff,0x64e00); WRITE32(0x0006000e,0x64e04); WRITE32(0x00d75fff,0x64e08); WRITE32(0x0005000a,0x64e0c); WRITE32(0x00c30fff,0x64e10); WRITE32(0x00040006,0x64e14); WRITE32(0x80aaafff,0x64e18); WRITE32(0x000b0000,0x64e1c); WRITE32(0x00ffffff,0x64e20); WRITE32(0x0005000a,0x64e24); WRITE32(0x00d75fff,0x64e28); WRITE32(0x000c0004,0x64e2c); WRITE32(0x80c30fff,0x64e30); WRITE32(0x000b0000,0x64e34); WRITE32(0x00ffffff,0x64e38); WRITE32(0x00040006,0x64e3c); WRITE32(0x80d75fff,0x64e40); WRITE32(0x000b0000,0x64e44); WRITE32( DIGITAL_PORTA_HOTPLUG_ENABLE |0x00000010,DIGITAL_PORT_HOTPLUG_CNTRL); WRITE32(0x10000000,SDEISR+0x30); /* END RESET. START AUX CHANNEL IO */ /* this seems to be the one mandatory empty IO you do to * block until the aux channel is up and running. */ intel_dp_aux_ch(aux_ctl, aux_data, auxout, 0, auxin, 0); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_DPCD_REV<<8|0x0|0x90000000; printk(BIOS_SPEW, "DP_DPCD_REV"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); /* this is EDID. For this simple code, the panel * is hard coded. We do it anyway but don't use it yet * on this hardware. */ auxout[0] = 0<<31 /* i2c */|1<<30|0x0<<28/*W*/|0x50<<8|0x0|0x40005000; auxout[1] = 0x00000000; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 5, auxin, 0); auxout[0] = 0<<31 /* i2c */|0<<30|0x1<<28/*R*/|0x50<<8|0x3|0x10005003; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 3); auxout[0] = 0<<31 /* i2c */|1<<30|0x0<<28/*W*/|0x50<<8|0x0|0x40005000; auxout[1] = 0x04000000; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 5, auxin, 0); auxout[0] = 0<<31 /* i2c */|0<<30|0x1<<28/*R*/|0x50<<8|0x3|0x10005003; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 3); auxout[0] = 0<<31 /* i2c */|1<<30|0x0<<28/*W*/|0x50<<8|0x0|0x40005000; auxout[1] = 0x00000000; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 5, auxin, 0); auxout[0] = 0<<31 /* i2c */|1<<30|0x1<<28/*R*/|0x50<<8|0xf|0x5000500f; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 15); auxout[0] = 0<<31 /* i2c */|1<<30|0x1<<28/*R*/|0x50<<8|0xf|0x5000500f; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 15); auxout[0] = 0<<31 /* i2c */|1<<30|0x1<<28/*R*/|0x50<<8|0xf|0x5000500f; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 15); auxout[0] = 0<<31 /* i2c */|1<<30|0x1<<28/*R*/|0x50<<8|0xf|0x5000500f; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 15); auxout[0] = 0<<31 /* i2c */|1<<30|0x1<<28/*R*/|0x50<<8|0xf|0x5000500f; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 15); auxout[0] = 0<<31 /* i2c */|1<<30|0x1<<28/*R*/|0x50<<8|0xf|0x5000500f; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 15); auxout[0] = 0<<31 /* i2c */|1<<30|0x1<<28/*R*/|0x50<<8|0xf|0x5000500f; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 15); auxout[0] = 0<<31 /* i2c */|1<<30|0x1<<28/*R*/|0x50<<8|0xf|0x5000500f; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 15); auxout[0] = 0<<31 /* i2c */|0<<30|0x1<<28/*R*/|0x50<<8|0x0|0x10005000; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); /* end EDID */ /* get lank rate and lane count. */ auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_MAX_LINK_RATE<<8|0x0|0x90000100; printk(BIOS_SPEW, "DP_MAX_LINK_RATE"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_MAX_LANE_COUNT<<8|0x0|0x90000200; printk(BIOS_SPEW, "DP_MAX_LANE_COUNT"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); /* back light. */ WRITE32(0x03a903a9,BLC_PWM_CPU_CTL); WRITE32(0x03a903a9,BLC_PWM_PCH_CTL2); WRITE32(0x00000000,BLC_PWM_PCH_CTL1); /* mystery registers. */ /* more reset, prior to training? not really sure. */ WRITE32(0x00ffffff,0x64f68); WRITE32(0x00040006,0x64f6c); WRITE32( PORTB_HOTPLUG_ENABLE |0x10000010,SDEISR+0x30); WRITE32(0x00ffffff,0x64f08); WRITE32(0x00040006,0x64f0c); WRITE32( PORTC_HOTPLUG_ENABLE | PORTB_HOTPLUG_ENABLE |0x10001010,SDEISR+0x30); WRITE32(0x00000008,0x4f05c); WRITE32(0x00000008,0x4f060); WRITE32(0x80000000,0x45400); WRITE32(0x80000000,CPU_VGACNTRL); WRITE32(0x00000000,_CURACNTR); WRITE32(0x00000000,_CURABASE); WRITE32( DISPPLANE_GAMMA_ENABLE |( DISPPLANE_32BPP_NO_ALPHA &0x18000000)|(/* DISPPLANE_SEL_PIPE(0=A,1=B) */0x0<<24)| DISPPLANE_TRICKLE_FEED_DISABLE /* Ironlake */ |0xd8004000,_DSPACNTR); WRITE32(0x74000/*0x00000000*/,_DSPASIZE+0xc); WRITE32(0x00000000,_CURBCNTR_IVB); WRITE32(0x00000000,_CURBBASE_IVB); WRITE32(0x00000000,_DSPBCNTR); WRITE32(0x00000000,_DSPBSURF); WRITE32(0x00000000,0x72080); WRITE32(0x00000000,0x72084); WRITE32(0x00000000,_DVSACNTR); WRITE32(0x00000000,_DVSASURF); WRITE32(0x00000008,0x4f05c); WRITE32(0x00000008,0x4f060); WRITE32(0x80000000,CPU_VGACNTRL); /* this value is suspicious. The VBIOS was in 16 bit mode. * that said, this is a 4:4:4 panel. I wonder if I screwed that * up below. */ WRITE32(0x00000640,_DSPASTRIDE); WRITE32(0x00000000,_DSPAADDR); /* bios set it to 0, kernel to 74000, hmm. */ WRITE32(0x74000/*0x00000000*/,_DSPASIZE+0xc); auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_SET_POWER<<8|0x0|0x80060000; printk(BIOS_SPEW, "DP_SET_POWER"); auxout[1] = 0x01000000; /* DP_SET_POWER_D0 | DP_PSR_SINK_INACTIVE |0x00000001*/ intel_dp_aux_ch(aux_ctl, aux_data, auxout, 0, auxin, 0); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 5, auxin, 0); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_DPCD_REV<<8|0x0|0x90000000; printk(BIOS_SPEW, "DP_DPCD_REV"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); WRITE32(0x00000018,0x4f014); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_MAX_DOWNSPREAD<<8|0x0|0x90000300; printk(BIOS_SPEW, "DP_MAX_DOWNSPREAD"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); /* more mystery registers ... */ /* so we're doing some stuff here with downspread. * not sure what yet. */ WRITE32(0x7e62b020,0x6f030); WRITE32(0x00800000,0x6f034); WRITE32(0x00041cac,0x6f040); WRITE32(0x00080000,0x6f044); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_MAX_DOWNSPREAD<<8|0x0|0x90000300; printk(BIOS_SPEW, "DP_MAX_DOWNSPREAD"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_MAX_DOWNSPREAD<<8|0x0|0x90000300; printk(BIOS_SPEW, "DP_MAX_DOWNSPREAD"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); WRITE32(0x40000006,FORCEWAKE_MT_ACK); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_MAX_DOWNSPREAD<<8|0x0|0x90000300; printk(BIOS_SPEW, "DP_MAX_DOWNSPREAD"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); /* more mystery. */ /* these numbers just are not documented in the kernel code yet? */ WRITE32(0x081f077f,0x6f000); WRITE32(0x081f077f,0x6f004); WRITE32(0x07cb07ad,0x6f008); WRITE32(0x04570437,0x6f00c); WRITE32(0x04570437,0x6f010); WRITE32(0x043d0439,0x6f014); WRITE32(0x077f0437,_PIPEASRC); WRITE32(0x00000000,0x7f008); WRITE32(0x00000000,_TRANSACONF); WRITE32(0x081f077f,_HTOTAL_A); WRITE32(0x081f077f,_HBLANK_A); WRITE32(0x07cb07ad,_HSYNC_A); WRITE32(0x04570437,_VTOTAL_A); WRITE32(0x04570437,_VBLANK_A); WRITE32(0x043d0439,_VSYNC_A); /* and again? */ auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_MAX_DOWNSPREAD<<8|0x0|0x90000300; printk(BIOS_SPEW, "DP_MAX_DOWNSPREAD"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); WRITE32(0x20000000,0x46100); WRITE32( DISPPLANE_GAMMA_ENABLE |( DISPPLANE_32BPP_NO_ALPHA &0x18000000)|(/* DISPPLANE_SEL_PIPE(0=A,1=B) */0x0<<24)| DISPPLANE_TRICKLE_FEED_DISABLE /* Ironlake */ |0xd8004000,_DSPACNTR); WRITE32(0x00000640,_DSPASTRIDE); WRITE32(0x00000000,_DSPAADDR); WRITE32(0x74000/*0x00000000*/,_DSPASIZE+0xc); WRITE32( DISPPLANE_GAMMA_ENABLE |( DISPPLANE_32BPP_NO_ALPHA &0x18000000)|(/* DISPPLANE_SEL_PIPE(0=A,1=B) */0x0<<24)| DISPPLANE_TRICKLE_FEED_DISABLE /* Ironlake */ |0xd8004000,_DSPACNTR); WRITE32( DISPPLANE_GAMMA_ENABLE |( DISPPLANE_32BPP_NO_ALPHA &0x18000000)|(/* DISPPLANE_SEL_PIPE(0=A,1=B) */0x0<<24)| DISPPLANE_TRICKLE_FEED_DISABLE /* Ironlake */ |0xd8004000,_DSPACNTR); WRITE32(0x74000/*0x00000000*/,_DSPASIZE+0xc); WRITE32(0x00000000,_PFA_WIN_POS); WRITE32(0x077f0437,_PIPEASRC); WRITE32(0x00000000,_PFA_WIN_POS); WRITE32(0x80800000,_PFA_CTL_1); WRITE32(0x00000000,_PFA_WIN_SZ); WRITE32(0x00030000,0x6f400); WRITE32(0x00000000,0x7f008); WRITE32(0x82034002,0x6f400); WRITE32(0x80000000,0x7f008); /* read the EDID again? Hmm. * it seems to me that this may be just the way vbios * is structured ... */ auxout[0] = 0<<31 /* i2c */|1<<30|0x0<<28/*W*/|0x50<<8|0x0|0x40005000; auxout[1] = 0x00000000; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 5, auxin, 0); auxout[0] = 0<<31 /* i2c */|0<<30|0x1<<28/*R*/|0x50<<8|0x3|0x10005003; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 3); auxout[0] = 0<<31 /* i2c */|1<<30|0x0<<28/*W*/|0x50<<8|0x0|0x40005000; auxout[1] = 0x04000000; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 5, auxin, 0); auxout[0] = 0<<31 /* i2c */|0<<30|0x1<<28/*R*/|0x50<<8|0x3|0x10005003; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 3); auxout[0] = 0<<31 /* i2c */|1<<30|0x0<<28/*W*/|0x50<<8|0x0|0x40005000; auxout[1] = 0x7e000000; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 5, auxin, 0); auxout[0] = 0<<31 /* i2c */|0<<30|0x1<<28/*R*/|0x50<<8|0x0|0x10005000; intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); /* this seems to be the training part for real. */ WRITE32( DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_PLL_FREQ_270MHZ | DP_SCRAMBLING_DISABLE_IRONLAKE | DP_SYNC_VS_HIGH |0x00000091,DP_A); WRITE32(0x00000021,0x6f410); WRITE32(0x80000011,DP_A+0x40); WRITE32( DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_PLL_FREQ_270MHZ | DP_SCRAMBLING_DISABLE_IRONLAKE | DP_SYNC_VS_HIGH |0x80000093,DP_A); WRITE32( PANEL_PORT_SELECT_LVDS |(/* PANEL_POWER_UP_DELAY_MASK */0x1<<16)|(/* PANEL_LIGHT_ON_DELAY_MASK */0xa<<0)|0x0001000a,PCH_PP_ON_DELAYS); WRITE32( PANEL_PORT_SELECT_LVDS |(/* PANEL_POWER_UP_DELAY_MASK */0x7d0<<16)|(/* PANEL_LIGHT_ON_DELAY_MASK */0xa<<0)|0x07d0000a,PCH_PP_ON_DELAYS); auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_LINK_BW_SET<<8|0x0|0x80010000; printk(BIOS_SPEW, "DP_LINK_BW_SET"); auxout[1] = 0x0a000080; /*( DP_LINK_BW_2_7 &0xa)|0xffffffff8000000a*/ intel_dp_aux_ch(aux_ctl, aux_data, auxout, 5, auxin, 0); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_MAX_LANE_COUNT<<8|0x0|0x90000200; printk(BIOS_SPEW, "DP_MAX_LANE_COUNT"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_LANE_COUNT_SET<<8|0x0|0x80010100; printk(BIOS_SPEW, "DP_LANE_COUNT_SET"); auxout[1] = 0x02000000; /*0x00000002*/ intel_dp_aux_ch(aux_ctl, aux_data, auxout, 5, auxin, 0); WRITE32(0x80000000,DP_A+0x40); WRITE32( DP_PORT_EN | DP_LINK_TRAIN_PAT_1 | DP_LINK_TRAIN_PAT_1_CPT | DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0 | DP_PORT_WIDTH_1 | DP_PLL_FREQ_270MHZ | DP_SYNC_VS_HIGH |0x80000013,DP_A); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_TRAINING_PATTERN_SET<<8|0x0|0x90010200; printk(BIOS_SPEW, "DP_TRAINING_PATTERN_SET"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_PATTERN_SET<<8|0x0|0x80010200; printk(BIOS_SPEW, "DP_TRAINING_PATTERN_SET"); auxout[1] = 0x01000000; /* DP_TRAINING_PATTERN_1 | DP_LINK_QUAL_PATTERN_DISABLE | DP_SYMBOL_ERROR_COUNT_BOTH |0x00000001*/ intel_dp_aux_ch(aux_ctl, aux_data, auxout, 5, auxin, 0); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_LANE_COUNT_SET<<8|0x0|0x90010100; #if 1 printk(BIOS_SPEW, "DP_LANE_COUNT_SET"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_LANE0_SET<<8|0x1|0x80010301; printk(BIOS_SPEW, "DP_TRAINING_LANE0_SET"); auxout[1] = 0x00000000; /* DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0 |0x00000000*/ intel_dp_aux_ch(aux_ctl, aux_data, auxout, 6, auxin, 0); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_LANE0_1_STATUS<<8|0x1|0x90020201; printk(BIOS_SPEW, "DP_LANE0_1_STATUS"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 1); WRITE32(0x80000100,DP_A+0x40); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_TRAINING_PATTERN_SET<<8|0x0|0x90010200; printk(BIOS_SPEW, "DP_TRAINING_PATTERN_SET"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_PATTERN_SET<<8|0x0|0x80010200; printk(BIOS_SPEW, "DP_TRAINING_PATTERN_SET"); auxout[1] = 0x02000000; /* DP_TRAINING_PATTERN_2 | DP_LINK_QUAL_PATTERN_DISABLE | DP_SYMBOL_ERROR_COUNT_BOTH |0x00000002*/ intel_dp_aux_ch(aux_ctl, aux_data, auxout, 5, auxin, 0); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_LANE0_1_STATUS<<8|0x1|0x90020201; printk(BIOS_SPEW, "DP_LANE0_1_STATUS"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 1); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_LANE_ALIGN_STATUS_UPDATED<<8|0x0|0x90020400; printk(BIOS_SPEW, "DP_LANE_ALIGN_STATUS_UPDATED"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_TRAINING_PATTERN_SET<<8|0x0|0x90010200; printk(BIOS_SPEW, "DP_TRAINING_PATTERN_SET"); intel_dp_aux_ch(aux_ctl, aux_data, auxout, 4, auxin, 0); auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_PATTERN_SET<<8|0x0|0x80010200; printk(BIOS_SPEW, "DP_TRAINING_PATTERN_SET"); auxout[1] = 0x00000000; /* DP_TRAINING_PATTERN_DISABLE | DP_LINK_QUAL_PATTERN_DISABLE | DP_SYMBOL_ERROR_COUNT_BOTH |0x00000000*/ intel_dp_aux_ch(aux_ctl, aux_data, auxout, 5, auxin, 0); /* from kernel */ //WRITE32(0x000f3806, WM0_PIPEA_ILK); // did not go well when we turned this on! /* end from kernel */ /* training is done, final sets? */ WRITE32(0x80000200,DP_A+0x40); WRITE32(0x80000300,DP_A+0x40); WRITE32( PWM_ENABLE |0x80000000,BLC_PWM_CPU_CTL2); WRITE32( PWM_PCH_ENABLE |0x80000000,BLC_PWM_PCH_CTL1); WRITE32(0x03a903a9,BLC_PWM_CPU_CTL); WRITE32(0x03a903a9,BLC_PWM_CPU_CTL); WRITE32(0x03a903a9,BLC_PWM_PCH_CTL2); WRITE32( PWM_PCH_ENABLE |0x80000000,BLC_PWM_PCH_CTL1); WRITE32( PORTC_HOTPLUG_ENABLE | PORTB_HOTPLUG_ENABLE |0x10001010,SDEISR+0x30); WRITE32( DIGITAL_PORTA_HOTPLUG_ENABLE |0x00000010,DIGITAL_PORT_HOTPLUG_CNTRL); printk(BIOS_SPEW, "Sleep long and well\n"); udelay(5000000); /* this runs (I kid you not) 210 times in the VBIOS. The values * never change. So what's it do? Timing? */ for(i = 0; i < 210; i++){ if (verbose & vio) READ32(0x45400); WRITE32(0x80000000,0x45400); if (verbose & vio) READ32(0x45400); if (verbose & vio) READ32(_DSPASTRIDE); if (verbose & vio) READ32(_DSPASTRIDE); } printk(BIOS_SPEW, "Wait a bit\n"); #endif WRITE32(0x80000000,CPU_VGACNTRL); WRITE32(0x00000000,_CURACNTR); WRITE32(0x00000000,_CURABASE); WRITE32( DISPPLANE_GAMMA_ENABLE |( DISPPLANE_32BPP_NO_ALPHA &0x18000000)|(/* DISPPLANE_SEL_PIPE(0=A,1=B) */0x0<<24)| DISPPLANE_TRICKLE_FEED_DISABLE /* Ironlake */ |0xd8004000,_DSPACNTR); WRITE32(0x74000/*0x00000000*/,_DSPASIZE+0xc); WRITE32(0x00000000,_CURBCNTR_IVB); WRITE32(0x00000000,_CURBBASE_IVB); WRITE32(0x00000000,_DSPBCNTR); WRITE32(0x00000000,_DSPBSURF); WRITE32(0x00000000,0x72080); WRITE32(0x00000000,0x72084); WRITE32(0x00000000,_DVSACNTR); WRITE32(0x00000000,_DVSASURF); WRITE32(0x00000008,0x4f05c); WRITE32(0x00000008,0x4f060); WRITE32(0x80000000,CPU_VGACNTRL); WRITE32(0x00000640,_DSPASTRIDE); WRITE32(0x00000000,_DSPAADDR); WRITE32(0x74000/*0x00000000*/,_DSPASIZE+0xc); WRITE32( DISPPLANE_GAMMA_ENABLE |( DISPPLANE_32BPP_NO_ALPHA &0x18000000)|(/* DISPPLANE_SEL_PIPE(0=A,1=B) */0x0<<24)| DISPPLANE_TRICKLE_FEED_DISABLE /* Ironlake */ |0xd8004000,_DSPACNTR); WRITE32(0x74000/*0x00000000*/,_DSPASIZE+0xc); WRITE32(0x00000000,_PFA_WIN_POS); WRITE32(0x00000000,_PFA_WIN_SZ); WRITE32(0x077f0437,_PIPEASRC); WRITE32(0x00000000,_PFA_WIN_POS); WRITE32(0x077f0437,_PIPEASRC); WRITE32(0x00000000,_PFA_WIN_POS); WRITE32(0x80800000,_PFA_CTL_1); WRITE32(0x00000000,_PFA_WIN_SZ); WRITE32( DISPPLANE_GAMMA_ENABLE |( DISPPLANE_32BPP_NO_ALPHA &0x18000000)|(/* DISPPLANE_SEL_PIPE(0=A,1=B) */0x0<<24)| DISPPLANE_TRICKLE_FEED_DISABLE /* Ironlake */ |0xd8004000,_DSPACNTR); WRITE32(0x00000640,_DSPASTRIDE); WRITE32(0x00000000,_DSPAADDR); WRITE32(0x74000/*0x00000000*/,_DSPASIZE+0xc); WRITE32( DISPPLANE_GAMMA_ENABLE |( DISPPLANE_32BPP_NO_ALPHA &0x18000000)|(/* DISPPLANE_SEL_PIPE(0=A,1=B) */0x0<<24)| DISPPLANE_TRICKLE_FEED_DISABLE /* Ironlake */ |0xd8004000,_DSPACNTR); WRITE32( DISPPLANE_GAMMA_ENABLE |( DISPPLANE_32BPP_NO_ALPHA &0x18000000)|(/* DISPPLANE_SEL_PIPE(0=A,1=B) */0x0<<24)| DISPPLANE_TRICKLE_FEED_DISABLE /* Ironlake */ |0xd8004000,_DSPACNTR); WRITE32(0x74000/*0x00000000*/,_DSPASIZE+0xc); /* from kernel. */ WRITE32(0x00074000,_DSPASIZE+0xc); WRITE32( PORTC_HOTPLUG_ENABLE | PORTB_HOTPLUG_ENABLE |0x10001010,SDEISR+0x30); WRITE32( DIGITAL_PORTA_HOTPLUG_ENABLE |0x00000010,DIGITAL_PORT_HOTPLUG_CNTRL); }
int i915lightup(unsigned int pphysbase, unsigned int piobase, unsigned int pmmio, unsigned int pgfx) { static struct edid edid; int index; u32 auxin[16], auxout[16]; mmio = (void *)pmmio; addrport = piobase; dataport = addrport + 4; physbase = pphysbase; graphics = pgfx; printk(BIOS_SPEW, "i915lightup: graphics %p mmio %p" "addrport %04x physbase %08x\n", (void *)graphics, mmio, addrport, physbase); globalstart = rdtscll(); decode_edid((unsigned char *)&link_edid_data, sizeof(link_edid_data), &edid); htotal = (edid.ha - 1) | ((edid.ha + edid.hbl- 1) << 16); printk(BIOS_SPEW, "I915_WRITE(HTOTAL(pipe), %08x)\n", htotal); hblank = (edid.ha - 1) | ((edid.ha + edid.hbl- 1) << 16); printk(BIOS_SPEW, "I915_WRITE(HBLANK(pipe),0x%08x)\n", hblank); hsync = (edid.ha + edid.hso - 1) | ((edid.ha + edid.hso + edid.hspw- 1) << 16); printk(BIOS_SPEW, "I915_WRITE(HSYNC(pipe),0x%08x)\n", hsync); vtotal = (edid.va - 1) | ((edid.va + edid.vbl- 1) << 16); printk(BIOS_SPEW, "I915_WRITE(VTOTAL(pipe), %08x)\n", vtotal); vblank = (edid.va - 1) | ((edid.va + edid.vbl- 1) << 16); printk(BIOS_SPEW, "I915_WRITE(VBLANK(pipe),0x%08x)\n", vblank); vsync = (edid.va + edid.vso - 1) |((edid.va + edid.vso + edid.vspw- 1) << 16); printk(BIOS_SPEW, "I915_WRITE(VSYNC(pipe),0x%08x)\n", vsync); printk(BIOS_SPEW, "Table has %d elements\n", niodefs); index = run(0); printk(BIOS_SPEW, "Run returns %d\n", index); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_DPCD_REV<<8|0xe; intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 4, auxin, 14); auxout[0] = 0<<31 /* i2c */|1<<30|0x0<<28/*W*/|0x0<<8|0x0; intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 3, auxin, 0); index = run(index); printk(BIOS_SPEW, "Run returns %d\n", index); auxout[0] = 0<<31 /* i2c */|0<<30|0x0<<28/*W*/|0x0<<8|0x0; intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 3, auxin, 0); index = run(index); printk(BIOS_SPEW, "Run returns %d\n", index); auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_SET_POWER<<8|0x0; auxout[1] = 0x01000000; /* DP_SET_POWER_D0 | DP_PSR_SINK_INACTIVE */ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0); index = run(index); auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_LINK_BW_SET<<8|0x8; auxout[1] = 0x0a840000; /*( DP_LINK_BW_2_7 &0xa)|0x0000840a*/ auxout[2] = 0x00000000; auxout[3] = 0x01000000; intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 13, auxin, 0); index = run(index); auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_PATTERN_SET<<8|0x0; auxout[1] = 0x21000000; /* DP_TRAINING_PATTERN_1 | DP_LINK_SCRAMBLING_DISABLE | * DP_SYMBOL_ERROR_COUNT_BOTH |0x00000021*/ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0); index = run(index); auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_LANE0_SET<<8|0x3; auxout[1] = 0x00000000; /* DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0 |0x00000000*/ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 8, auxin, 0); index = run(index); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_LANE0_1_STATUS<<8|0x5; intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 4, auxin, 5); index = run(index); auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_PATTERN_SET<<8|0x0; auxout[1] = 0x22000000; /* DP_TRAINING_PATTERN_2 | DP_LINK_SCRAMBLING_DISABLE | * DP_SYMBOL_ERROR_COUNT_BOTH |0x00000022*/ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0); index = run(index); auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_LANE0_SET<<8|0x3; auxout[1] = 0x00000000; /* DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0 |0x00000000*/ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 8, auxin, 0); index = run(index); auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_LANE0_1_STATUS<<8|0x5; intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 4, auxin, 5); index = run(index); auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_PATTERN_SET<<8|0x0; auxout[1] = 0x00000000; /* DP_TRAINING_PATTERN_DISABLE | DP_LINK_QUAL_PATTERN_DISABLE | * DP_SYMBOL_ERROR_COUNT_BOTH |0x00000000*/ intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0); index = run(index); if (index != niodefs) printk(BIOS_ERR, "Left over IO work in i915_lightup" " -- this is likely a table error. " "Only %d of %d were done.\n", index, niodefs); printk(BIOS_SPEW, "DONE startup\n"); verbose = 0; /* GTT is the Global Translation Table for the graphics pipeline. * It is used to translate graphics addresses to physical * memory addresses. As in the CPU, GTTs map 4K pages. * There are 32 bits per pixel, or 4 bytes, * which means 1024 pixels per page. * There are 4250 GTTs on Link: * 2650 (X) * 1700 (Y) pixels / 1024 pixels per page. * The setgtt function adds a further bit of flexibility: * it allows you to set a range (the first two parameters) to point * to a physical address (third parameter);the physical address is * incremented by a count (fourth parameter) for each GTT in the * range. * Why do it this way? For ultrafast startup, * we can point all the GTT entries to point to one page, * and set that page to 0s: * memset(physbase, 0, 4096); * setgtt(0, 4250, physbase, 0); * this takes about 2 ms, and is a win because zeroing * the page takes a up to 200 ms. We will be exploiting this * trick in a later rev of this code. * This call sets the GTT to point to a linear range of pages * starting at physbase. */ setgtt(0, FRAME_BUFFER_PAGES, physbase, 4096); printk(BIOS_SPEW, "memset %p to 0 for %d bytes\n", (void *)graphics, FRAME_BUFFER_BYTES); memset((void *)graphics, 0, FRAME_BUFFER_BYTES); printk(BIOS_SPEW, "%ld microseconds\n", globalmicroseconds()); i915_init_done = 1; oprom_is_loaded = 1; return 0; }