RE: [RESEND PATCH v10 2/2] phy: samsung-ufs: add UFS PHY driver for samsung SoC
From: Alim Akhtar
Date: Thu Jul 02 2020 - 21:27:39 EST
Hi Vinod
> -----Original Message-----
> From: Vinod Koul <vkoul@xxxxxxxxxx>
> Sent: 01 July 2020 12:23
> To: Alim Akhtar <alim.akhtar@xxxxxxxxxxx>
> Cc: robh+dt@xxxxxxxxxx; krzk@xxxxxxxxxx; kwmad.kim@xxxxxxxxxxx;
> devicetree@xxxxxxxxxxxxxxx; linux-arm-kernel@xxxxxxxxxxxxxxxxxxx; linux-
> kernel@xxxxxxxxxxxxxxx; linux-samsung-soc@xxxxxxxxxxxxxxx; kishon@xxxxxx
> Subject: Re: [RESEND PATCH v10 2/2] phy: samsung-ufs: add UFS PHY driver
for
> samsung SoC
>
> Hi Alim,
>
> On 25-06-20, 05:26, Alim Akhtar wrote:
>
> > +int samsung_ufs_phy_wait_for_lock_acq(struct phy *phy)
>
> static ?
>
Sure, already got warning email from Kobot. Will fix this.
> > +{
> > + struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy);
> > + const unsigned int timeout_us = 100000;
> > + const unsigned int sleep_us = 10;
> > + u32 val;
> > + int err;
> > +
> > + err = readl_poll_timeout(
> > + ufs_phy->reg_pma +
> PHY_APB_ADDR(PHY_PLL_LOCK_STATUS),
> > + val, (val & PHY_PLL_LOCK_BIT), sleep_us,
timeout_us);
> > + if (err) {
> > + dev_err(ufs_phy->dev,
> > + "failed to get phy pll lock acquisition %d\n", err);
> > + goto out;
> > + }
> > +
> > + err = readl_poll_timeout(
> > + ufs_phy->reg_pma +
> PHY_APB_ADDR(PHY_CDR_LOCK_STATUS),
> > + val, (val & PHY_CDR_LOCK_BIT), sleep_us,
timeout_us);
> > + if (err) {
> > + dev_err(ufs_phy->dev,
> > + "failed to get phy cdr lock acquisition %d\n", err);
> > + goto out;
>
> this one can be dropped
>
Sure, will update.
> > + }
> > +
> > +out:
> > + return err;
> > +}
> > +
> > +int samsung_ufs_phy_calibrate(struct phy *phy)
>
> static?
>
Will fix
> > +{
> > + struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy);
> > + struct samsung_ufs_phy_cfg **cfgs = ufs_phy->cfg;
> > + const struct samsung_ufs_phy_cfg *cfg;
> > + int i;
> > + int err = 0;
>
> err before i would make it look better
>
sure
> > +
> > + if (unlikely(ufs_phy->ufs_phy_state < CFG_PRE_INIT ||
> > + ufs_phy->ufs_phy_state >= CFG_TAG_MAX)) {
> > + dev_err(ufs_phy->dev, "invalid phy config index %d\n",
> > + ufs_phy-
> >ufs_phy_state);
>
> single line now?
>
Yes,
> > + return -EINVAL;
> > + }
> > +
> > + if (ufs_phy->is_pre_init)
> > + ufs_phy->is_pre_init = false;
>
> that sounds bit strange, you clear it if set? Can you explain what is
going on
> here, and add comments
>
Hmm, yes right, this is not needed, let me change this and will add a
comment.
The idea here is, before exiting phy calibration in one state, change the
state to next state,
So that when next time calibrate() is called, it will do the phy settings
for the next stage.
> > +static int samsung_ufs_phy_symbol_clk_init(struct samsung_ufs_phy
> > +*phy) {
> > + int ret = 0;
>
> superfluous init
>
ok
> > +
> > + phy->tx0_symbol_clk = devm_clk_get(phy->dev, "tx0_symbol_clk");
> > + if (IS_ERR(phy->tx0_symbol_clk)) {
> > + dev_err(phy->dev, "failed to get tx0_symbol_clk clock\n");
> > + goto out;
> > + }
> > +
> > + phy->rx0_symbol_clk = devm_clk_get(phy->dev, "rx0_symbol_clk");
> > + if (IS_ERR(phy->rx0_symbol_clk)) {
> > + dev_err(phy->dev, "failed to get rx0_symbol_clk clock\n");
> > + goto out;
> > + }
> > +
> > + phy->rx1_symbol_clk = devm_clk_get(phy->dev, "rx1_symbol_clk");
> > + if (IS_ERR(phy->rx0_symbol_clk)) {
> > + dev_err(phy->dev, "failed to get rx1_symbol_clk clock\n");
> > + goto out;
> > + }
> > +
> > + ret = clk_prepare_enable(phy->tx0_symbol_clk);
> > + if (ret) {
> > + dev_err(phy->dev, "%s: tx0_symbol_clk enable failed %d\n",
> > + __func__, ret);
> > + goto out;
> > + }
> > + ret = clk_prepare_enable(phy->rx0_symbol_clk);
> > + if (ret) {
> > + dev_err(phy->dev, "%s: rx0_symbol_clk enable failed %d\n",
> > + __func__, ret);
>
> so we keep tx0_symbol_clk enabled when bailing out?
>
Will add a clk_disable_unprepare()
> > + goto out;
> > + }
> > + ret = clk_prepare_enable(phy->rx1_symbol_clk);
> > + if (ret) {
> > + dev_err(phy->dev, "%s: rx1_symbol_clk enable failed %d\n",
> > + __func__, ret);
>
> here as well
>
Will add a clk_disable_unprepare()
> > +static int samsung_ufs_phy_init(struct phy *phy) {
> > + struct samsung_ufs_phy *_phy = get_samsung_ufs_phy(phy);
> > + int ret;
> > +
> > + _phy->lane_cnt = phy->attrs.bus_width;
> > + _phy->ufs_phy_state = CFG_PRE_INIT;
> > +
> > + /**
> > + * In ufs, PHY need to be calibrated at different stages / state
> > + * mainly before Linkstartup, after Linkstartup, before power
> > + * mode change and after power mode change.
> > + * Below state machine initialize the initial state to handle
> > + * PHY calibration at various stages of UFS initialization and power
> > + * mode changes
> > + */
> > + _phy->is_pre_init = true;
> > + _phy->is_post_init = false;
> > + _phy->is_pre_pmc = false;
> > + _phy->is_post_pmc = false;
>
> hmm why not have phy_state and assign that
> pre_init/post_init/pre_pmc/post_pmc states?
>
These are not needed, ufs_phy_state is enough to handle various stages.
Thanks, will remove and simplify this logic.
> > +static int samsung_ufs_phy_set_mode(struct phy *generic_phy,
> > + enum phy_mode mode, int submode)
>
> pls align this to preceding line opening brace (tip: checkpatch with
--strict can
> tell you about these)
Sure, will fix this, thanks for the tip.
> --
> ~Vinod