Hi TI, we are using SN65DP159 + FPGA to build a HDMI2.0 PHY(Max bit rate 5.94GHz, not display port), and the hardware connection is like this:
LVDS(On PCB) LVDS(On PCB) TMDS(HDMI2.0 cable)
FPGA ----------------------> Caps(0.1uF)-------------------------> SN65DP159 ----------------------------------> TV set.
So far we can show color bars on the TV set for 4K30P and 4K60P, with SN65DP159 working in re-driver mode(for 4K60P, the color has some error).
Now we are trying SN65DP159 running in re-timer mode for 4K30P or 4K60P, but always fail. TV set recognizes the resolution formats and does show bars, but with definitely wrong colors. We have followed your guide in SLLA358 and some other on-line resources about this chip, but the problem is still there.
Below are my questions, the registers setting and the procedure of our work, please help to check, thanks a lot:
Q1: Are the registers setting and the feeding to SN65DP159 right for Step1-5 in main()?
Q2: What is the normal values read from 0x0f if we do PRBS23 verification as step5 in main()?
Q3: Is there any register to indicate the alignment status between ch0-ch2 on SN65DP159?
Q4: Or How can I align up ch0-2?
FPGA can do phase shifting and bit slide for each channel, but what feed back can SN65DP159 give out to complete the adjustment?
//-- Register settings
void main( ) {
//--1. Feed TPS1 to sn65dp159: ch0/ch1/ch2 with a 2.97G(1/2 BitRate) clock,
// ch ck with a clock of 148.5MHz.
tx_tps1();
//--2. sn65dp159 initialization
write_csr (0xFF, 0x00);
write_csr (0x09, 0x0a); // Power down and then power up sn65dp159.
delayms(100);
write_csr (0x09, 0x02);
initial_prog_dp159();
//--3. Do TPS1 test.
tp1_prog_dp159();
//--4. Feed TSP2 to sn65dp159: ch0/ch1/ch2 with repeated a pattern(K28.5-, D11.6, K28.5+, D11.6, D10.2, D10.2, D10.2, D10.2, D10.2, D10.2).
// ch ck with a clock of 148.5MHz.
tx_tps2();
tp2_prog_dp159();
//--5. Fed PRBS23 to sn65dp159: ch0/ch1/ch2 with PRBS23.
// ch ck with a clock of 148.5MHz.
tx_prbs23();
write_csr (0xFF, 0x00);
write_csr (0x10, 0x11);
write_csr (0x0e, 0x07); // Enable prbs23 check.
read_csr (0x0f); // To check the result: Should be 0x00? It reads unstable values on my test: 0xff, 0x0, 0x1e, ....
//--6. Fed normal video to sn65dp159: ch0/ch1/ch2 with tmds data,
// ch ck with a clock of 148.5MHz.
//
tx_tmds();
}
void initial_prog_dp159 (void) {
printf ("\n Initializing DP159...");
write_csr (0xFF, 0x00); // Select Page 0
write_csr (0x09, 0x36); // Enable X-Mode
write_csr (0x0A, 0x7B); // Disable HPD_SNK pass-thru to HPD_SRC. Enable AUX
write_csr (0x0D, 0x80); // Clock on AUX is 1/20 datarate and enabled.
write_csr (0x0C, 0x6D); // Set TX Swing to MAX
write_csr (0x10, 0x00); // Turn off pattern verifier
write_csr (0x16, 0xF1); // Enable DP_TST_EN (disable char-alignment on all lanes)
write_csr (0xFF, 0x01); // Select Page 1
// CONFIGURE PLL BLOCK
write_csr (0x00, 0x02); // Enable Bandgap.
write_csr (0x04, 0x80); // PLL_FBDIV is 40
write_csr (0x05, 0x00); //
write_csr (0x08, 0x00); //
write_csr (0x0D, 0x02); // Selects Lane0 for clock.
write_csr (0x0E, 0x03); // CDR_CONFIG[4:0]. FIXED, LN0.
write_csr (0x01, 0x01); // CP_EN is PLL mode
write_csr (0x02, 0x3f); // CP_CURRENT
write_csr (0x0B, 0x33); // Test. May not use.
write_csr (0xA1, 0x02); // Oscillator enable.
write_csr (0xA4, 0x02); // Override enables.
write_csr (0x10, 0xF0); // ENTX Disable
write_csr (0x11, 0x30); // TX_RATE is Full Rate, TX_TERM = 75 to 150 , TX_INVPAIR = None
write_csr (0x14, 0x00); // HDMI_TWPST1 is 0dB de-emphasis
write_csr (0x12, 0x03); // SLEW_CTRL is Normal, SWING is 600mV.
write_csr (0x13, 0xFF); // FIR_UPD. Load TX settings
write_csr (0x13, 0x00); //
write_csr (0x30, 0xE0); // Disable Receivers
write_csr (0x32, 0x00); // PD_RXINT
write_csr (0x31, 0x00); // RX_RATE is Full
write_csr (0x4D, 0x08); // EQFTC = 1 and EQLEV = 2
write_csr (0x4C, 0x01); // Enable Fixed EQ (must not use adaptive when RX is disabled)
write_csr (0x34, 0x01); // Enable Offset Correction (gated by rx_ld) !!!!
write_csr (0x32, 0xF0); // Load Rx Settings
write_csr (0x32, 0x00); //
write_csr (0x33, 0xF0); // Load EQ settings
write_csr (0xFF, 0x00); // Select Page 0
write_csr (0x0A, 0x3B); // Enable HPD_SNK pass thru to HPD_SRC. Retimer.
write_csr (0xFF, 0x01); // Select Page 1
}
void tp1_prog_dp159 () {
u8 rtxen, eqreg, tsten;
rtxen = 0x0F;
eqreg = 0x08;
tsten = 0xF1; // 1 : 0x11, 2 : 0x31, 4 : 0xF1
// Add all BW_handler processing here...
write_csr(0x00, 0x02); // Enable Bandgap, DISABLE PLL, clear A_LOCK_OVR (to reset it)
write_csr(0x01, 0x01); // CP_EN = PLL (reference) mode
write_csr(0x0B, 0x33); // Set PLL control
write_csr(0x02, 0x3f); // Set CP_CURRENT
write_csr(0x30, 0x0f); // Enable RX lanes
write_csr(0x00, 0x03); // Enable Bandgap, ENABLE PLL, clear A_LOCK_OVR
write_csr(0x4C, 0x01); // Enable fixed EQ (to reset adaptive EQ logic)
write_csr(0x4D, 0x08); // Set EQFTC and EQLEV (fixed EQ)
// Wait for PLL lock...
lock_cnt = 0;
lock_status = 0;
ReadBuffer[0] = 0;
while (ReadBuffer[0] == 0 && lock_cnt < lock_wait) {
read_csr (0x00);
ReadBuffer[0] = ReadBuffer[0] & 0x40; // 0x80;
lock_cnt++;
}
write_csr (0x10, 0x0f); // Enable TX lanes
write_csr (0x00, 0x23); // Enable PLL and Bandgap, set A_LOCK_OVR, and set expand LPRES
write_csr (0x02, 0x5f); // CP_CURRENT
write_csr (0x0B, 0x30); // Set PLL control
write_csr (0x01, 0x02); // CP_EN is PD mode
write_csr (0xFF, 0x00); // Select page 0
write_csr (0x16, 0xf1); // Set DP_TST_EN per #lanes, latch FIFO errors
write_csr (0x10, 0x00); // Disable PV (allows char-align and 8b10 decode to operate)
write_csr (0xFF, 0x01); // Select page 1
}
void tp2_prog_dp159 (XTmrCtr *InstancePtr, u8 link_lanecnt, u16 link_bw) {
write_csr (0x4C, 0x03); // Enable Adaptive EQ
write_csr (0xFF, 0x00); // Select page 0
write_csr (0x15, 0x18); // Clear BERT counters and TST_INTQ latches -- Self-clearing in DP159
err_cnt = read_csr (0x18); // Read core BERT counter [7:0]
err_cnt += ((read_csr(0x19) & 0xF) << 8); // Read core BERT counter [11:8]
write_csr (0xFF, 0x01); // Select page 1
}