Takashi Iwai 0841d8
From da08aab940092a050a4fb2857ed9479d2b0e03c4 Mon Sep 17 00:00:00 2001
Takashi Iwai 0841d8
From: Swapnil Jakhade <sjakhade@cadence.com>
Takashi Iwai 0841d8
Date: Thu, 23 Dec 2021 07:01:33 +0100
Takashi Iwai 0841d8
Subject: [PATCH] phy: cadence: Sierra: Fix to get correct parent for mux clocks
Takashi Iwai 0841d8
Git-commit: da08aab940092a050a4fb2857ed9479d2b0e03c4
Takashi Iwai 0841d8
Patch-mainline: v5.17-rc1
Takashi Iwai 0841d8
References: git-fixes
Takashi Iwai 0841d8
Takashi Iwai 0841d8
Fix get_parent() callback to return the correct index of the parent for
Takashi Iwai 0841d8
PLL_CMNLC1 clock. Add a separate table of register values corresponding
Takashi Iwai 0841d8
to the parent index for PLL_CMNLC1. Update set_parent() callback
Takashi Iwai 0841d8
accordingly.
Takashi Iwai 0841d8
Takashi Iwai 0841d8
Fixes: 28081b72859f ("phy: cadence: Sierra: Model PLL_CMNLC and PLL_CMNLC1 as clocks (mux clocks)")
Takashi Iwai 0841d8
Signed-off-by: Swapnil Jakhade <sjakhade@cadence.com>
Takashi Iwai 0841d8
Reviewed-by: Aswath Govindraju <a-govindraju@ti.com>
Takashi Iwai 0841d8
Link: https://lore.kernel.org/r/20211223060137.9252-12-sjakhade@cadence.com
Takashi Iwai 0841d8
Signed-off-by: Vinod Koul <vkoul@kernel.org>
Takashi Iwai 0841d8
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai 0841d8
Takashi Iwai 0841d8
---
Takashi Iwai 0841d8
 drivers/phy/cadence/phy-cadence-sierra.c |   31 ++++++++++++++++++++++++++-----
Takashi Iwai 0841d8
 1 file changed, 26 insertions(+), 5 deletions(-)
Takashi Iwai 0841d8
Takashi Iwai 0841d8
--- a/drivers/phy/cadence/phy-cadence-sierra.c
Takashi Iwai 0841d8
+++ b/drivers/phy/cadence/phy-cadence-sierra.c
Takashi Iwai 0841d8
@@ -215,7 +215,10 @@ static const int pll_mux_parent_index[][
Takashi Iwai 0841d8
 	[CMN_PLLLC1] = { PLL1_REFCLK, PLL0_REFCLK },
Takashi Iwai 0841d8
 };
Takashi Iwai 0841d8
 
Takashi Iwai 0841d8
-static u32 cdns_sierra_pll_mux_table[] = { 0, 1 };
Takashi Iwai 0841d8
+static u32 cdns_sierra_pll_mux_table[][SIERRA_NUM_CMN_PLLC_PARENTS] = {
Takashi Iwai 0841d8
+	[CMN_PLLLC] = { 0, 1 },
Takashi Iwai 0841d8
+	[CMN_PLLLC1] = { 1, 0 },
Takashi Iwai 0841d8
+};
Takashi Iwai 0841d8
 
Takashi Iwai 0841d8
 struct cdns_sierra_inst {
Takashi Iwai 0841d8
 	struct phy *phy;
Takashi Iwai 0841d8
@@ -436,11 +439,25 @@ static const struct phy_ops ops = {
Takashi Iwai 0841d8
 static u8 cdns_sierra_pll_mux_get_parent(struct clk_hw *hw)
Takashi Iwai 0841d8
 {
Takashi Iwai 0841d8
 	struct cdns_sierra_pll_mux *mux = to_cdns_sierra_pll_mux(hw);
Takashi Iwai 0841d8
+	struct regmap_field *plllc1en_field = mux->plllc1en_field;
Takashi Iwai 0841d8
+	struct regmap_field *termen_field = mux->termen_field;
Takashi Iwai 0841d8
 	struct regmap_field *field = mux->pfdclk_sel_preg;
Takashi Iwai 0841d8
 	unsigned int val;
Takashi Iwai 0841d8
+	int index;
Takashi Iwai 0841d8
 
Takashi Iwai 0841d8
 	regmap_field_read(field, &val;;
Takashi Iwai 0841d8
-	return clk_mux_val_to_index(hw, cdns_sierra_pll_mux_table, 0, val);
Takashi Iwai 0841d8
+
Takashi Iwai 0841d8
+	if (strstr(clk_hw_get_name(hw), clk_names[CDNS_SIERRA_PLL_CMNLC1])) {
Takashi Iwai 0841d8
+		index = clk_mux_val_to_index(hw, cdns_sierra_pll_mux_table[CMN_PLLLC1], 0, val);
Takashi Iwai 0841d8
+		if (index == 1) {
Takashi Iwai 0841d8
+			regmap_field_write(plllc1en_field, 1);
Takashi Iwai 0841d8
+			regmap_field_write(termen_field, 1);
Takashi Iwai 0841d8
+		}
Takashi Iwai 0841d8
+	} else {
Takashi Iwai 0841d8
+		index = clk_mux_val_to_index(hw, cdns_sierra_pll_mux_table[CMN_PLLLC], 0, val);
Takashi Iwai 0841d8
+	}
Takashi Iwai 0841d8
+
Takashi Iwai 0841d8
+	return index;
Takashi Iwai 0841d8
 }
Takashi Iwai 0841d8
 
Takashi Iwai 0841d8
 static int cdns_sierra_pll_mux_set_parent(struct clk_hw *hw, u8 index)
Takashi Iwai 0841d8
@@ -458,7 +475,11 @@ static int cdns_sierra_pll_mux_set_paren
Takashi Iwai 0841d8
 		ret |= regmap_field_write(termen_field, 1);
Takashi Iwai 0841d8
 	}
Takashi Iwai 0841d8
 
Takashi Iwai 0841d8
-	val = cdns_sierra_pll_mux_table[index];
Takashi Iwai 0841d8
+	if (strstr(clk_hw_get_name(hw), clk_names[CDNS_SIERRA_PLL_CMNLC1]))
Takashi Iwai 0841d8
+		val = cdns_sierra_pll_mux_table[CMN_PLLLC1][index];
Takashi Iwai 0841d8
+	else
Takashi Iwai 0841d8
+		val = cdns_sierra_pll_mux_table[CMN_PLLLC][index];
Takashi Iwai 0841d8
+
Takashi Iwai 0841d8
 	ret |= regmap_field_write(field, val);
Takashi Iwai 0841d8
 
Takashi Iwai 0841d8
 	return ret;
Takashi Iwai 0841d8
@@ -496,8 +517,8 @@ static int cdns_sierra_pll_mux_register(
Takashi Iwai 0841d8
 	for (i = 0; i < num_parents; i++) {
Takashi Iwai 0841d8
 		clk = sp->input_clks[pll_mux_parent_index[clk_index][i]];
Takashi Iwai 0841d8
 		if (IS_ERR_OR_NULL(clk)) {
Takashi Iwai 0841d8
-			dev_err(dev, "No parent clock for derived_refclk\n");
Takashi Iwai 0841d8
-			return PTR_ERR(clk);
Takashi Iwai 0841d8
+			dev_err(dev, "No parent clock for PLL mux clocks\n");
Takashi Iwai 0841d8
+			return IS_ERR(clk) ? PTR_ERR(clk) : -ENOENT;
Takashi Iwai 0841d8
 		}
Takashi Iwai 0841d8
 		parent_names[i] = __clk_get_name(clk);
Takashi Iwai 0841d8
 	}