phy: rockchip: usbdp: adjust phy parameters for SI test

According to the result of SI test, adjust the ssc, voltage
swing, pre-emphasis to improve the phy compatibility.

Different rates use different parameters. The rbr and hbr
use the same parameters. Note that Type-C port's parameters
and DP standard port's parameters are different when the
lane rate is rbr or hbr.

Signed-off-by: Zhang Yubing <yubing.zhang@rock-chips.com>
Change-Id: I27a8a846a198c7feabf1aaf1459a7df056e4312a
This commit is contained in:
Zhang Yubing
2021-12-17 20:30:58 +08:00
committed by Tao Huang
parent 577e8c4548
commit e7599abc64

View File

@@ -72,6 +72,13 @@ struct udphy_vogrf_cfg {
struct udphy_grf_reg hpd_trigger;
};
struct dp_tx_drv_ctrl {
u32 trsv_reg0204;
u32 trsv_reg0205;
u32 trsv_reg0206;
u32 trsv_reg0207;
};
struct rockchip_udphy;
struct rockchip_udphy_cfg {
@@ -81,6 +88,8 @@ struct rockchip_udphy_cfg {
struct udphy_grf_cfg grfcfg;
struct udphy_vogrf_cfg vogrfcfg[2];
const struct dp_tx_drv_ctrl (*dp_tx_ctrl_cfg[4])[4];
const struct dp_tx_drv_ctrl (*dp_tx_ctrl_cfg_typec[4])[4];
int (*combophy_init)(struct rockchip_udphy *udphy);
int (*dp_phy_set_rate)(struct rockchip_udphy *udphy,
struct phy_configure_opts_dp *dp);
@@ -124,12 +133,125 @@ struct rockchip_udphy {
u32 dp_lane_sel[4];
u32 dp_aux_dout_sel;
u32 dp_aux_din_sel;
u8 bw;
int id;
/* PHY const config */
const struct rockchip_udphy_cfg *cfgs;
};
static const struct dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_rbr_hbr[4][4] = {
/* voltage swing 0, pre-emphasis 0->3 */
{
{ 0x20, 0x10, 0x42, 0xe5 },
{ 0x26, 0x14, 0x42, 0xe5 },
{ 0x29, 0x18, 0x42, 0xe5 },
{ 0x2b, 0x1c, 0x43, 0xe7 },
},
/* voltage swing 1, pre-emphasis 0->2 */
{
{ 0x23, 0x10, 0x42, 0xe7 },
{ 0x2a, 0x17, 0x43, 0xe7 },
{ 0x2b, 0x1a, 0x43, 0xe7 },
},
/* voltage swing 2, pre-emphasis 0->1 */
{
{ 0x27, 0x10, 0x42, 0xe7 },
{ 0x2b, 0x17, 0x43, 0xe7 },
},
/* voltage swing 3, pre-emphasis 0 */
{
{ 0x29, 0x10, 0x43, 0xe7 },
},
};
static const struct dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_rbr_hbr_typec[4][4] = {
/* voltage swing 0, pre-emphasis 0->3 */
{
{ 0x20, 0x10, 0x42, 0xe5 },
{ 0x26, 0x14, 0x42, 0xe5 },
{ 0x29, 0x18, 0x42, 0xe5 },
{ 0x2b, 0x1c, 0x43, 0xe7 },
},
/* voltage swing 1, pre-emphasis 0->2 */
{
{ 0x23, 0x10, 0x42, 0xe7 },
{ 0x2a, 0x17, 0x43, 0xe7 },
{ 0x2b, 0x1a, 0x43, 0xe7 },
},
/* voltage swing 2, pre-emphasis 0->1 */
{
{ 0x27, 0x10, 0x43, 0x67 },
{ 0x2b, 0x17, 0x43, 0xe7 },
},
/* voltage swing 3, pre-emphasis 0 */
{
{ 0x29, 0x10, 0x43, 0xe7 },
},
};
static const struct dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_hbr2[4][4] = {
/* voltage swing 0, pre-emphasis 0->3 */
{
{ 0x21, 0x10, 0x42, 0xe5 },
{ 0x26, 0x14, 0x42, 0xe5 },
{ 0x26, 0x16, 0x43, 0xe5 },
{ 0x2a, 0x19, 0x43, 0xe7 },
},
/* voltage swing 1, pre-emphasis 0->2 */
{
{ 0x24, 0x10, 0x42, 0xe7 },
{ 0x2a, 0x17, 0x43, 0xe7 },
{ 0x2b, 0x1a, 0x43, 0xe7 },
},
/* voltage swing 2, pre-emphasis 0->1 */
{
{ 0x28, 0x10, 0x42, 0xe7 },
{ 0x2b, 0x17, 0x43, 0xe7 },
},
/* voltage swing 3, pre-emphasis 0 */
{
{ 0x28, 0x10, 0x43, 0xe7 },
},
};
static const struct dp_tx_drv_ctrl rk3588_dp_tx_drv_ctrl_hbr3[4][4] = {
/* voltage swing 0, pre-emphasis 0->3 */
{
{ 0x21, 0x10, 0x42, 0xe5 },
{ 0x26, 0x14, 0x42, 0xe5 },
{ 0x26, 0x16, 0x43, 0xe5 },
{ 0x29, 0x18, 0x43, 0xe7 },
},
/* voltage swing 1, pre-emphasis 0->2 */
{
{ 0x24, 0x10, 0x42, 0xe7 },
{ 0x2a, 0x18, 0x43, 0xe7 },
{ 0x2b, 0x1b, 0x43, 0xe7 }
},
/* voltage swing 2, pre-emphasis 0->1 */
{
{ 0x27, 0x10, 0x42, 0xe7 },
{ 0x2b, 0x18, 0x43, 0xe7 }
},
/* voltage swing 3, pre-emphasis 0 */
{
{ 0x28, 0x10, 0x43, 0xe7 },
},
};
static const struct reg_sequence rk3588_udphy_24m_refclk_cfg[] = {
{0x0090, 0x68}, {0x0094, 0x68},
{0x0128, 0x24}, {0x012c, 0x44},
@@ -150,10 +272,10 @@ static const struct reg_sequence rk3588_udphy_24m_refclk_cfg[] = {
{0x01fc, 0x29}, {0x0208, 0x2a},
{0x020c, 0x17}, {0x0210, 0x17},
{0x0214, 0x2a}, {0x0224, 0x20},
{0x03f0, 0x0d}, {0x03f4, 0x09},
{0x03f8, 0x09}, {0x03fc, 0x0d},
{0x0404, 0x0e}, {0x0408, 0x14},
{0x040c, 0x14}, {0x0410, 0x3b},
{0x03f0, 0x0a}, {0x03f4, 0x07},
{0x03f8, 0x07}, {0x03fc, 0x0c},
{0x0404, 0x12}, {0x0408, 0x1a},
{0x040c, 0x1a}, {0x0410, 0x3f},
{0x0ce0, 0x68}, {0x0ce8, 0xd0},
{0x0cf0, 0x87}, {0x0cf8, 0x70},
{0x0d00, 0x70}, {0x0d08, 0xa9},
@@ -1033,13 +1155,15 @@ static int rockchip_udphy_probe(struct platform_device *pdev)
return ret;
}
ret = udphy_setup_typec_mux(udphy);
if (ret)
return ret;
if (device_property_present(dev, "svid")) {
ret = udphy_setup_typec_mux(udphy);
if (ret)
return ret;
ret = devm_add_action_or_reset(dev, udphy_typec_mux_unregister, udphy);
if (ret)
return ret;
ret = devm_add_action_or_reset(dev, udphy_typec_mux_unregister, udphy);
if (ret)
return ret;
}
for_each_available_child_of_node(np, child_np) {
struct phy *phy;
@@ -1271,7 +1395,6 @@ static int rk3588_udphy_dplane_select(struct rockchip_udphy *udphy)
static int rk3588_dp_phy_set_rate(struct rockchip_udphy *udphy,
struct phy_configure_opts_dp *dp)
{
u8 bw;
u32 val;
int ret;
@@ -1280,23 +1403,23 @@ static int rk3588_dp_phy_set_rate(struct rockchip_udphy *udphy,
switch (dp->link_rate) {
case 1620:
bw = DP_BW_RBR;
udphy->bw = DP_BW_RBR;
break;
case 2700:
bw = DP_BW_HBR;
udphy->bw = DP_BW_HBR;
break;
case 5400:
bw = DP_BW_HBR2;
udphy->bw = DP_BW_HBR2;
break;
case 8100:
bw = DP_BW_HBR3;
udphy->bw = DP_BW_HBR3;
break;
default:
return -EINVAL;
}
regmap_update_bits(udphy->pma_regmap, CMN_DP_LINK_OFFSET, CMN_DP_TX_LINK_BW,
FIELD_PREP(CMN_DP_TX_LINK_BW, bw));
FIELD_PREP(CMN_DP_TX_LINK_BW, udphy->bw));
regmap_update_bits(udphy->pma_regmap, CMN_SSC_EN_OFFSET, CMN_ROPLL_SSC_EN,
FIELD_PREP(CMN_ROPLL_SSC_EN, dp->ssc));
regmap_update_bits(udphy->pma_regmap, CMN_DP_RSTN_OFFSET, CMN_DP_CMN_RSTN,
@@ -1314,55 +1437,25 @@ static int rk3588_dp_phy_set_rate(struct rockchip_udphy *udphy,
return 0;
}
static const struct {
u32 trsv_reg0204;
u32 trsv_reg0205;
u32 trsv_reg0206;
u32 trsv_reg0207;
} training_table[4][4] = {
/* voltage swing 0, pre-emphasis 0->3 */
{
{ 0x21, 0x10, 0x42, 0xe5 },
{ 0x25, 0x14, 0x42, 0xe5 },
{ 0x26, 0x17, 0x43, 0xe5 },
{ 0x2b, 0x1c, 0x43, 0xe7 }
},
/* voltage swing 1, pre-emphasis 0->2 */
{
{ 0x26, 0x10, 0x42, 0xe7 },
{ 0x2b, 0x15, 0x42, 0xe7 },
{ 0x2b, 0x18, 0x43, 0xe7 }
},
/* voltage swing 2, pre-emphasis 0->1 */
{
{ 0x2a, 0x10, 0x42, 0xe7 },
{ 0x2b, 0x15, 0x43, 0xe7 }
},
/* voltage swing 3, pre-emphasis 0 */
{
{ 0x2b, 0x10, 0x43, 0xe7 },
},
};
static void rk3588_dp_phy_set_voltage(struct rockchip_udphy *udphy,
static void rk3588_dp_phy_set_voltage(struct rockchip_udphy *udphy, u8 bw,
u32 voltage, u32 pre, u32 lane)
{
u32 offset = 0x800 * lane;
u32 val;
const struct rockchip_udphy_cfg *cfg = udphy->cfgs;
const struct dp_tx_drv_ctrl (*dp_ctrl)[4];
val = training_table[voltage][pre].trsv_reg0204;
dp_ctrl = udphy->mux ? cfg->dp_tx_ctrl_cfg_typec[bw] : cfg->dp_tx_ctrl_cfg[bw];
val = dp_ctrl[voltage][pre].trsv_reg0204;
regmap_write(udphy->pma_regmap, 0x0810 + offset, val);
val = training_table[voltage][pre].trsv_reg0205;
val = dp_ctrl[voltage][pre].trsv_reg0205;
regmap_write(udphy->pma_regmap, 0x0814 + offset, val);
val = training_table[voltage][pre].trsv_reg0206;
val = dp_ctrl[voltage][pre].trsv_reg0206;
regmap_write(udphy->pma_regmap, 0x0818 + offset, val);
val = training_table[voltage][pre].trsv_reg0207;
val = dp_ctrl[voltage][pre].trsv_reg0207;
regmap_write(udphy->pma_regmap, 0x081c + offset, val);
}
@@ -1389,8 +1482,7 @@ static int rk3588_dp_phy_set_voltages(struct rockchip_udphy *udphy,
break;
}
rk3588_dp_phy_set_voltage(udphy, dp->voltage[i],
dp->pre[i], lane);
rk3588_dp_phy_set_voltage(udphy, udphy->bw, dp->voltage[i], dp->pre[i], lane);
}
return 0;
@@ -1424,6 +1516,18 @@ static const struct rockchip_udphy_cfg rk3588_udphy_cfgs = {
.hpd_trigger = { 0x0008, 11, 10, 1, 3 },
},
},
.dp_tx_ctrl_cfg = {
rk3588_dp_tx_drv_ctrl_rbr_hbr,
rk3588_dp_tx_drv_ctrl_rbr_hbr,
rk3588_dp_tx_drv_ctrl_hbr2,
rk3588_dp_tx_drv_ctrl_hbr3,
},
.dp_tx_ctrl_cfg_typec = {
rk3588_dp_tx_drv_ctrl_rbr_hbr_typec,
rk3588_dp_tx_drv_ctrl_rbr_hbr_typec,
rk3588_dp_tx_drv_ctrl_hbr2,
rk3588_dp_tx_drv_ctrl_hbr3,
},
.combophy_init = rk3588_udphy_init,
.dp_phy_set_rate = rk3588_dp_phy_set_rate,
.dp_phy_set_voltages = rk3588_dp_phy_set_voltages,