[PATCH 2/4] phy: rockchip-typec: support variable phy config value

hl hl at rock-chips.com
Tue May 8 20:39:58 PDT 2018



On Monday, May 07, 2018 09:59 PM, Enric Balletbo Serra wrote:
> Hi Lin,
>
> Thanks for the patch, apart from the new build warnings introduced
> some more comments below.
>
> 2018-05-04 10:08 GMT+02:00 Lin Huang <hl at rock-chips.com>:
>> the phy config values used to fix in dp firmware, but some boards
>> need change these values to do training and get the better eye diagram
>> result. So support that in phy driver.
>>
>> Signed-off-by: Chris Zhong <zyw at rock-chips.com>
>> Signed-off-by: Lin Huang <hl at rock-chips.com>
>> ---
>>   drivers/phy/rockchip/phy-rockchip-typec.c | 286 +++++++++++++++++++-----------
>>   include/soc/rockchip/rockchip_phy_typec.h |  72 ++++++++
>>   2 files changed, 259 insertions(+), 99 deletions(-)
>>   create mode 100644 include/soc/rockchip/rockchip_phy_typec.h
>>
>> diff --git a/drivers/phy/rockchip/phy-rockchip-typec.c b/drivers/phy/rockchip/phy-rockchip-typec.c
>> index 76a4b58..831a93b 100644
>> --- a/drivers/phy/rockchip/phy-rockchip-typec.c
>> +++ b/drivers/phy/rockchip/phy-rockchip-typec.c
>> @@ -63,6 +63,7 @@
>>
>>   #include <linux/mfd/syscon.h>
>>   #include <linux/phy/phy.h>
>> +#include <soc/rockchip/rockchip_phy_typec.h>
>>
>>   #define CMN_SSM_BANDGAP                        (0x21 << 2)
>>   #define CMN_SSM_BIAS                   (0x22 << 2)
>> @@ -323,23 +324,31 @@
>>    * clock 0: PLL 0 div 1
>>    * clock 1: PLL 1 div 2
>>    */
>> -#define CLK_PLL_CONFIG                 0X30
>> +#define CLK_PLL1_DIV1                  0x20
>> +#define CLK_PLL1_DIV2                  0x30
>>   #define CLK_PLL_MASK                   0x33
>>
>>   #define CMN_READY                      BIT(0)
>>
>> +#define DP_PLL_CLOCK_ENABLE_ACK                BIT(3)
>>   #define DP_PLL_CLOCK_ENABLE            BIT(2)
>> +#define DP_PLL_ENABLE_ACK              BIT(1)
>>   #define DP_PLL_ENABLE                  BIT(0)
>>   #define DP_PLL_DATA_RATE_RBR           ((2 << 12) | (4 << 8))
>>   #define DP_PLL_DATA_RATE_HBR           ((2 << 12) | (4 << 8))
>>   #define DP_PLL_DATA_RATE_HBR2          ((1 << 12) | (2 << 8))
>> +#define DP_PLL_DATA_RATE_MASK          0xff00
>>
>> -#define DP_MODE_A0                     BIT(4)
>> -#define DP_MODE_A2                     BIT(6)
>> -#define DP_MODE_ENTER_A0               0xc101
>> -#define DP_MODE_ENTER_A2               0xc104
>> +#define DP_MODE_MASK                   0xf
>> +#define DP_MODE_ENTER_A0               BIT(0)
>> +#define DP_MODE_ENTER_A2               BIT(2)
>> +#define DP_MODE_ENTER_A3               BIT(3)
>> +#define DP_MODE_A0_ACK                 BIT(4)
>> +#define DP_MODE_A2_ACK                 BIT(6)
>> +#define DP_MODE_A3_ACK                 BIT(7)
>> +#define DP_LINK_RESET_DEASSERTED       BIT(8)
>>
>> -#define PHY_MODE_SET_TIMEOUT           100000
>> +#define PHY_MODE_SET_TIMEOUT           1000000
>>
> Why do you need to increase this timeout? Is because the software link
> training timed out using the old value?
That for debug, will fix it in next version.
>
>
>>   #define PIN_ASSIGN_C_E                 0x51d9
>>   #define PIN_ASSIGN_D_F                 0x5100
>> @@ -349,51 +358,7 @@
>>   #define MODE_DFP_USB                   BIT(1)
>>   #define MODE_DFP_DP                    BIT(2)
>>
>> -struct usb3phy_reg {
>> -       u32 offset;
>> -       u32 enable_bit;
>> -       u32 write_enable;
>> -};
>> -
>> -/**
>> - * struct rockchip_usb3phy_port_cfg: usb3-phy port configuration.
>> - * @reg: the base address for usb3-phy config.
>> - * @typec_conn_dir: the register of type-c connector direction.
>> - * @usb3tousb2_en: the register of type-c force usb2 to usb2 enable.
>> - * @external_psm: the register of type-c phy external psm clock.
>> - * @pipe_status: the register of type-c phy pipe status.
>> - * @usb3_host_disable: the register of type-c usb3 host disable.
>> - * @usb3_host_port: the register of type-c usb3 host port.
>> - * @uphy_dp_sel: the register of type-c phy DP select control.
>> - */
>> -struct rockchip_usb3phy_port_cfg {
>> -       unsigned int reg;
>> -       struct usb3phy_reg typec_conn_dir;
>> -       struct usb3phy_reg usb3tousb2_en;
>> -       struct usb3phy_reg external_psm;
>> -       struct usb3phy_reg pipe_status;
>> -       struct usb3phy_reg usb3_host_disable;
>> -       struct usb3phy_reg usb3_host_port;
>> -       struct usb3phy_reg uphy_dp_sel;
>> -};
>> -
>> -struct rockchip_typec_phy {
>> -       struct device *dev;
>> -       void __iomem *base;
>> -       struct extcon_dev *extcon;
>> -       struct regmap *grf_regs;
>> -       struct clk *clk_core;
>> -       struct clk *clk_ref;
>> -       struct reset_control *uphy_rst;
>> -       struct reset_control *pipe_rst;
>> -       struct reset_control *tcphy_rst;
>> -       const struct rockchip_usb3phy_port_cfg *port_cfgs;
>> -       /* mutex to protect access to individual PHYs */
>> -       struct mutex lock;
>> -
>> -       bool flip;
>> -       u8 mode;
>> -};
>> +#define DEFAULT_RATE                   162000
>>
> DEFAULT_RATE seems a very common name for me, maybe add a prefix?
Okay, will fix it.
>
>
>>   struct phy_reg {
>>          u16 value;
>> @@ -417,15 +382,15 @@ struct phy_reg usb3_pll_cfg[] = {
>>          { 0x8,          CMN_DIAG_PLL0_LF_PROG },
>>   };
>>
>> -struct phy_reg dp_pll_cfg[] = {
>> +struct phy_reg dp_pll_rbr_cfg[] = {
>>          { 0xf0,         CMN_PLL1_VCOCAL_INIT },
>>          { 0x18,         CMN_PLL1_VCOCAL_ITER },
>>          { 0x30b9,       CMN_PLL1_VCOCAL_START },
>> -       { 0x21c,        CMN_PLL1_INTDIV },
>> +       { 0x87,         CMN_PLL1_INTDIV },
>>          { 0,            CMN_PLL1_FRACDIV },
>> -       { 0x5,          CMN_PLL1_HIGH_THR },
>> -       { 0x35,         CMN_PLL1_SS_CTRL1 },
>> -       { 0x7f1e,       CMN_PLL1_SS_CTRL2 },
>> +       { 0x22,         CMN_PLL1_HIGH_THR },
>> +       { 0x8000,       CMN_PLL1_SS_CTRL1 },
>> +       { 0,            CMN_PLL1_SS_CTRL2 },
>>          { 0x20,         CMN_PLL1_DSM_DIAG },
>>          { 0,            CMN_PLLSM1_USER_DEF_CTRL },
>>          { 0,            CMN_DIAG_PLL1_OVRD },
>> @@ -436,9 +401,52 @@ struct phy_reg dp_pll_cfg[] = {
>>          { 0x8,          CMN_DIAG_PLL1_LF_PROG },
>>          { 0x100,        CMN_DIAG_PLL1_PTATIS_TUNE1 },
>>          { 0x7,          CMN_DIAG_PLL1_PTATIS_TUNE2 },
>> -       { 0x4,          CMN_DIAG_PLL1_INCLK_CTRL },
>> +       { 0x1,          CMN_DIAG_PLL1_INCLK_CTRL },
>> +};
>> +
>> +struct phy_reg dp_pll_hbr_cfg[] = {
>> +       { 0xf0,         CMN_PLL1_VCOCAL_INIT },
>> +       { 0x18,         CMN_PLL1_VCOCAL_ITER },
>> +       { 0x30b4,       CMN_PLL1_VCOCAL_START },
>> +       { 0xe1,         CMN_PLL1_INTDIV },
>> +       { 0,            CMN_PLL1_FRACDIV },
>> +       { 0x5,          CMN_PLL1_HIGH_THR },
>> +       { 0x8000,       CMN_PLL1_SS_CTRL1 },
>> +       { 0,            CMN_PLL1_SS_CTRL2 },
>> +       { 0x20,         CMN_PLL1_DSM_DIAG },
>> +       { 0x1000,       CMN_PLLSM1_USER_DEF_CTRL },
>> +       { 0,            CMN_DIAG_PLL1_OVRD },
>> +       { 0,            CMN_DIAG_PLL1_FBH_OVRD },
>> +       { 0,            CMN_DIAG_PLL1_FBL_OVRD },
>> +       { 0x7,          CMN_DIAG_PLL1_V2I_TUNE },
>> +       { 0x45,         CMN_DIAG_PLL1_CP_TUNE },
>> +       { 0x8,          CMN_DIAG_PLL1_LF_PROG },
>> +       { 0x1,          CMN_DIAG_PLL1_PTATIS_TUNE1 },
>> +       { 0x1,          CMN_DIAG_PLL1_PTATIS_TUNE2 },
>> +       { 0x1,          CMN_DIAG_PLL1_INCLK_CTRL },
>>   };
>>
>> +struct phy_reg dp_pll_hbr2_cfg[] = {
>> +       { 0xf0,         CMN_PLL1_VCOCAL_INIT },
>> +       { 0x18,         CMN_PLL1_VCOCAL_ITER },
>> +       { 0x30b4,       CMN_PLL1_VCOCAL_START },
>> +       { 0xe1,         CMN_PLL1_INTDIV },
>> +       { 0,            CMN_PLL1_FRACDIV },
>> +       { 0x5,          CMN_PLL1_HIGH_THR },
>> +       { 0x8000,       CMN_PLL1_SS_CTRL1 },
>> +       { 0,            CMN_PLL1_SS_CTRL2 },
>> +       { 0x20,         CMN_PLL1_DSM_DIAG },
>> +       { 0x1000,       CMN_PLLSM1_USER_DEF_CTRL },
>> +       { 0,            CMN_DIAG_PLL1_OVRD },
>> +       { 0,            CMN_DIAG_PLL1_FBH_OVRD },
>> +       { 0,            CMN_DIAG_PLL1_FBL_OVRD },
>> +       { 0x7,          CMN_DIAG_PLL1_V2I_TUNE },
>> +       { 0x45,         CMN_DIAG_PLL1_CP_TUNE },
>> +       { 0x8,          CMN_DIAG_PLL1_LF_PROG },
>> +       { 0x1,          CMN_DIAG_PLL1_PTATIS_TUNE1 },
>> +       { 0x1,          CMN_DIAG_PLL1_PTATIS_TUNE2 },
>> +       { 0x1,          CMN_DIAG_PLL1_INCLK_CTRL },
>> +};
>>   static const struct rockchip_usb3phy_port_cfg rk3399_usb3phy_port_cfgs[] = {
>>          {
>>                  .reg = 0xff7c0000,
>> @@ -484,7 +492,7 @@ static void tcphy_cfg_24m(struct rockchip_typec_phy *tcphy)
>>
>>          rdata = readl(tcphy->base + CMN_DIAG_HSCLK_SEL);
>>          rdata &= ~CLK_PLL_MASK;
>> -       rdata |= CLK_PLL_CONFIG;
>> +       rdata |= CLK_PLL1_DIV2;
>>          writel(rdata, tcphy->base + CMN_DIAG_HSCLK_SEL);
>>   }
>>
>> @@ -498,17 +506,44 @@ static void tcphy_cfg_usb3_pll(struct rockchip_typec_phy *tcphy)
>>                         tcphy->base + usb3_pll_cfg[i].addr);
>>   }
>>
>> -static void tcphy_cfg_dp_pll(struct rockchip_typec_phy *tcphy)
>> +static void tcphy_cfg_dp_pll(struct rockchip_typec_phy *tcphy, int link_rate)
>>   {
>> -       u32 i;
>> +       struct phy_reg *phy_cfg;
>> +       u32 clk_ctrl;
>> +       u32 i, cfg_size, hsclk_sel;
>> +
>> +       hsclk_sel = readl(tcphy->base + CMN_DIAG_HSCLK_SEL);
>> +       hsclk_sel &= ~CLK_PLL_MASK;
>> +
>> +       switch (link_rate) {
>> +       case 162000:
>> +               clk_ctrl = DP_PLL_DATA_RATE_RBR;
>> +               hsclk_sel |= CLK_PLL1_DIV2;
>> +               phy_cfg = dp_pll_rbr_cfg;
>> +               cfg_size = ARRAY_SIZE(dp_pll_rbr_cfg);
>> +               break;
>> +       case 270000:
>> +               clk_ctrl = DP_PLL_DATA_RATE_HBR;
>> +               hsclk_sel |= CLK_PLL1_DIV2;
>> +               phy_cfg = dp_pll_hbr_cfg;
>> +               cfg_size = ARRAY_SIZE(dp_pll_hbr_cfg);
>> +               break;
>> +       case 540000:
>> +               clk_ctrl = DP_PLL_DATA_RATE_HBR2;
>> +               hsclk_sel |= CLK_PLL1_DIV1;
>> +               phy_cfg = dp_pll_hbr2_cfg;
>> +               cfg_size = ARRAY_SIZE(dp_pll_hbr2_cfg);
>> +               break;
>> +       }
>> +
>> +       clk_ctrl |= DP_PLL_CLOCK_ENABLE | DP_PLL_ENABLE;
>> +       writel(clk_ctrl, tcphy->base + DP_CLK_CTL);
>>
>> -       /* set the default mode to RBR */
>> -       writel(DP_PLL_CLOCK_ENABLE | DP_PLL_ENABLE | DP_PLL_DATA_RATE_RBR,
>> -              tcphy->base + DP_CLK_CTL);
>> +       writel(hsclk_sel, tcphy->base + CMN_DIAG_HSCLK_SEL);
>>
>>          /* load the configuration of PLL1 */
>> -       for (i = 0; i < ARRAY_SIZE(dp_pll_cfg); i++)
>> -               writel(dp_pll_cfg[i].value, tcphy->base + dp_pll_cfg[i].addr);
>> +       for (i = 0; i < cfg_size; i++)
>> +               writel(phy_cfg[i].value, tcphy->base + phy_cfg[i].addr);
>>   }
>>
>>   static void tcphy_tx_usb3_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
>> @@ -535,9 +570,10 @@ static void tcphy_rx_usb3_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
>>          writel(0xfb, tcphy->base + XCVR_DIAG_BIDI_CTRL(lane));
>>   }
>>
>> -static void tcphy_dp_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
>> +static void tcphy_dp_cfg_lane(struct rockchip_typec_phy *tcphy, int link_rate,
>> +                             u8 swing, u8 pre_emp, u32 lane)
>>   {
>> -       u16 rdata;
>> +       u16 val;
> >From what I see you are only renaming rdata to val, there is any reason?
not reason, just rename a new variable :)
>
>>          writel(0xbefc, tcphy->base + XCVR_PSM_RCTRL(lane));
>>          writel(0x6799, tcphy->base + TX_PSC_A0(lane));
>> @@ -545,25 +581,31 @@ static void tcphy_dp_cfg_lane(struct rockchip_typec_phy *tcphy, u32 lane)
>>          writel(0x98, tcphy->base + TX_PSC_A2(lane));
>>          writel(0x98, tcphy->base + TX_PSC_A3(lane));
>>
>> -       writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_000(lane));
>> -       writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_001(lane));
>> -       writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_010(lane));
>> -       writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_011(lane));
>> -       writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_100(lane));
>> -       writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_101(lane));
>> -       writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_110(lane));
>> -       writel(0, tcphy->base + TX_TXCC_MGNFS_MULT_111(lane));
>> -       writel(0, tcphy->base + TX_TXCC_CPOST_MULT_10(lane));
>> -       writel(0, tcphy->base + TX_TXCC_CPOST_MULT_01(lane));
>> -       writel(0, tcphy->base + TX_TXCC_CPOST_MULT_00(lane));
>> -       writel(0, tcphy->base + TX_TXCC_CPOST_MULT_11(lane));
>> -
>> -       writel(0x128, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane));
>> -       writel(0x400, tcphy->base + TX_DIAG_TX_DRV(lane));
>> -
>> -       rdata = readl(tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
>> -       rdata = (rdata & 0x8fff) | 0x6000;
>> -       writel(rdata, tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
>> +       writel(tcphy->config[swing][pre_emp].swing,
>> +              tcphy->base + TX_TXCC_MGNFS_MULT_000(lane));
>> +       writel(tcphy->config[swing][pre_emp].pe,
>> +              tcphy->base + TX_TXCC_CPOST_MULT_00(lane));
>> +
>> +       if (swing == 2 && pre_emp == 0 && link_rate != 540000) {
>> +               writel(0x700, tcphy->base + TX_DIAG_TX_DRV(lane));
>> +               writel(0x13c, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane));
>> +       } else {
>> +               writel(0x128, tcphy->base + TX_TXCC_CAL_SCLR_MULT(lane));
>> +               writel(0x0400, tcphy->base + TX_DIAG_TX_DRV(lane));
>> +       }
>> +
>> +       val = readl(tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
>> +       val = val & 0x8fff;
>> +       switch (link_rate) {
>> +       case 162000:
>> +       case 270000:
>> +               val |= (6 << 12);
>> +               break;
>> +       case 540000:
>> +               val |= (4 << 12);
>> +               break;
>> +       }
>> +       writel(val, tcphy->base + XCVR_DIAG_PLLDRC_CTRL(lane));
>>   }
>>
>>   static inline int property_enable(struct rockchip_typec_phy *tcphy,
>> @@ -754,30 +796,33 @@ static int tcphy_phy_init(struct rockchip_typec_phy *tcphy, u8 mode)
>>          tcphy_cfg_24m(tcphy);
>>
>>          if (mode == MODE_DFP_DP) {
>> -               tcphy_cfg_dp_pll(tcphy);
>> +               tcphy_cfg_dp_pll(tcphy, DEFAULT_RATE);
>>                  for (i = 0; i < 4; i++)
>> -                       tcphy_dp_cfg_lane(tcphy, i);
>> +                       tcphy_dp_cfg_lane(tcphy, DEFAULT_RATE, 0, 0, i);
>>
>>                  writel(PIN_ASSIGN_C_E, tcphy->base + PMA_LANE_CFG);
>>          } else {
>>                  tcphy_cfg_usb3_pll(tcphy);
>> -               tcphy_cfg_dp_pll(tcphy);
>> +               tcphy_cfg_dp_pll(tcphy, DEFAULT_RATE);
>>                  if (tcphy->flip) {
>>                          tcphy_tx_usb3_cfg_lane(tcphy, 3);
>>                          tcphy_rx_usb3_cfg_lane(tcphy, 2);
>> -                       tcphy_dp_cfg_lane(tcphy, 0);
>> -                       tcphy_dp_cfg_lane(tcphy, 1);
>> +                       tcphy_dp_cfg_lane(tcphy, DEFAULT_RATE, 0, 0, 0);
>> +                       tcphy_dp_cfg_lane(tcphy, DEFAULT_RATE, 0, 0, 1);
>>                  } else {
>>                          tcphy_tx_usb3_cfg_lane(tcphy, 0);
>>                          tcphy_rx_usb3_cfg_lane(tcphy, 1);
>> -                       tcphy_dp_cfg_lane(tcphy, 2);
>> -                       tcphy_dp_cfg_lane(tcphy, 3);
>> +                       tcphy_dp_cfg_lane(tcphy, DEFAULT_RATE, 0, 0, 2);
>> +                       tcphy_dp_cfg_lane(tcphy, DEFAULT_RATE, 0, 0, 3);
>>                  }
>>
>>                  writel(PIN_ASSIGN_D_F, tcphy->base + PMA_LANE_CFG);
>>          }
>>
>> -       writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
>> +       val = readl(tcphy->base + DP_MODE_CTL);
>> +       val &= ~DP_MODE_MASK;
>> +       val |= DP_MODE_ENTER_A2 | DP_LINK_RESET_DEASSERTED;
>> +       writel(val, tcphy->base + DP_MODE_CTL);
>>
>>          reset_control_deassert(tcphy->uphy_rst);
>>
>> @@ -990,7 +1035,7 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
>>          property_enable(tcphy, &cfg->uphy_dp_sel, 1);
>>
>>          ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
>> -                                val, val & DP_MODE_A2, 1000,
>> +                                val, val & DP_MODE_A2_ACK, 1000,
>>                                   PHY_MODE_SET_TIMEOUT);
>>          if (ret < 0) {
>>                  dev_err(tcphy->dev, "failed to wait TCPHY enter A2\n");
>> @@ -999,13 +1044,19 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
>>
>>          tcphy_dp_aux_calibration(tcphy);
>>
>> -       writel(DP_MODE_ENTER_A0, tcphy->base + DP_MODE_CTL);
>> +       /* enter A0 mode */
>> +       val = readl(tcphy->base + DP_MODE_CTL);
>> +       val &= ~DP_MODE_MASK;
>> +       val |= DP_MODE_ENTER_A0;
>> +       writel(val, tcphy->base + DP_MODE_CTL);
>>
>>          ret = readx_poll_timeout(readl, tcphy->base + DP_MODE_CTL,
>> -                                val, val & DP_MODE_A0, 1000,
>> +                                val, val & DP_MODE_A0_ACK, 1000,
>>                                   PHY_MODE_SET_TIMEOUT);
>>          if (ret < 0) {
>> -               writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
>> +               val &= ~DP_MODE_MASK;
>> +               val |= DP_MODE_ENTER_A2;
>> +               writel(val, tcphy->base + DP_MODE_CTL);
>>                  dev_err(tcphy->dev, "failed to wait TCPHY enter A0\n");
>>                  goto power_on_finish;
>>          }
>> @@ -1023,6 +1074,7 @@ static int rockchip_dp_phy_power_on(struct phy *phy)
>>   static int rockchip_dp_phy_power_off(struct phy *phy)
>>   {
>>          struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
>> +       u32 val;
>>
>>          mutex_lock(&tcphy->lock);
>>
>> @@ -1031,7 +1083,10 @@ static int rockchip_dp_phy_power_off(struct phy *phy)
>>
>>          tcphy->mode &= ~MODE_DFP_DP;
>>
>> -       writel(DP_MODE_ENTER_A2, tcphy->base + DP_MODE_CTL);
>> +       val = readl(tcphy->base + DP_MODE_CTL);
>> +       val &= ~DP_MODE_MASK;
>> +       val |= DP_MODE_ENTER_A2;
>> +       writel(val, tcphy->base + DP_MODE_CTL);
>>
>>          if (tcphy->mode == MODE_DISCONNECT)
>>                  tcphy_phy_deinit(tcphy);
>> @@ -1047,6 +1102,30 @@ static const struct phy_ops rockchip_dp_phy_ops = {
>>          .owner          = THIS_MODULE,
>>   };
>>
>> +static int type_c_dp_phy_config(struct phy *phy, int link_rate,
> s/type_c/typec/ to be coherent with the rest of the code.
>
>> +                        int lanes, u8 swing, u8 pre_emp)
>> +{
>> +       struct rockchip_typec_phy *tcphy = phy_get_drvdata(phy);
>> +       u8 i;
>> +
>> +       tcphy_cfg_dp_pll(tcphy, link_rate);
>> +
>> +       if (tcphy->mode == MODE_DFP_DP) {
>> +               for (i = 0; i < 4; i++)
>> +                       tcphy_dp_cfg_lane(tcphy, link_rate, swing, pre_emp, i);
>> +       } else {
>> +               if (tcphy->flip) {
>> +                       tcphy_dp_cfg_lane(tcphy, link_rate, swing, pre_emp, 0);
>> +                       tcphy_dp_cfg_lane(tcphy, link_rate, swing, pre_emp, 1);
>> +               } else {
>> +                       tcphy_dp_cfg_lane(tcphy, link_rate, swing, pre_emp, 2);
>> +                       tcphy_dp_cfg_lane(tcphy, link_rate, swing, pre_emp, 3);
>> +               }
>> +       }
>> +
>> +       return 0;
>> +}
>> +
>>   static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy,
>>                            struct device *dev)
>>   {
>> @@ -1087,6 +1166,14 @@ static int tcphy_parse_dt(struct rockchip_typec_phy *tcphy,
>>                  return PTR_ERR(tcphy->tcphy_rst);
>>          }
>>
>> +       /*
>> +        * check if phy_config pass from dts, if yes,
>> +        * need to use this phy config to do software training later
>> +        */
>> +       if (!of_property_read_u32_array(dev->of_node, "rockchip,phy_config",
>> +               (u32 *)tcphy->config, sizeof(tcphy->config) / sizeof(u32)))
>> +               tcphy->need_software_training = 1;
>> +
>>          return 0;
>>   }
>>
>> @@ -1171,6 +1258,7 @@ static int rockchip_typec_phy_probe(struct platform_device *pdev)
>>                  }
>>          }
>>
>> +       tcphy->typec_phy_config = type_c_dp_phy_config;
> type_c_dp_phy_config -> typec_dp_phy_config
>
>>          pm_runtime_enable(dev);
>>
>>          for_each_available_child_of_node(np, child_np) {
>> diff --git a/include/soc/rockchip/rockchip_phy_typec.h b/include/soc/rockchip/rockchip_phy_typec.h
>> new file mode 100644
>> index 0000000..e25840e
>> --- /dev/null
>> +++ b/include/soc/rockchip/rockchip_phy_typec.h
>> @@ -0,0 +1,72 @@
>> +/*
> Add the SPDX License identifier ...
>
>> + * Copyright (c) 2018, Fuzhou Rockchip Electronics Co., Ltd
>> + * Author: Lin Huang <hl at rock-chips.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify it
>> + * under the terms and conditions of the GNU General Public License,
>> + * version 2, as published by the Free Software Foundation.
>> + *
>> + * This program is distributed in the hope it will be useful, but WITHOUT
>> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
>> + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
>> + * more details.
> ... and remove the above notice.
>
>> + */
>> +#ifndef __SOC_ROCKCHIP_PHY_TYPEC_H
>> +#define __SOC_ROCKCHIP_PHY_TYPEC_H
>> +
>> +
> Remove the extra new line.
>
>> +struct usb3phy_reg {
>> +       u32 offset;
>> +       u32 enable_bit;
>> +       u32 write_enable;
>> +};
>> +
>> +/**
>> + * struct rockchip_usb3phy_port_cfg: usb3-phy port configuration.
>> + * @reg: the base address for usb3-phy config.
>> + * @typec_conn_dir: the register of type-c connector direction.
>> + * @usb3tousb2_en: the register of type-c force usb2 to usb2 enable.
>> + * @external_psm: the register of type-c phy external psm clock.
>> + * @pipe_status: the register of type-c phy pipe status.
>> + * @usb3_host_disable: the register of type-c usb3 host disable.
>> + * @usb3_host_port: the register of type-c usb3 host port.
>> + * @uphy_dp_sel: the register of type-c phy DP select control.
>> + */
>> +struct rockchip_usb3phy_port_cfg {
>> +       unsigned int reg;
>> +       struct usb3phy_reg typec_conn_dir;
>> +       struct usb3phy_reg usb3tousb2_en;
>> +       struct usb3phy_reg external_psm;
>> +       struct usb3phy_reg pipe_status;
>> +       struct usb3phy_reg usb3_host_disable;
>> +       struct usb3phy_reg usb3_host_port;
>> +       struct usb3phy_reg uphy_dp_sel;
>> +};
>> +
>> +struct phy_config {
>> +       int swing;
>> +       int pe;
>> +};
>> +
>> +struct rockchip_typec_phy {
>> +       struct device *dev;
>> +       void __iomem *base;
>> +       struct extcon_dev *extcon;
>> +       struct regmap *grf_regs;
>> +       struct clk *clk_core;
>> +       struct clk *clk_ref;
>> +       struct reset_control *uphy_rst;
>> +       struct reset_control *pipe_rst;
>> +       struct reset_control *tcphy_rst;
>> +       struct rockchip_usb3phy_port_cfg *port_cfgs;
>> +       /* mutex to protect access to individual PHYs */
>> +       struct mutex lock;
>> +       struct phy_config config[3][4];
>> +       u8 need_software_training;
>> +       bool flip;
>> +       u8 mode;
>> +       int (*typec_phy_config)(struct phy *phy, int link_rate,
>> +                               int lanes, u8 swing, u8 pre_emp);
>> +};
>> +
>> +#endif
> Best regards,
>   Enric
>
>> --
>> 2.7.4
>>
>>
>> _______________________________________________
>> Linux-rockchip mailing list
>> Linux-rockchip at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-rockchip
> _______________________________________________
> Linux-rockchip mailing list
> Linux-rockchip at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-rockchip
>
>
>





More information about the linux-arm-kernel mailing list