Skip to content

Commit c0d4def

Browse files
committed
intel_extreme: Implement Ilk PCH FDI link training
* IronLake tested and FDI says it trains successfully * Still no LVDS video on Ilk
1 parent 9ca2669 commit c0d4def

File tree

5 files changed

+249
-65
lines changed

5 files changed

+249
-65
lines changed

headers/private/graphics/intel_extreme/intel_extreme.h

Lines changed: 70 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@
8989
#define INTEL_PCH_PPT_DEVICE_ID 0x1e00
9090
#define INTEL_PCH_LPT_DEVICE_ID 0x8c00
9191
#define INTEL_PCH_LPT_LP_DEVICE_ID 0x9c00
92-
#define INTEL_PCH_SPT_DEVICE_ID 0xA100
93-
#define INTEL_PCH_SPT_LP_DEVICE_ID 0x9D00
92+
#define INTEL_PCH_SPT_DEVICE_ID 0xa100
93+
#define INTEL_PCH_SPT_LP_DEVICE_ID 0x9d00
9494
#define INTEL_PCH_P2X_DEVICE_ID 0x7100
9595
#define INTEL_PCH_P3X_DEVICE_ID 0x7000
9696

@@ -543,21 +543,21 @@ struct intel_free_graphics_memory {
543543
#define PORT_TRANS_SEL_MASK (3<<29)
544544

545545
// on PCH we also have to set the transcoder
546-
#define INTEL_TRANSCODER_A_HTOTAL (0x0000 | REGS_SOUTH_TRANSCODER_PORT)
547-
#define INTEL_TRANSCODER_A_HBLANK (0x0004 | REGS_SOUTH_TRANSCODER_PORT)
548-
#define INTEL_TRANSCODER_A_HSYNC (0x0008 | REGS_SOUTH_TRANSCODER_PORT)
549-
#define INTEL_TRANSCODER_A_VTOTAL (0x000c | REGS_SOUTH_TRANSCODER_PORT)
550-
#define INTEL_TRANSCODER_A_VBLANK (0x0010 | REGS_SOUTH_TRANSCODER_PORT)
551-
#define INTEL_TRANSCODER_A_VSYNC (0x0014 | REGS_SOUTH_TRANSCODER_PORT)
552-
#define INTEL_TRANSCODER_B_HTOTAL (0x1000 | REGS_SOUTH_TRANSCODER_PORT)
553-
#define INTEL_TRANSCODER_B_HBLANK (0x1004 | REGS_SOUTH_TRANSCODER_PORT)
554-
#define INTEL_TRANSCODER_B_HSYNC (0x1008 | REGS_SOUTH_TRANSCODER_PORT)
555-
#define INTEL_TRANSCODER_B_VTOTAL (0x100c | REGS_SOUTH_TRANSCODER_PORT)
556-
#define INTEL_TRANSCODER_B_VBLANK (0x1010 | REGS_SOUTH_TRANSCODER_PORT)
557-
#define INTEL_TRANSCODER_B_VSYNC (0x1014 | REGS_SOUTH_TRANSCODER_PORT)
558-
559-
#define INTEL_TRANSCODER_A_IMAGE_SIZE (0x001c | REGS_SOUTH_TRANSCODER_PORT)
560-
#define INTEL_TRANSCODER_B_IMAGE_SIZE (0x101c | REGS_SOUTH_TRANSCODER_PORT)
546+
#define INTEL_TRANSCODER_A_HTOTAL (0x0000 | REGS_SOUTH_TRANSCODER_PORT)
547+
#define INTEL_TRANSCODER_A_HBLANK (0x0004 | REGS_SOUTH_TRANSCODER_PORT)
548+
#define INTEL_TRANSCODER_A_HSYNC (0x0008 | REGS_SOUTH_TRANSCODER_PORT)
549+
#define INTEL_TRANSCODER_A_VTOTAL (0x000c | REGS_SOUTH_TRANSCODER_PORT)
550+
#define INTEL_TRANSCODER_A_VBLANK (0x0010 | REGS_SOUTH_TRANSCODER_PORT)
551+
#define INTEL_TRANSCODER_A_VSYNC (0x0014 | REGS_SOUTH_TRANSCODER_PORT)
552+
#define INTEL_TRANSCODER_B_HTOTAL (0x1000 | REGS_SOUTH_TRANSCODER_PORT)
553+
#define INTEL_TRANSCODER_B_HBLANK (0x1004 | REGS_SOUTH_TRANSCODER_PORT)
554+
#define INTEL_TRANSCODER_B_HSYNC (0x1008 | REGS_SOUTH_TRANSCODER_PORT)
555+
#define INTEL_TRANSCODER_B_VTOTAL (0x100c | REGS_SOUTH_TRANSCODER_PORT)
556+
#define INTEL_TRANSCODER_B_VBLANK (0x1010 | REGS_SOUTH_TRANSCODER_PORT)
557+
#define INTEL_TRANSCODER_B_VSYNC (0x1014 | REGS_SOUTH_TRANSCODER_PORT)
558+
559+
#define INTEL_TRANSCODER_A_IMAGE_SIZE (0x001c | REGS_SOUTH_TRANSCODER_PORT)
560+
#define INTEL_TRANSCODER_B_IMAGE_SIZE (0x101c | REGS_SOUTH_TRANSCODER_PORT)
561561

562562
// TODO: Is there consolidation that could happen here with digital ports?
563563

@@ -855,9 +855,26 @@ struct intel_free_graphics_memory {
855855
#define PCH_FDI_RX_BASE_REGISTER 0xf0000
856856
#define PCH_FDI_RX_PIPE_OFFSET 0x01000
857857
#define PCH_FDI_RX_CONTROL 0x00c
858+
#define PCH_FDI_RX_IIR 0x014
859+
#define PCH_FDI_RX_IMR 0x018
860+
858861
#define FDI_RX_ENABLE (1 << 31)
859862
#define FDI_RX_PLL_ENABLED (1 << 13)
860863

864+
865+
// FDI_tX interrupt register
866+
#define FDI_RX_INTER_LANE_ALIGN (1 << 10)
867+
#define FDI_RX_SYMBOL_LOCK (1 << 9)
868+
#define FDI_RX_BIT_LOCK (1 << 8)
869+
#define FDI_RX_TRAIN_PATTERN_2_FAIL (1 << 7)
870+
#define FDI_RX_FS_CODE_ERR (1 << 6)
871+
#define FDI_RX_FE_CODE_ERR (1 << 5)
872+
#define FDI_RX_SYMBOL_ERR_RATE_ABOVE (1 << 4)
873+
#define FDI_RX_HDCP_LINK_FAIL (1 << 3)
874+
#define FDI_RX_PIXEL_FIFO_OVERFLOW (1 << 2)
875+
#define FDI_RX_CROSS_CLOCK_OVERFLOW (1 << 1)
876+
#define FDI_RX_SYMBOL_QUEUE_OVERFLOW (1 << 0)
877+
861878
#define FDI_FS_ERRC_ENABLE (1 << 27)
862879
#define FDI_FE_ERRC_ENABLE (1 << 26)
863880

@@ -871,12 +888,37 @@ struct intel_free_graphics_memory {
871888
#define FDI_RX_CLOCK_RAW (0 << 4)
872889
#define FDI_RX_CLOCK_PCD (1 << 4)
873890

874-
#define PCH_FDI_TX_BASE_REGISTER 0x60000
875-
#define PCH_FDI_TX_PIPE_OFFSET 0x01000
876-
#define PCH_FDI_TX_CONTROL 0x100
877-
#define FDI_TX_ENABLE (1 << 31)
878-
#define FDI_TX_ENHANCE_FRAME_ENABLE (1 << 18)
879-
#define FDI_TX_PLL_ENABLED (1 << 14)
891+
#define PCH_FDI_TX_BASE_REGISTER 0x60000
892+
#define PCH_FDI_TX_PIPE_OFFSET 0x01000
893+
#define PCH_FDI_TX_CONTROL 0x100
894+
#define FDI_TX_ENABLE (1 << 31)
895+
#define FDI_LINK_TRAIN_PATTERN_1 (0 << 28)
896+
#define FDI_LINK_TRAIN_PATTERN_2 (1 << 28)
897+
#define FDI_LINK_TRAIN_PATTERN_IDLE (2 << 28)
898+
#define FDI_LINK_TRAIN_NONE (3 << 28)
899+
#define FDI_LINK_TRAIN_VOLTAGE_0_4V (0 << 25)
900+
#define FDI_LINK_TRAIN_VOLTAGE_0_6V (1 << 25)
901+
#define FDI_LINK_TRAIN_VOLTAGE_0_8V (2 << 25)
902+
#define FDI_LINK_TRAIN_VOLTAGE_1_2V (3 << 25)
903+
#define FDI_LINK_TRAIN_PRE_EMPHASIS_NONE (0 << 22)
904+
#define FDI_LINK_TRAIN_PRE_EMPHASIS_1_5X (1 << 22)
905+
#define FDI_LINK_TRAIN_PRE_EMPHASIS_2X (2 << 22)
906+
#define FDI_LINK_TRAIN_PRE_EMPHASIS_3X (3 << 22)
907+
908+
// SNB A stepping
909+
#define FDI_LINK_TRAIN_400MV_0DB_SNB_A (0x38 << 22)
910+
#define FDI_LINK_TRAIN_400MV_6DB_SNB_A (0x02 << 22)
911+
#define FDI_LINK_TRAIN_600MV_3_5DB_SNB_A (0x01 << 22)
912+
#define FDI_LINK_TRAIN_800MV_0DB_SNB_A (0x00 << 22)
913+
914+
// SNB B stepping
915+
#define FDI_LINK_TRAIN_400MV_0DB_SNB_B (0x00 << 22)
916+
#define FDI_LINK_TRAIN_400MV_6DB_SNB_B (0x3a << 22)
917+
#define FDI_LINK_TRAIN_600MV_3_5DB_SNB_B (0x39 << 22)
918+
#define FDI_LINK_TRAIN_800MV_0DB_SNB_B (0x38 << 22)
919+
#define FDI_LINK_TRAIN_VOL_EMP_MASK (0x3f << 22)
920+
#define FDI_TX_ENHANCE_FRAME_ENABLE (1 << 18)
921+
#define FDI_TX_PLL_ENABLED (1 << 14)
880922

881923
#define FDI_DP_PORT_WIDTH_SHIFT 19
882924
#define FDI_DP_PORT_WIDTH_MASK (7 << FDI_DP_PORT_WIDTH_SHIFT)
@@ -887,35 +929,9 @@ struct intel_free_graphics_memory {
887929
#define FDI_PLL_BIOS_1 0x46004
888930
#define FDI_PLL_BIOS_2 0x46008
889931

890-
#define FDI_LINK_TRAIN_PATTERN_1 (0 << 28)
891-
#define FDI_LINK_TRAIN_PATTERN_2 (1 << 28)
892-
#define FDI_LINK_TRAIN_PATTERN_IDLE (2 << 28)
893-
#define FDI_LINK_TRAIN_NONE (3 << 28)
894-
#define FDI_LINK_TRAIN_VOLTAGE_0_4V (0 << 25)
895-
#define FDI_LINK_TRAIN_VOLTAGE_0_6V (1 << 25)
896-
#define FDI_LINK_TRAIN_VOLTAGE_0_8V (2 << 25)
897-
#define FDI_LINK_TRAIN_VOLTAGE_1_2V (3 << 25)
898-
#define FDI_LINK_TRAIN_PRE_EMPHASIS_NONE (0 << 22)
899-
#define FDI_LINK_TRAIN_PRE_EMPHASIS_1_5X (1 << 22)
900-
#define FDI_LINK_TRAIN_PRE_EMPHASIS_2X (2 << 22)
901-
#define FDI_LINK_TRAIN_PRE_EMPHASIS_3X (3 << 22)
902-
903932
#define FDI_AUTO_TRAINING (1 << 10)
904933
#define FDI_AUTO_TRAIN_DONE (1 << 1)
905934

906-
// SNB A-stepping
907-
#define FDI_LINK_TRAIN_400MV_0DB_SNB_A (0x38 << 22)
908-
#define FDI_LINK_TRAIN_400MV_6DB_SNB_A (0x02 << 22)
909-
#define FDI_LINK_TRAIN_600MV_3_5DB_SNB_A (0x01 << 22)
910-
#define FDI_LINK_TRAIN_800MV_0DB_SNB_A (0x00 << 22)
911-
912-
// SNB B-stepping
913-
#define FDI_LINK_TRAIN_400MV_0DB_SNB_B (0x00 << 22)
914-
#define FDI_LINK_TRAIN_400MV_6DB_SNB_B (0x3a << 22)
915-
#define FDI_LINK_TRAIN_600MV_3_5DB_SNB_B (0x39 << 22)
916-
#define FDI_LINK_TRAIN_800MV_0DB_SNB_B (0x38 << 22)
917-
#define FDI_LINK_TRAIN_VOL_EMP_MASK (0x3f << 22)
918-
919935
#define FDI_LINK_TRAIN_PATTERN_1_CPT (0 << 8)
920936
#define FDI_LINK_TRAIN_PATTERN_2_CPT (1 << 8)
921937
#define FDI_LINK_TRAIN_PATTERN_IDLE_CPT (2 << 8)
@@ -928,6 +944,11 @@ struct intel_free_graphics_memory {
928944
#define FDI_LINK_TRAIN_PATTERN_IDLE_IVB (2 << 8)
929945
#define FDI_LINK_TRAIN_NONE_IVB (3 << 8)
930946

947+
#define PCH_FDI_RXA_CHICKEN (0x200c | REGS_SOUTH_SHARED)
948+
#define PCH_FDI_RXB_CHICKEN (0x2010 | REGS_SOUTH_SHARED)
949+
#define FDI_RX_PHASE_SYNC_POINTER_EN (1 << 0)
950+
#define FDI_RX_PHASE_SYNC_POINTER_OVR (1 << 1)
951+
931952
// CPU Panel Fitters - These are for IronLake and up and are the CPU internal
932953
// panel fitters.
933954
#define PCH_PANEL_FITTER_BASE_REGISTER 0x68000

src/add-ons/accelerants/intel_extreme/FlexibleDisplayInterface.cpp

Lines changed: 168 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,8 @@ FDIReceiver::SwitchClock(bool toPCDClock)
220220
FDILink::FDILink(pipe_index pipeIndex)
221221
:
222222
fTransmitter(pipeIndex),
223-
fReceiver(pipeIndex)
223+
fReceiver(pipeIndex),
224+
fPipeIndex(pipeIndex)
224225
{
225226
}
226227

@@ -262,35 +263,188 @@ FDILink::Train(display_mode* target)
262263

263264
status_t result = B_ERROR;
264265

265-
// Over IVB supports AutoTraining of FDI
266-
if (gInfo->shared_info->device_type.Generation() >= 7) {
266+
// TODO: Only _AutoTrain on IVYB Stepping B or later
267+
// otherwise, _ManualTrain
268+
if (gInfo->shared_info->device_type.Generation() >= 7)
267269
result = _AutoTrain(lanes);
268-
if (result != B_OK) {
269-
ERROR("%s: FDI auto-training fault. Attempting manual train.\n",
270-
__func__);
271-
return _ManualTrain(lanes);
272-
}
273-
return B_OK;
270+
else if (gInfo->shared_info->device_type.Generation() == 6)
271+
result = _SnbTrain(lanes);
272+
else if (gInfo->shared_info->device_type.Generation() == 5)
273+
result = _IlkTrain(lanes);
274+
else
275+
result = _NormalTrain(lanes);
276+
277+
if (result != B_OK) {
278+
ERROR("%s: FDI training fault.\n", __func__);
274279
}
275-
return _ManualTrain(lanes);
280+
281+
return result;
276282
}
277283

278284

279285
status_t
280-
FDILink::_ManualTrain(uint32 lanes)
286+
FDILink::_NormalTrain(uint32 lanes)
287+
{
288+
CALLED();
289+
uint32 txControl = Transmitter().Base() + PCH_FDI_TX_CONTROL;
290+
uint32 rxControl = Receiver().Base() + PCH_FDI_RX_CONTROL;
291+
292+
// Enable normal link training
293+
uint32 tmp = read32(txControl);
294+
if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_IVB)) {
295+
tmp &= ~FDI_LINK_TRAIN_NONE_IVB;
296+
tmp |= FDI_LINK_TRAIN_NONE_IVB | FDI_TX_ENHANCE_FRAME_ENABLE;
297+
} else {
298+
tmp &= ~FDI_LINK_TRAIN_NONE;
299+
tmp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
300+
}
301+
write32(txControl, tmp);
302+
303+
tmp = read32(rxControl);
304+
if (gInfo->shared_info->pch_info == INTEL_PCH_CPT) {
305+
tmp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
306+
tmp |= FDI_LINK_TRAIN_NORMAL_CPT;
307+
} else {
308+
tmp &= ~FDI_LINK_TRAIN_NONE;
309+
tmp |= FDI_LINK_TRAIN_NONE;
310+
}
311+
write32(rxControl, tmp | FDI_RX_ENHANCE_FRAME_ENABLE);
312+
313+
// Wait 1x idle pattern
314+
read32(rxControl);
315+
spin(1000);
316+
317+
// Enable ecc on IVB
318+
if (gInfo->shared_info->device_type.InGroup(INTEL_GROUP_IVB)) {
319+
write32(rxControl, read32(rxControl)
320+
| FDI_FS_ERRC_ENABLE | FDI_FE_ERRC_ENABLE);
321+
read32(rxControl);
322+
}
323+
324+
return B_OK;
325+
}
326+
327+
328+
status_t
329+
FDILink::_IlkTrain(uint32 lanes)
281330
{
282331
CALLED();
332+
uint32 txControl = Transmitter().Base() + PCH_FDI_TX_CONTROL;
333+
uint32 rxControl = Receiver().Base() + PCH_FDI_RX_CONTROL;
283334

284-
// This needs completed
285-
ERROR("TODO: Manual FDI Link Training\n");
335+
// Train 1: unmask FDI RX Interrupt symbol_lock and bit_lock
336+
uint32 tmp = read32(Receiver().Base() + PCH_FDI_RX_IMR);
337+
tmp &= ~FDI_RX_SYMBOL_LOCK;
338+
tmp &= ~FDI_RX_BIT_LOCK;
339+
write32(Receiver().Base() + PCH_FDI_RX_IMR, tmp);
340+
spin(150);
286341

287-
// Enable pipes
342+
// Enable CPU FDI TX and RX
343+
tmp = read32(txControl);
344+
tmp &= ~FDI_DP_PORT_WIDTH_MASK;
345+
tmp |= FDI_DP_PORT_WIDTH(lanes);
346+
tmp &= ~FDI_LINK_TRAIN_NONE;
347+
tmp |= FDI_LINK_TRAIN_PATTERN_1;
348+
write32(txControl, tmp);
288349
Transmitter().Enable();
350+
351+
tmp = read32(rxControl);
352+
tmp &= ~FDI_LINK_TRAIN_NONE;
353+
tmp |= FDI_LINK_TRAIN_PATTERN_1;
354+
write32(rxControl, tmp);
289355
Receiver().Enable();
356+
357+
// ILK Workaround, enable clk after FDI enable
358+
if (fPipeIndex == INTEL_PIPE_B) {
359+
write32(PCH_FDI_RXB_CHICKEN, FDI_RX_PHASE_SYNC_POINTER_OVR);
360+
write32(PCH_FDI_RXB_CHICKEN, FDI_RX_PHASE_SYNC_POINTER_OVR
361+
| FDI_RX_PHASE_SYNC_POINTER_EN);
362+
} else {
363+
write32(PCH_FDI_RXA_CHICKEN, FDI_RX_PHASE_SYNC_POINTER_OVR);
364+
write32(PCH_FDI_RXA_CHICKEN, FDI_RX_PHASE_SYNC_POINTER_OVR
365+
| FDI_RX_PHASE_SYNC_POINTER_EN);
366+
}
367+
368+
uint32 iirControl = Receiver().Base() + PCH_FDI_RX_IIR;
369+
TRACE("%s: FDI RX IIR Control @ 0x%x\n", __func__, iirControl);
370+
371+
int tries = 0;
372+
for (tries = 0; tries < 5; tries++) {
373+
tmp = read32(iirControl);
374+
TRACE("%s: FDI RX IIR 0x%x\n", __func__, tmp);
375+
376+
if ((tmp & FDI_RX_BIT_LOCK)) {
377+
TRACE("%s: FDI train 1 done\n", __func__);
378+
write32(iirControl, tmp | FDI_RX_BIT_LOCK);
379+
break;
380+
}
381+
}
382+
383+
if (tries == 5) {
384+
ERROR("%s: FDI train 1 failure!\n", __func__);
385+
return B_ERROR;
386+
}
387+
388+
// Train 2
389+
tmp = read32(txControl);
390+
tmp &= ~FDI_LINK_TRAIN_NONE;
391+
tmp |= FDI_LINK_TRAIN_PATTERN_2;
392+
write32(txControl, tmp);
393+
394+
tmp = read32(rxControl);
395+
tmp &= ~FDI_LINK_TRAIN_NONE;
396+
tmp |= FDI_LINK_TRAIN_PATTERN_2;
397+
write32(rxControl, tmp);
398+
399+
read32(rxControl);
400+
spin(150);
401+
402+
for (tries = 0; tries < 5; tries++) {
403+
tmp = read32(iirControl);
404+
TRACE("%s: FDI RX IIR 0x%x\n", __func__, tmp);
405+
406+
if (tmp & FDI_RX_SYMBOL_LOCK) {
407+
TRACE("%s: FDI train 2 done\n", __func__);
408+
write32(iirControl, tmp | FDI_RX_SYMBOL_LOCK);
409+
break;
410+
}
411+
}
412+
413+
if (tries == 5) {
414+
ERROR("%s: FDI train 2 failure!\n", __func__);
415+
return B_ERROR;
416+
}
417+
290418
return B_OK;
291419
}
292420

293421

422+
status_t
423+
FDILink::_SnbTrain(uint32 lanes)
424+
{
425+
CALLED();
426+
//uint32 txControl = Transmitter().Base() + PCH_FDI_TX_CONTROL;
427+
//uint32 rxControl = Receiver().Base() + PCH_FDI_RX_CONTROL;
428+
429+
ERROR("%s: TODO\n", __func__);
430+
431+
return B_ERROR;
432+
}
433+
434+
435+
status_t
436+
FDILink::_ManualTrain(uint32 lanes)
437+
{
438+
CALLED();
439+
//uint32 txControl = Transmitter().Base() + PCH_FDI_TX_CONTROL;
440+
//uint32 rxControl = Receiver().Base() + PCH_FDI_RX_CONTROL;
441+
442+
ERROR("%s: TODO\n", __func__);
443+
444+
return B_ERROR;
445+
}
446+
447+
294448
status_t
295449
FDILink::_AutoTrain(uint32 lanes)
296450
{

src/add-ons/accelerants/intel_extreme/FlexibleDisplayInterface.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,11 +68,16 @@ class FDILink {
6868
status_t Train(display_mode* target);
6969

7070
private:
71+
status_t _NormalTrain(uint32 lanes);
72+
status_t _IlkTrain(uint32 lanes);
73+
status_t _SnbTrain(uint32 lanes);
7174
status_t _ManualTrain(uint32 lanes);
7275
status_t _AutoTrain(uint32 lanes);
7376

7477
FDITransmitter fTransmitter;
7578
FDIReceiver fReceiver;
79+
80+
pipe_index fPipeIndex;
7681
};
7782

7883

0 commit comments

Comments
 (0)