Browse Source

Add X8 PCIE clock phase calibration.

This patch can fix some PCIE x8 device be recognized to PCIE x4 problem.

Change-Id: I9a109845aa1abd93010b35314cbc1501eeaa8ae5
master
Chen Xinke 6 years ago
committed by zhangbaoqi
parent
commit
056c160be4
  1. 81
      pmon/arch/mips/ls7a/ls7a_config.S
  2. 105
      pmon/arch/mips/ls7a/ls7a_init.S

81
pmon/arch/mips/ls7a/ls7a_config.S

@ -150,3 +150,84 @@ ls7a_phy_cfg_read:
jr ra
nop
.end ls7a_phy_cfg_read
//score calculation algorithm:
//for value: 3/c: -1; 1/4/5: +1; others: +0;
//repeat N times, each time get 2 values, so highest score is 2N,
//lowest score is -2N.
//add score offset 2N to make score keep positive
//record number of value 3 and value c seperately too, for dll adjustment.
//t1: count of value 3; indicate clk 1 early
//t2: count of value c; indicate clk 0 early
//t3: current configure score
.global ls7a_get_pcie_dll_score
.ent ls7a_get_pcie_dll_score
.set noreorder
.set mips3
ls7a_get_pcie_dll_score:
//input:
//t4: confreg address
//return: t1, t2, t3
//used register: a0-a2, v0-v1, t1-t5
move t1, $0
move t2, $0
li t3, (PCIE_PD_LOOP * 2)
li a1, PCIE_PD_LOOP
1:
lw a0, 0x0(t4)
srl a2, a0, 24
and a2, a2, 0xf
move t5, $0 //control check 2 clk
check_1clk:
li v0, 0x3
beq a2, v0, pd_3
nop
li v0, 0xc
beq a2, v0, pd_c
nop
li v0, 0x1
beq a2, v0, pd_145
nop
li v0, 0x4
beq a2, v0, pd_145
nop
li v0, 0x5
beq a2, v0, pd_145
nop
b 2f
nop
pd_3:
li v1, (1 << 0)
daddu t1, t1, v1
subu t3, t3, 1
b 2f
nop
pd_c:
li v1, (1 << 0)
daddu t2, t2, v1
subu t3, t3, 1
b 2f
nop
pd_145:
addu t3, t3, 1
2:
bnez t5, 3f
nop
addu t5, t5, 1
srl a2, a0, 28
and a2, a2, 0xf
b check_1clk
nop
3:
subu a1, a1, 1
bnez a1, 1b
nop
jr ra
nop
.end ls7a_get_pcie_dll_score

105
pmon/arch/mips/ls7a/ls7a_init.S

@ -423,6 +423,111 @@
sw t1, CONF_NB_OFFSET(t0)
#endif
#if 1
#define PCIE_PD_LOOP 20
//for PCIE_H/G0/G1
//t7: adjust dir(dll delay offset, 0: add delay at dll 0; 8: add deley at dll 1)
//t8: old score
dli a0, 0x5cc
daddu t4, t0, a0
cal_one_pcie_x8:
bal ls7a_get_pcie_dll_score
nop
#if 0
TTYDBG("\r\ninitial config is: 0x")
lw a0, 0x0(t4)
bal hexserial
nop
TTYDBG("\r\ninitial score is: 0x")
move a0, t3
bal hexserial
nop
TTYDBG("\r\ninitial count of 3 is: 0x")
move a0, t1
bal hexserial
nop
TTYDBG("\r\ninitial count of c is: 0x")
move a0, t2
bal hexserial
nop
#endif
//find max of value 3 and c and determine the calibration direction
bgt t1, t2, 1f
nop
//t2 > t1
dsubu a0, t2, t1
b 2f
nop
1:
//t1 > t2
dsubu a0, t1, t2
2:
//when the two number has remarkable difference, start dll calibration
dli a1, (PCIE_PD_LOOP / 2)
blt a0, a1, 8f
nop
move t7, $0
ble t1, t2, 1f
nop
daddu t7, $0, 8
1:
//calibration begin
//store old score
move t8, t3
li a1, 0xff
lw a0, 0x0(t4)
srl a0, a0, t7
and a0, a0, a1
beq a0, a1, 8f //reach max adjust value
nop
sll a0, a0, 1
or a0, a0, 1
and a0, a0, a1
sll a0, a0, t7
sw a0, 0x0(t4)
bal ls7a_get_pcie_dll_score
nop
dsub a0, t3, t8
dli a1, -2 //if this calibration has not make it remarkable worse, continue
bgt a0, a1, 1b
nop
//make it worse a lot, scroll back
lw a0, 0x0(t4)
srl a0, a0, t7
and a0, a0, 0xff
srl a0, a0, 1
sll a0, a0, t7
sw a0, 0x0(t4)
8: //end of calibration
#if 0
TTYDBG("\r\nfinal config is: 0x")
lw a0, 0x0(t4)
bal hexserial
nop
TTYDBG("\r\nfinal score is: 0x")
move a0, t3
bal hexserial
nop
TTYDBG("\r\nfinal count of 3 is: 0x")
move a0, t1
bal hexserial
nop
TTYDBG("\r\nfinal count of c is: 0x")
move a0, t2
bal hexserial
nop
#endif
daddu t4, t4, 0x20
dsubu a0, t4, t0
li a1, 0x60c
dsubu a0, a0, a1
blez a0, cal_one_pcie_x8
nop
#endif
//enable access
lw t1, CONF_NB_OFFSET(t0)
li t2, ((1 << 29) | (1 << 25) | (1 << 21) | (1 << 17) | (1 << 9))

Loading…
Cancel
Save