Message ID | 20210908182628.28364-4-sjakhade@cadence.com |
---|---|
State | New |
Headers | show |
Series | PHY: Add support to output derived and received reference clock from Torrent | expand |
Hi Swapnil, On 08/09/21 11:56 pm, Swapnil Jakhade wrote: > Update the reference clock driver implementation where cmn_refclk_<p/m> > is configured to output the reference clock. cmn_refclk_p/m will output > either derived or received reference clock based on the selection. So, > all these clocks should be modelled separately. Model the derived > reference clock here as a first step to support reference clock driver. > Will AM64 work after this patch? Since you are removing bunch of configurations here, would it affect git bisectability? Thanks Kishon > Signed-off-by: Swapnil Jakhade <sjakhade@cadence.com> > --- > drivers/phy/cadence/phy-cadence-torrent.c | 78 +++++++++-------------- > 1 file changed, 31 insertions(+), 47 deletions(-) > > diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c > index ecb1aa883c05..6dceb12e88c4 100644 > --- a/drivers/phy/cadence/phy-cadence-torrent.c > +++ b/drivers/phy/cadence/phy-cadence-torrent.c > @@ -235,10 +235,11 @@ > #define PHY_PMA_CMN_CTRL2 0x0001U > #define PHY_PMA_PLL_RAW_CTRL 0x0003U > > -#define CDNS_TORRENT_OUTPUT_CLOCKS 1 > +#define CDNS_TORRENT_OUTPUT_CLOCKS 2 > > static const char * const clk_names[] = { > [CDNS_TORRENT_REFCLK_DRIVER] = "refclk-driver", > + [CDNS_TORRENT_DERIVED_REFCLK] = "refclk-der", > }; > > static const struct reg_field phy_pll_cfg = > @@ -261,23 +262,8 @@ static const struct reg_field phy_pcs_iso_link_ctrl_1 = > > static const struct reg_field phy_pipe_cmn_ctrl1_0 = REG_FIELD(PHY_PIPE_CMN_CTRL1, 0, 0); > > -#define REFCLK_OUT_NUM_CMN_CONFIG 5 > - > -enum cdns_torrent_refclk_out_cmn { > - CMN_CDIAG_REFCLK_OVRD_4, > - CMN_CDIAG_REFCLK_DRV0_CTRL_1, > - CMN_CDIAG_REFCLK_DRV0_CTRL_4, > - CMN_CDIAG_REFCLK_DRV0_CTRL_5, > - CMN_CDIAG_REFCLK_DRV0_CTRL_6, > -}; > - > -static const struct reg_field refclk_out_cmn_cfg[] = { > - [CMN_CDIAG_REFCLK_OVRD_4] = REG_FIELD(CMN_CDIAG_REFCLK_OVRD, 4, 4), > - [CMN_CDIAG_REFCLK_DRV0_CTRL_1] = REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 1, 1), > - [CMN_CDIAG_REFCLK_DRV0_CTRL_4] = REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 4, 4), > - [CMN_CDIAG_REFCLK_DRV0_CTRL_5] = REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 5, 5), > - [CMN_CDIAG_REFCLK_DRV0_CTRL_6] = REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 6, 6), > -}; > +static const struct reg_field cmn_cdiag_refclk_ovrd_4 = > + REG_FIELD(CMN_CDIAG_REFCLK_OVRD, 4, 4); > > enum cdns_torrent_phy_type { > TYPE_NONE, > @@ -330,6 +316,8 @@ struct cdns_torrent_phy { > struct regmap *regmap_phy_pcs_lane_cdb[MAX_NUM_LANES]; > struct regmap *regmap_dptx_phy_reg; > struct regmap_field *phy_pll_cfg; > + struct regmap_field *phy_pipe_cmn_ctrl1_0; > + struct regmap_field *cmn_cdiag_refclk_ovrd_4; > struct regmap_field *phy_pma_cmn_ctrl_1; > struct regmap_field *phy_pma_cmn_ctrl_2; > struct regmap_field *phy_pma_pll_raw_ctrl; > @@ -348,7 +336,7 @@ enum phy_powerstate { > struct cdns_torrent_derived_refclk { > struct clk_hw hw; > struct regmap_field *phy_pipe_cmn_ctrl1_0; > - struct regmap_field *cmn_fields[REFCLK_OUT_NUM_CMN_CONFIG]; > + struct regmap_field *cmn_cdiag_refclk_ovrd_4; > struct clk_init_data clk_data; > }; > > @@ -1618,11 +1606,7 @@ static int cdns_torrent_derived_refclk_enable(struct clk_hw *hw) > { > struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw); > > - regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_6], 0); > - regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_4], 1); > - regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_5], 1); > - regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_1], 0); > - regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_OVRD_4], 1); > + regmap_field_write(derived_refclk->cmn_cdiag_refclk_ovrd_4, 1); > regmap_field_write(derived_refclk->phy_pipe_cmn_ctrl1_0, 1); > > return 0; > @@ -1633,6 +1617,7 @@ static void cdns_torrent_derived_refclk_disable(struct clk_hw *hw) > struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw); > > regmap_field_write(derived_refclk->phy_pipe_cmn_ctrl1_0, 0); > + regmap_field_write(derived_refclk->cmn_cdiag_refclk_ovrd_4, 0); > } > > static int cdns_torrent_derived_refclk_is_enabled(struct clk_hw *hw) > @@ -1640,7 +1625,7 @@ static int cdns_torrent_derived_refclk_is_enabled(struct clk_hw *hw) > struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw); > int val; > > - regmap_field_read(derived_refclk->phy_pipe_cmn_ctrl1_0, &val); > + regmap_field_read(derived_refclk->cmn_cdiag_refclk_ovrd_4, &val); > > return !!val; > } > @@ -1655,21 +1640,19 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph > { > struct cdns_torrent_derived_refclk *derived_refclk; > struct device *dev = cdns_phy->dev; > - struct regmap_field *field; > struct clk_init_data *init; > const char *parent_name; > - struct regmap *regmap; > char clk_name[100]; > struct clk_hw *hw; > struct clk *clk; > - int i, ret; > + int ret; > > derived_refclk = devm_kzalloc(dev, sizeof(*derived_refclk), GFP_KERNEL); > if (!derived_refclk) > return -ENOMEM; > > snprintf(clk_name, sizeof(clk_name), "%s_%s", dev_name(dev), > - clk_names[CDNS_TORRENT_REFCLK_DRIVER]); > + clk_names[CDNS_TORRENT_DERIVED_REFCLK]); > > clk = devm_clk_get_optional(dev, "phy_en_refclk"); > if (IS_ERR(clk)) { > @@ -1688,23 +1671,8 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph > init->flags = 0; > init->name = clk_name; > > - regmap = cdns_phy->regmap_phy_pcs_common_cdb; > - field = devm_regmap_field_alloc(dev, regmap, phy_pipe_cmn_ctrl1_0); > - if (IS_ERR(field)) { > - dev_err(dev, "phy_pipe_cmn_ctrl1_0 reg field init failed\n"); > - return PTR_ERR(field); > - } > - derived_refclk->phy_pipe_cmn_ctrl1_0 = field; > - > - regmap = cdns_phy->regmap_common_cdb; > - for (i = 0; i < REFCLK_OUT_NUM_CMN_CONFIG; i++) { > - field = devm_regmap_field_alloc(dev, regmap, refclk_out_cmn_cfg[i]); > - if (IS_ERR(field)) { > - dev_err(dev, "CMN reg field init failed\n"); > - return PTR_ERR(field); > - } > - derived_refclk->cmn_fields[i] = field; > - } > + derived_refclk->phy_pipe_cmn_ctrl1_0 = cdns_phy->phy_pipe_cmn_ctrl1_0; > + derived_refclk->cmn_cdiag_refclk_ovrd_4 = cdns_phy->cmn_cdiag_refclk_ovrd_4; > > derived_refclk->hw.init = init; > > @@ -1713,7 +1681,7 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph > if (ret) > return ret; > > - cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER] = hw; > + cdns_phy->clk_hw_data->hws[CDNS_TORRENT_DERIVED_REFCLK] = hw; > > return 0; > } > @@ -1768,6 +1736,22 @@ static int cdns_torrent_regfield_init(struct cdns_torrent_phy *cdns_phy) > } > cdns_phy->phy_pll_cfg = field; > > + regmap = cdns_phy->regmap_phy_pcs_common_cdb; > + field = devm_regmap_field_alloc(dev, regmap, phy_pipe_cmn_ctrl1_0); > + if (IS_ERR(field)) { > + dev_err(dev, "phy_pipe_cmn_ctrl1_0 reg field init failed\n"); > + return PTR_ERR(field); > + } > + cdns_phy->phy_pipe_cmn_ctrl1_0 = field; > + > + regmap = cdns_phy->regmap_common_cdb; > + field = devm_regmap_field_alloc(dev, regmap, cmn_cdiag_refclk_ovrd_4); > + if (IS_ERR(field)) { > + dev_err(dev, "cmn_cdiag_refclk_ovrd_4 reg field init failed\n"); > + return PTR_ERR(field); > + } > + cdns_phy->cmn_cdiag_refclk_ovrd_4 = field; > + > regmap = cdns_phy->regmap_phy_pma_common_cdb; > field = devm_regmap_field_alloc(dev, regmap, phy_pma_cmn_ctrl_1); > if (IS_ERR(field)) { >
diff --git a/drivers/phy/cadence/phy-cadence-torrent.c b/drivers/phy/cadence/phy-cadence-torrent.c index ecb1aa883c05..6dceb12e88c4 100644 --- a/drivers/phy/cadence/phy-cadence-torrent.c +++ b/drivers/phy/cadence/phy-cadence-torrent.c @@ -235,10 +235,11 @@ #define PHY_PMA_CMN_CTRL2 0x0001U #define PHY_PMA_PLL_RAW_CTRL 0x0003U -#define CDNS_TORRENT_OUTPUT_CLOCKS 1 +#define CDNS_TORRENT_OUTPUT_CLOCKS 2 static const char * const clk_names[] = { [CDNS_TORRENT_REFCLK_DRIVER] = "refclk-driver", + [CDNS_TORRENT_DERIVED_REFCLK] = "refclk-der", }; static const struct reg_field phy_pll_cfg = @@ -261,23 +262,8 @@ static const struct reg_field phy_pcs_iso_link_ctrl_1 = static const struct reg_field phy_pipe_cmn_ctrl1_0 = REG_FIELD(PHY_PIPE_CMN_CTRL1, 0, 0); -#define REFCLK_OUT_NUM_CMN_CONFIG 5 - -enum cdns_torrent_refclk_out_cmn { - CMN_CDIAG_REFCLK_OVRD_4, - CMN_CDIAG_REFCLK_DRV0_CTRL_1, - CMN_CDIAG_REFCLK_DRV0_CTRL_4, - CMN_CDIAG_REFCLK_DRV0_CTRL_5, - CMN_CDIAG_REFCLK_DRV0_CTRL_6, -}; - -static const struct reg_field refclk_out_cmn_cfg[] = { - [CMN_CDIAG_REFCLK_OVRD_4] = REG_FIELD(CMN_CDIAG_REFCLK_OVRD, 4, 4), - [CMN_CDIAG_REFCLK_DRV0_CTRL_1] = REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 1, 1), - [CMN_CDIAG_REFCLK_DRV0_CTRL_4] = REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 4, 4), - [CMN_CDIAG_REFCLK_DRV0_CTRL_5] = REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 5, 5), - [CMN_CDIAG_REFCLK_DRV0_CTRL_6] = REG_FIELD(CMN_CDIAG_REFCLK_DRV0_CTRL, 6, 6), -}; +static const struct reg_field cmn_cdiag_refclk_ovrd_4 = + REG_FIELD(CMN_CDIAG_REFCLK_OVRD, 4, 4); enum cdns_torrent_phy_type { TYPE_NONE, @@ -330,6 +316,8 @@ struct cdns_torrent_phy { struct regmap *regmap_phy_pcs_lane_cdb[MAX_NUM_LANES]; struct regmap *regmap_dptx_phy_reg; struct regmap_field *phy_pll_cfg; + struct regmap_field *phy_pipe_cmn_ctrl1_0; + struct regmap_field *cmn_cdiag_refclk_ovrd_4; struct regmap_field *phy_pma_cmn_ctrl_1; struct regmap_field *phy_pma_cmn_ctrl_2; struct regmap_field *phy_pma_pll_raw_ctrl; @@ -348,7 +336,7 @@ enum phy_powerstate { struct cdns_torrent_derived_refclk { struct clk_hw hw; struct regmap_field *phy_pipe_cmn_ctrl1_0; - struct regmap_field *cmn_fields[REFCLK_OUT_NUM_CMN_CONFIG]; + struct regmap_field *cmn_cdiag_refclk_ovrd_4; struct clk_init_data clk_data; }; @@ -1618,11 +1606,7 @@ static int cdns_torrent_derived_refclk_enable(struct clk_hw *hw) { struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw); - regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_6], 0); - regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_4], 1); - regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_5], 1); - regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_DRV0_CTRL_1], 0); - regmap_field_write(derived_refclk->cmn_fields[CMN_CDIAG_REFCLK_OVRD_4], 1); + regmap_field_write(derived_refclk->cmn_cdiag_refclk_ovrd_4, 1); regmap_field_write(derived_refclk->phy_pipe_cmn_ctrl1_0, 1); return 0; @@ -1633,6 +1617,7 @@ static void cdns_torrent_derived_refclk_disable(struct clk_hw *hw) struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw); regmap_field_write(derived_refclk->phy_pipe_cmn_ctrl1_0, 0); + regmap_field_write(derived_refclk->cmn_cdiag_refclk_ovrd_4, 0); } static int cdns_torrent_derived_refclk_is_enabled(struct clk_hw *hw) @@ -1640,7 +1625,7 @@ static int cdns_torrent_derived_refclk_is_enabled(struct clk_hw *hw) struct cdns_torrent_derived_refclk *derived_refclk = to_cdns_torrent_derived_refclk(hw); int val; - regmap_field_read(derived_refclk->phy_pipe_cmn_ctrl1_0, &val); + regmap_field_read(derived_refclk->cmn_cdiag_refclk_ovrd_4, &val); return !!val; } @@ -1655,21 +1640,19 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph { struct cdns_torrent_derived_refclk *derived_refclk; struct device *dev = cdns_phy->dev; - struct regmap_field *field; struct clk_init_data *init; const char *parent_name; - struct regmap *regmap; char clk_name[100]; struct clk_hw *hw; struct clk *clk; - int i, ret; + int ret; derived_refclk = devm_kzalloc(dev, sizeof(*derived_refclk), GFP_KERNEL); if (!derived_refclk) return -ENOMEM; snprintf(clk_name, sizeof(clk_name), "%s_%s", dev_name(dev), - clk_names[CDNS_TORRENT_REFCLK_DRIVER]); + clk_names[CDNS_TORRENT_DERIVED_REFCLK]); clk = devm_clk_get_optional(dev, "phy_en_refclk"); if (IS_ERR(clk)) { @@ -1688,23 +1671,8 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph init->flags = 0; init->name = clk_name; - regmap = cdns_phy->regmap_phy_pcs_common_cdb; - field = devm_regmap_field_alloc(dev, regmap, phy_pipe_cmn_ctrl1_0); - if (IS_ERR(field)) { - dev_err(dev, "phy_pipe_cmn_ctrl1_0 reg field init failed\n"); - return PTR_ERR(field); - } - derived_refclk->phy_pipe_cmn_ctrl1_0 = field; - - regmap = cdns_phy->regmap_common_cdb; - for (i = 0; i < REFCLK_OUT_NUM_CMN_CONFIG; i++) { - field = devm_regmap_field_alloc(dev, regmap, refclk_out_cmn_cfg[i]); - if (IS_ERR(field)) { - dev_err(dev, "CMN reg field init failed\n"); - return PTR_ERR(field); - } - derived_refclk->cmn_fields[i] = field; - } + derived_refclk->phy_pipe_cmn_ctrl1_0 = cdns_phy->phy_pipe_cmn_ctrl1_0; + derived_refclk->cmn_cdiag_refclk_ovrd_4 = cdns_phy->cmn_cdiag_refclk_ovrd_4; derived_refclk->hw.init = init; @@ -1713,7 +1681,7 @@ static int cdns_torrent_derived_refclk_register(struct cdns_torrent_phy *cdns_ph if (ret) return ret; - cdns_phy->clk_hw_data->hws[CDNS_TORRENT_REFCLK_DRIVER] = hw; + cdns_phy->clk_hw_data->hws[CDNS_TORRENT_DERIVED_REFCLK] = hw; return 0; } @@ -1768,6 +1736,22 @@ static int cdns_torrent_regfield_init(struct cdns_torrent_phy *cdns_phy) } cdns_phy->phy_pll_cfg = field; + regmap = cdns_phy->regmap_phy_pcs_common_cdb; + field = devm_regmap_field_alloc(dev, regmap, phy_pipe_cmn_ctrl1_0); + if (IS_ERR(field)) { + dev_err(dev, "phy_pipe_cmn_ctrl1_0 reg field init failed\n"); + return PTR_ERR(field); + } + cdns_phy->phy_pipe_cmn_ctrl1_0 = field; + + regmap = cdns_phy->regmap_common_cdb; + field = devm_regmap_field_alloc(dev, regmap, cmn_cdiag_refclk_ovrd_4); + if (IS_ERR(field)) { + dev_err(dev, "cmn_cdiag_refclk_ovrd_4 reg field init failed\n"); + return PTR_ERR(field); + } + cdns_phy->cmn_cdiag_refclk_ovrd_4 = field; + regmap = cdns_phy->regmap_phy_pma_common_cdb; field = devm_regmap_field_alloc(dev, regmap, phy_pma_cmn_ctrl_1); if (IS_ERR(field)) {
Update the reference clock driver implementation where cmn_refclk_<p/m> is configured to output the reference clock. cmn_refclk_p/m will output either derived or received reference clock based on the selection. So, all these clocks should be modelled separately. Model the derived reference clock here as a first step to support reference clock driver. Signed-off-by: Swapnil Jakhade <sjakhade@cadence.com> --- drivers/phy/cadence/phy-cadence-torrent.c | 78 +++++++++-------------- 1 file changed, 31 insertions(+), 47 deletions(-)