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@xxxxxxxxxxx> --- 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)) { -- 2.26.1