Просмотр исходного кода

disp: msm: dp: Convert clock operations to byte2 ops

Convert clock operation to byte2 ops to meet DISPCC requirement.
Clock unit is changed from KHZ to HZ. Added link clock parent as
freq table is no longer supported in byte2 ops.

Change-Id: Icf5a595708040e8afefecebe7f371bb832d6673e
Signed-off-by: Sandeep Gangadharaiah <[email protected]>
Sandeep Gangadharaiah 3 лет назад
Родитель
Сommit
e4e277ad36
5 измененных файлов с 75 добавлено и 50 удалено
  1. 3 0
      msm/dp/dp_ctrl.c
  2. 1 0
      msm/dp/dp_pll.h
  3. 5 6
      msm/dp/dp_pll_4nm.c
  4. 5 6
      msm/dp/dp_pll_5nm.c
  5. 61 38
      msm/dp/dp_power.c

+ 3 - 0
msm/dp/dp_ctrl.c

@@ -647,6 +647,9 @@ static void dp_ctrl_set_clock_rate(struct dp_ctrl_private *ctrl,
 	u32 num = ctrl->parser->mp[clk_type].num_clk;
 	struct dss_clk *cfg = ctrl->parser->mp[clk_type].clk_config;
 
+	/* convert to HZ for byte2 ops */
+	rate *= ctrl->pll->clk_factor;
+
 	while (num && strcmp(cfg->clk_name, name)) {
 		num--;
 		cfg++;

+ 1 - 0
msm/dp/dp_pll.h

@@ -95,6 +95,7 @@ struct dp_pll {
 	struct dp_pll_io io;
 	struct clk_onecell_data *clk_data;
 	u32 dp_core_revision;
+	u32 clk_factor;
 
 	int (*pll_cfg)(struct dp_pll *pll, unsigned long rate);
 	int (*pll_prepare)(struct dp_pll *pll);

+ 5 - 6
msm/dp/dp_pll_4nm.c

@@ -737,8 +737,7 @@ static unsigned long dp_pll_link_clk_recalc_rate(struct clk_hw *hw,
 	pll_link = to_dp_vco_hw(hw);
 	pll = pll_link->priv;
 
-	rate = pll->vco_rate;
-	rate = pll->vco_rate / 10;
+	rate = pll->vco_rate * pll->clk_factor / 10;
 
 	return rate;
 }
@@ -757,7 +756,7 @@ static long dp_pll_link_clk_round(struct clk_hw *hw, unsigned long rate,
 	pll_link = to_dp_vco_hw(hw);
 	pll = pll_link->priv;
 
-	rate = pll->vco_rate / 10;
+	rate = pll->vco_rate * pll->clk_factor / 10;
 
 	return rate;
 }
@@ -765,11 +764,11 @@ static long dp_pll_link_clk_round(struct clk_hw *hw, unsigned long rate,
 static unsigned long dp_pll_vco_div_clk_get_rate(struct dp_pll *pll)
 {
 	if (pll->vco_rate == DP_VCO_HSCLK_RATE_8100MHZDIV1000)
-		return (pll->vco_rate / 6);
+		return (pll->vco_rate / (6 * pll->clk_factor));
 	else if (pll->vco_rate == DP_VCO_HSCLK_RATE_5400MHZDIV1000)
-		return (pll->vco_rate / 4);
+		return (pll->vco_rate / (4 * pll->clk_factor));
 	else
-		return (pll->vco_rate / 2);
+		return (pll->vco_rate / (2 * pll->clk_factor));
 }
 
 static unsigned long dp_pll_vco_div_clk_recalc_rate(struct clk_hw *hw,

+ 5 - 6
msm/dp/dp_pll_5nm.c

@@ -719,8 +719,7 @@ static unsigned long dp_pll_link_clk_recalc_rate(struct clk_hw *hw,
 	pll_link = to_dp_vco_hw(hw);
 	pll = pll_link->priv;
 
-	rate = pll->vco_rate;
-	rate = pll->vco_rate / 10;
+	rate = pll->vco_rate * pll->clk_factor / 10;
 
 	return rate;
 }
@@ -739,7 +738,7 @@ static long dp_pll_link_clk_round(struct clk_hw *hw, unsigned long rate,
 	pll_link = to_dp_vco_hw(hw);
 	pll = pll_link->priv;
 
-	rate = pll->vco_rate / 10;
+	rate = pll->vco_rate * pll->clk_factor / 10;
 
 	return rate;
 }
@@ -747,11 +746,11 @@ static long dp_pll_link_clk_round(struct clk_hw *hw, unsigned long rate,
 static unsigned long dp_pll_vco_div_clk_get_rate(struct dp_pll *pll)
 {
 	if (pll->vco_rate == DP_VCO_HSCLK_RATE_8100MHZDIV1000)
-		return (pll->vco_rate / 6);
+		return (pll->vco_rate / (6 * pll->clk_factor));
 	else if (pll->vco_rate == DP_VCO_HSCLK_RATE_5400MHZDIV1000)
-		return (pll->vco_rate / 4);
+		return (pll->vco_rate / (4 * pll->clk_factor));
 	else
-		return (pll->vco_rate / 2);
+		return (pll->vco_rate / (2 * pll->clk_factor));
 }
 
 static unsigned long dp_pll_vco_div_clk_recalc_rate(struct clk_hw *hw,

+ 61 - 38
msm/dp/dp_power.c

@@ -22,6 +22,8 @@ struct dp_power_private {
 	struct clk *pixel_parent;
 	struct clk *pixel1_clk_rcg;
 	struct clk *xo_clk;
+	struct clk *link_clk_rcg;
+	struct clk *link_parent;
 
 	struct dp_power dp_power;
 
@@ -245,6 +247,25 @@ static int dp_power_clk_init(struct dp_power_private *power, bool enable)
 				goto err_pixel1_clk_rcg;
 			}
 		}
+
+		power->link_clk_rcg = clk_get(dev, "link_clk_src");
+		if (IS_ERR(power->link_clk_rcg)) {
+			DP_ERR("Unable to get DP link clk RCG: %ld\n",
+					PTR_ERR(power->link_clk_rcg));
+			rc = PTR_ERR(power->link_clk_rcg);
+			power->link_clk_rcg = NULL;
+			goto err_link_clk_rcg;
+		}
+
+		/* If link_parent node is available, convert clk rates to HZ for byte2 ops */
+		power->pll->clk_factor = 1000;
+		power->link_parent = clk_get(dev, "link_parent");
+		if (IS_ERR(power->link_parent)) {
+			DP_WARN("Unable to get DP link parent: %ld\n",
+					PTR_ERR(power->link_parent));
+			power->link_parent = NULL;
+			power->pll->clk_factor = 1;
+		}
 	} else {
 		if (power->pixel1_clk_rcg)
 			clk_put(power->pixel1_clk_rcg);
@@ -255,10 +276,19 @@ static int dp_power_clk_init(struct dp_power_private *power, bool enable)
 		if (power->pixel_clk_rcg)
 			clk_put(power->pixel_clk_rcg);
 
+		if (power->link_parent)
+			clk_put(power->link_parent);
+
+		if (power->link_clk_rcg)
+			clk_put(power->link_clk_rcg);
+
 		dp_power_clk_put(power);
 	}
 
 	return rc;
+err_link_clk_rcg:
+	if (power->pixel1_clk_rcg)
+		clk_put(power->pixel1_clk_rcg);
 err_pixel1_clk_rcg:
 	clk_put(power->xo_clk);
 err_xo_clk:
@@ -363,6 +393,29 @@ exit:
 	return rc;
 }
 
+static bool dp_power_clk_status(struct dp_power *dp_power, enum dp_pm_type pm_type)
+{
+	struct dp_power_private *power;
+
+	if (!dp_power) {
+		DP_ERR("invalid power data\n");
+		return false;
+	}
+
+	power = container_of(dp_power, struct dp_power_private, dp_power);
+
+	if (pm_type == DP_LINK_PM)
+		return power->link_clks_on;
+	else if (pm_type == DP_CORE_PM)
+		return power->core_clks_on;
+	else if (pm_type == DP_STREAM0_PM)
+		return power->strm0_clks_on;
+	else if (pm_type == DP_STREAM1_PM)
+		return power->strm1_clks_on;
+	else
+		return false;
+}
+
 static int dp_power_clk_enable(struct dp_power *dp_power,
 		enum dp_pm_type pm_type, bool enable)
 {
@@ -387,18 +440,8 @@ static int dp_power_clk_enable(struct dp_power *dp_power,
 	}
 
 	if (enable) {
-		if (pm_type == DP_CORE_PM && power->core_clks_on) {
-			DP_DEBUG("core clks already enabled\n");
-			return 0;
-		}
-
-		if ((pm_type == DP_STREAM0_PM) && (power->strm0_clks_on)) {
-			DP_DEBUG("strm0 clks already enabled\n");
-			return 0;
-		}
-
-		if ((pm_type == DP_STREAM1_PM) && (power->strm1_clks_on)) {
-			DP_DEBUG("strm1 clks already enabled\n");
+		if (dp_power_clk_status(dp_power, pm_type)) {
+			DP_DEBUG("%s clks already enabled\n", dp_parser_pm_name(pm_type));
 			return 0;
 		}
 
@@ -415,9 +458,12 @@ static int dp_power_clk_enable(struct dp_power *dp_power,
 			}
 		}
 
-		if (pm_type == DP_LINK_PM && power->link_clks_on) {
-			DP_DEBUG("links clks already enabled\n");
-			return 0;
+		if (pm_type == DP_LINK_PM && power->link_parent) {
+			rc = clk_set_parent(power->link_clk_rcg, power->link_parent);
+			if (rc) {
+				DP_ERR("failed to set link parent\n");
+				goto error;
+			}
 		}
 	}
 
@@ -458,29 +504,6 @@ error:
 	return rc;
 }
 
-static bool dp_power_clk_status(struct dp_power *dp_power, enum dp_pm_type pm_type)
-{
-	struct dp_power_private *power;
-
-	if (!dp_power) {
-		DP_ERR("invalid power data\n");
-		return false;
-	}
-
-	power = container_of(dp_power, struct dp_power_private, dp_power);
-
-	if (pm_type == DP_LINK_PM)
-		return power->link_clks_on;
-	else if (pm_type == DP_CORE_PM)
-		return power->core_clks_on;
-	else if (pm_type == DP_STREAM0_PM)
-		return power->strm0_clks_on;
-	else if (pm_type == DP_STREAM1_PM)
-		return power->strm1_clks_on;
-	else
-		return false;
-}
-
 static int dp_power_request_gpios(struct dp_power_private *power)
 {
 	int rc = 0, i;