All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jernej Skrabec <jernej.skrabec@siol.net>
To: maxime.ripard@bootlin.com, wens@csie.org, robh+dt@kernel.org
Cc: airlied@linux.ie, gustavo@padovan.org,
	maarten.lankhorst@linux.intel.com, seanpaul@chromium.org,
	mark.rutland@arm.com, dri-devel@lists.freedesktop.org,
	devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org,
	linux-sunxi@googlegroups.com
Subject: [PATCH v3 19/24] drm/sun4i: Add support for second clock parent to DW HDMI PHY clk driver
Date: Mon, 25 Jun 2018 14:02:59 +0200	[thread overview]
Message-ID: <20180625120304.7543-20-jernej.skrabec@siol.net> (raw)
In-Reply-To: <20180625120304.7543-1-jernej.skrabec@siol.net>

Expand HDMI PHY clock driver to support second clock parent.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h      |  4 +-
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c     |  3 +-
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c | 90 ++++++++++++++++------
 3 files changed, 73 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
index 46a3aa6a53a9..aadbe0a10b0c 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -99,6 +99,7 @@
 #define SUN8I_HDMI_PHY_PLL_CFG1_LDO1_EN		BIT(28)
 #define SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33	BIT(27)
 #define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK	BIT(26)
+#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT	26
 #define SUN8I_HDMI_PHY_PLL_CFG1_PLLEN		BIT(25)
 #define SUN8I_HDMI_PHY_PLL_CFG1_LDO_VSET(x)	((x) << 22)
 #define SUN8I_HDMI_PHY_PLL_CFG1_UNKNOWN(x)	((x) << 20)
@@ -190,6 +191,7 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi);
 void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy);
 const struct dw_hdmi_phy_ops *sun8i_hdmi_phy_get_ops(void);
 
-int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev);
+int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev,
+			 bool second_parent);
 
 #endif /* _SUN8I_DW_HDMI_H_ */
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index f0877b3f67e7..aea46b08f127 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -491,7 +491,8 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
 			}
 		}
 
-		ret = sun8i_phy_clk_create(phy, dev);
+		ret = sun8i_phy_clk_create(phy, dev,
+					   phy->variant->has_second_pll);
 		if (ret) {
 			dev_err(dev, "Couldn't create the PHY clock\n");
 			goto err_put_clk_pll1;
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
index faea449812f8..a4d31fe3abff 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
@@ -22,35 +22,45 @@ static int sun8i_phy_clk_determine_rate(struct clk_hw *hw,
 {
 	unsigned long rate = req->rate;
 	unsigned long best_rate = 0;
+	struct clk_hw *best_parent = NULL;
 	struct clk_hw *parent;
 	int best_div = 1;
-	int i;
+	int i, p;
 
-	parent = clk_hw_get_parent(hw);
-
-	for (i = 1; i <= 16; i++) {
-		unsigned long ideal = rate * i;
-		unsigned long rounded;
-
-		rounded = clk_hw_round_rate(parent, ideal);
+	for (p = 0; p < clk_hw_get_num_parents(hw); p++) {
+		parent = clk_hw_get_parent_by_index(hw, p);
+		if (!parent)
+			continue;
 
-		if (rounded == ideal) {
-			best_rate = rounded;
-			best_div = i;
-			break;
+		for (i = 1; i <= 16; i++) {
+			unsigned long ideal = rate * i;
+			unsigned long rounded;
+
+			rounded = clk_hw_round_rate(parent, ideal);
+
+			if (rounded == ideal) {
+				best_rate = rounded;
+				best_div = i;
+				best_parent = parent;
+				break;
+			}
+
+			if (!best_rate ||
+			    abs(rate - rounded / i) <
+			    abs(rate - best_rate / best_div)) {
+				best_rate = rounded;
+				best_div = i;
+				best_parent = parent;
+			}
 		}
 
-		if (!best_rate ||
-		    abs(rate - rounded / i) <
-		    abs(rate - best_rate / best_div)) {
-			best_rate = rounded;
-			best_div = i;
-		}
+		if (best_rate / best_div == rate)
+			break;
 	}
 
 	req->rate = best_rate / best_div;
 	req->best_parent_rate = best_rate;
-	req->best_parent_hw = parent;
+	req->best_parent_hw = best_parent;
 
 	return 0;
 }
@@ -95,22 +105,58 @@ static int sun8i_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 	return 0;
 }
 
+static u8 sun8i_phy_clk_get_parent(struct clk_hw *hw)
+{
+	struct sun8i_phy_clk *priv = hw_to_phy_clk(hw);
+	u32 reg;
+
+	regmap_read(priv->phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, &reg);
+	reg = (reg & SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK) >>
+	      SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT;
+
+	return reg;
+}
+
+static int sun8i_phy_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct sun8i_phy_clk *priv = hw_to_phy_clk(hw);
+
+	if (index > 1)
+		return -EINVAL;
+
+	regmap_update_bits(priv->phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
+			   SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK,
+			   index << SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT);
+
+	return 0;
+}
+
 static const struct clk_ops sun8i_phy_clk_ops = {
 	.determine_rate	= sun8i_phy_clk_determine_rate,
 	.recalc_rate	= sun8i_phy_clk_recalc_rate,
 	.set_rate	= sun8i_phy_clk_set_rate,
+
+	.get_parent	= sun8i_phy_clk_get_parent,
+	.set_parent	= sun8i_phy_clk_set_parent,
 };
 
-int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev)
+int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev,
+			 bool second_parent)
 {
 	struct clk_init_data init;
 	struct sun8i_phy_clk *priv;
-	const char *parents[1];
+	const char *parents[2];
 
 	parents[0] = __clk_get_name(phy->clk_pll0);
 	if (!parents[0])
 		return -ENODEV;
 
+	if (second_parent) {
+		parents[1] = __clk_get_name(phy->clk_pll1);
+		if (!parents[1])
+			return -ENODEV;
+	}
+
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
@@ -118,7 +164,7 @@ int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev)
 	init.name = "hdmi-phy-clk";
 	init.ops = &sun8i_phy_clk_ops;
 	init.parent_names = parents;
-	init.num_parents = 1;
+	init.num_parents = second_parent ? 2 : 1;
 	init.flags = CLK_SET_RATE_PARENT;
 
 	priv->phy = phy;
-- 
2.18.0


WARNING: multiple messages have this Message-ID (diff)
From: Jernej Skrabec <jernej.skrabec-gGgVlfcn5nU@public.gmane.org>
To: maxime.ripard-LDxbnhwyfcJBDgjK7y7TUQ@public.gmane.org,
	wens-jdAy2FN1RRM@public.gmane.org,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org
Cc: airlied-cv59FeDIM0c@public.gmane.org,
	gustavo-THi1TnShQwVAfugRpC6u6w@public.gmane.org,
	maarten.lankhorst-VuQAYsv1563Yd54FQh9/CA@public.gmane.org,
	seanpaul-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org,
	mark.rutland-5wv7dgnIgG8@public.gmane.org,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
Subject: [PATCH v3 19/24] drm/sun4i: Add support for second clock parent to DW HDMI PHY clk driver
Date: Mon, 25 Jun 2018 14:02:59 +0200	[thread overview]
Message-ID: <20180625120304.7543-20-jernej.skrabec@siol.net> (raw)
In-Reply-To: <20180625120304.7543-1-jernej.skrabec-gGgVlfcn5nU@public.gmane.org>

Expand HDMI PHY clock driver to support second clock parent.

Signed-off-by: Jernej Skrabec <jernej.skrabec-gGgVlfcn5nU@public.gmane.org>
---
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h      |  4 +-
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c     |  3 +-
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c | 90 ++++++++++++++++------
 3 files changed, 73 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
index 46a3aa6a53a9..aadbe0a10b0c 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -99,6 +99,7 @@
 #define SUN8I_HDMI_PHY_PLL_CFG1_LDO1_EN		BIT(28)
 #define SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33	BIT(27)
 #define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK	BIT(26)
+#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT	26
 #define SUN8I_HDMI_PHY_PLL_CFG1_PLLEN		BIT(25)
 #define SUN8I_HDMI_PHY_PLL_CFG1_LDO_VSET(x)	((x) << 22)
 #define SUN8I_HDMI_PHY_PLL_CFG1_UNKNOWN(x)	((x) << 20)
@@ -190,6 +191,7 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi);
 void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy);
 const struct dw_hdmi_phy_ops *sun8i_hdmi_phy_get_ops(void);
 
-int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev);
+int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev,
+			 bool second_parent);
 
 #endif /* _SUN8I_DW_HDMI_H_ */
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index f0877b3f67e7..aea46b08f127 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -491,7 +491,8 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
 			}
 		}
 
-		ret = sun8i_phy_clk_create(phy, dev);
+		ret = sun8i_phy_clk_create(phy, dev,
+					   phy->variant->has_second_pll);
 		if (ret) {
 			dev_err(dev, "Couldn't create the PHY clock\n");
 			goto err_put_clk_pll1;
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
index faea449812f8..a4d31fe3abff 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
@@ -22,35 +22,45 @@ static int sun8i_phy_clk_determine_rate(struct clk_hw *hw,
 {
 	unsigned long rate = req->rate;
 	unsigned long best_rate = 0;
+	struct clk_hw *best_parent = NULL;
 	struct clk_hw *parent;
 	int best_div = 1;
-	int i;
+	int i, p;
 
-	parent = clk_hw_get_parent(hw);
-
-	for (i = 1; i <= 16; i++) {
-		unsigned long ideal = rate * i;
-		unsigned long rounded;
-
-		rounded = clk_hw_round_rate(parent, ideal);
+	for (p = 0; p < clk_hw_get_num_parents(hw); p++) {
+		parent = clk_hw_get_parent_by_index(hw, p);
+		if (!parent)
+			continue;
 
-		if (rounded == ideal) {
-			best_rate = rounded;
-			best_div = i;
-			break;
+		for (i = 1; i <= 16; i++) {
+			unsigned long ideal = rate * i;
+			unsigned long rounded;
+
+			rounded = clk_hw_round_rate(parent, ideal);
+
+			if (rounded == ideal) {
+				best_rate = rounded;
+				best_div = i;
+				best_parent = parent;
+				break;
+			}
+
+			if (!best_rate ||
+			    abs(rate - rounded / i) <
+			    abs(rate - best_rate / best_div)) {
+				best_rate = rounded;
+				best_div = i;
+				best_parent = parent;
+			}
 		}
 
-		if (!best_rate ||
-		    abs(rate - rounded / i) <
-		    abs(rate - best_rate / best_div)) {
-			best_rate = rounded;
-			best_div = i;
-		}
+		if (best_rate / best_div == rate)
+			break;
 	}
 
 	req->rate = best_rate / best_div;
 	req->best_parent_rate = best_rate;
-	req->best_parent_hw = parent;
+	req->best_parent_hw = best_parent;
 
 	return 0;
 }
@@ -95,22 +105,58 @@ static int sun8i_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 	return 0;
 }
 
+static u8 sun8i_phy_clk_get_parent(struct clk_hw *hw)
+{
+	struct sun8i_phy_clk *priv = hw_to_phy_clk(hw);
+	u32 reg;
+
+	regmap_read(priv->phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, &reg);
+	reg = (reg & SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK) >>
+	      SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT;
+
+	return reg;
+}
+
+static int sun8i_phy_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct sun8i_phy_clk *priv = hw_to_phy_clk(hw);
+
+	if (index > 1)
+		return -EINVAL;
+
+	regmap_update_bits(priv->phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
+			   SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK,
+			   index << SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT);
+
+	return 0;
+}
+
 static const struct clk_ops sun8i_phy_clk_ops = {
 	.determine_rate	= sun8i_phy_clk_determine_rate,
 	.recalc_rate	= sun8i_phy_clk_recalc_rate,
 	.set_rate	= sun8i_phy_clk_set_rate,
+
+	.get_parent	= sun8i_phy_clk_get_parent,
+	.set_parent	= sun8i_phy_clk_set_parent,
 };
 
-int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev)
+int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev,
+			 bool second_parent)
 {
 	struct clk_init_data init;
 	struct sun8i_phy_clk *priv;
-	const char *parents[1];
+	const char *parents[2];
 
 	parents[0] = __clk_get_name(phy->clk_pll0);
 	if (!parents[0])
 		return -ENODEV;
 
+	if (second_parent) {
+		parents[1] = __clk_get_name(phy->clk_pll1);
+		if (!parents[1])
+			return -ENODEV;
+	}
+
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
@@ -118,7 +164,7 @@ int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev)
 	init.name = "hdmi-phy-clk";
 	init.ops = &sun8i_phy_clk_ops;
 	init.parent_names = parents;
-	init.num_parents = 1;
+	init.num_parents = second_parent ? 2 : 1;
 	init.flags = CLK_SET_RATE_PARENT;
 
 	priv->phy = phy;
-- 
2.18.0

WARNING: multiple messages have this Message-ID (diff)
From: jernej.skrabec@siol.net (Jernej Skrabec)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v3 19/24] drm/sun4i: Add support for second clock parent to DW HDMI PHY clk driver
Date: Mon, 25 Jun 2018 14:02:59 +0200	[thread overview]
Message-ID: <20180625120304.7543-20-jernej.skrabec@siol.net> (raw)
In-Reply-To: <20180625120304.7543-1-jernej.skrabec@siol.net>

Expand HDMI PHY clock driver to support second clock parent.

Signed-off-by: Jernej Skrabec <jernej.skrabec@siol.net>
---
 drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h      |  4 +-
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c     |  3 +-
 drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c | 90 ++++++++++++++++------
 3 files changed, 73 insertions(+), 24 deletions(-)

diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
index 46a3aa6a53a9..aadbe0a10b0c 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -99,6 +99,7 @@
 #define SUN8I_HDMI_PHY_PLL_CFG1_LDO1_EN		BIT(28)
 #define SUN8I_HDMI_PHY_PLL_CFG1_HV_IS_33	BIT(27)
 #define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK	BIT(26)
+#define SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT	26
 #define SUN8I_HDMI_PHY_PLL_CFG1_PLLEN		BIT(25)
 #define SUN8I_HDMI_PHY_PLL_CFG1_LDO_VSET(x)	((x) << 22)
 #define SUN8I_HDMI_PHY_PLL_CFG1_UNKNOWN(x)	((x) << 20)
@@ -190,6 +191,7 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi);
 void sun8i_hdmi_phy_init(struct sun8i_hdmi_phy *phy);
 const struct dw_hdmi_phy_ops *sun8i_hdmi_phy_get_ops(void);
 
-int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev);
+int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev,
+			 bool second_parent);
 
 #endif /* _SUN8I_DW_HDMI_H_ */
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
index f0877b3f67e7..aea46b08f127 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -491,7 +491,8 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
 			}
 		}
 
-		ret = sun8i_phy_clk_create(phy, dev);
+		ret = sun8i_phy_clk_create(phy, dev,
+					   phy->variant->has_second_pll);
 		if (ret) {
 			dev_err(dev, "Couldn't create the PHY clock\n");
 			goto err_put_clk_pll1;
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
index faea449812f8..a4d31fe3abff 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
@@ -22,35 +22,45 @@ static int sun8i_phy_clk_determine_rate(struct clk_hw *hw,
 {
 	unsigned long rate = req->rate;
 	unsigned long best_rate = 0;
+	struct clk_hw *best_parent = NULL;
 	struct clk_hw *parent;
 	int best_div = 1;
-	int i;
+	int i, p;
 
-	parent = clk_hw_get_parent(hw);
-
-	for (i = 1; i <= 16; i++) {
-		unsigned long ideal = rate * i;
-		unsigned long rounded;
-
-		rounded = clk_hw_round_rate(parent, ideal);
+	for (p = 0; p < clk_hw_get_num_parents(hw); p++) {
+		parent = clk_hw_get_parent_by_index(hw, p);
+		if (!parent)
+			continue;
 
-		if (rounded == ideal) {
-			best_rate = rounded;
-			best_div = i;
-			break;
+		for (i = 1; i <= 16; i++) {
+			unsigned long ideal = rate * i;
+			unsigned long rounded;
+
+			rounded = clk_hw_round_rate(parent, ideal);
+
+			if (rounded == ideal) {
+				best_rate = rounded;
+				best_div = i;
+				best_parent = parent;
+				break;
+			}
+
+			if (!best_rate ||
+			    abs(rate - rounded / i) <
+			    abs(rate - best_rate / best_div)) {
+				best_rate = rounded;
+				best_div = i;
+				best_parent = parent;
+			}
 		}
 
-		if (!best_rate ||
-		    abs(rate - rounded / i) <
-		    abs(rate - best_rate / best_div)) {
-			best_rate = rounded;
-			best_div = i;
-		}
+		if (best_rate / best_div == rate)
+			break;
 	}
 
 	req->rate = best_rate / best_div;
 	req->best_parent_rate = best_rate;
-	req->best_parent_hw = parent;
+	req->best_parent_hw = best_parent;
 
 	return 0;
 }
@@ -95,22 +105,58 @@ static int sun8i_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
 	return 0;
 }
 
+static u8 sun8i_phy_clk_get_parent(struct clk_hw *hw)
+{
+	struct sun8i_phy_clk *priv = hw_to_phy_clk(hw);
+	u32 reg;
+
+	regmap_read(priv->phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, &reg);
+	reg = (reg & SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK) >>
+	      SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT;
+
+	return reg;
+}
+
+static int sun8i_phy_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct sun8i_phy_clk *priv = hw_to_phy_clk(hw);
+
+	if (index > 1)
+		return -EINVAL;
+
+	regmap_update_bits(priv->phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
+			   SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK,
+			   index << SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_SHIFT);
+
+	return 0;
+}
+
 static const struct clk_ops sun8i_phy_clk_ops = {
 	.determine_rate	= sun8i_phy_clk_determine_rate,
 	.recalc_rate	= sun8i_phy_clk_recalc_rate,
 	.set_rate	= sun8i_phy_clk_set_rate,
+
+	.get_parent	= sun8i_phy_clk_get_parent,
+	.set_parent	= sun8i_phy_clk_set_parent,
 };
 
-int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev)
+int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev,
+			 bool second_parent)
 {
 	struct clk_init_data init;
 	struct sun8i_phy_clk *priv;
-	const char *parents[1];
+	const char *parents[2];
 
 	parents[0] = __clk_get_name(phy->clk_pll0);
 	if (!parents[0])
 		return -ENODEV;
 
+	if (second_parent) {
+		parents[1] = __clk_get_name(phy->clk_pll1);
+		if (!parents[1])
+			return -ENODEV;
+	}
+
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
@@ -118,7 +164,7 @@ int sun8i_phy_clk_create(struct sun8i_hdmi_phy *phy, struct device *dev)
 	init.name = "hdmi-phy-clk";
 	init.ops = &sun8i_phy_clk_ops;
 	init.parent_names = parents;
-	init.num_parents = 1;
+	init.num_parents = second_parent ? 2 : 1;
 	init.flags = CLK_SET_RATE_PARENT;
 
 	priv->phy = phy;
-- 
2.18.0

  parent reply	other threads:[~2018-06-25 12:05 UTC|newest]

Thread overview: 269+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-25 12:02 [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Skrabec
2018-06-25 12:02 ` Jernej Skrabec
2018-06-25 12:02 ` Jernej Skrabec
2018-06-25 12:02 ` [PATCH v3 01/24] clk: sunxi-ng: r40: Add minimal rate for video PLLs Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02 ` [PATCH v3 02/24] clk: sunxi-ng: r40: Allow setting parent rate to display related clocks Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02 ` [PATCH v3 03/24] clk: sunxi-ng: r40: Export video PLLs Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:30   ` Chen-Yu Tsai
2018-06-25 12:30     ` Chen-Yu Tsai
2018-06-25 12:30     ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 04/24] dt-bindings: display: sunxi-drm: Add TCON TOP description Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 17:33   ` Rob Herring
2018-06-25 17:33     ` Rob Herring
2018-06-25 17:33     ` Rob Herring
2018-06-25 12:02 ` [PATCH v3 05/24] drm/sun4i: Add TCON TOP driver Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-28  1:47   ` Chen-Yu Tsai
2018-06-28  1:47     ` Chen-Yu Tsai
2018-06-28  1:47     ` Chen-Yu Tsai
2018-06-29 19:09     ` Jernej Škrabec
2018-06-29 19:09       ` Jernej Škrabec
2018-06-29 19:09       ` Jernej Škrabec
2018-06-30  1:13       ` [linux-sunxi] " Chen-Yu Tsai
2018-06-30  1:13         ` Chen-Yu Tsai
2018-06-30  1:13         ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 06/24] drm/sun4i: Fix releasing node when enumerating enpoints Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-28  1:53   ` [linux-sunxi] " Chen-Yu Tsai
2018-06-28  1:53     ` Chen-Yu Tsai
2018-06-28  1:53     ` Chen-Yu Tsai
2018-06-29 19:15     ` [linux-sunxi] " Jernej Škrabec
2018-06-29 19:15       ` Jernej Škrabec
2018-06-29 19:15       ` Jernej Škrabec
2018-06-30  1:09       ` [linux-sunxi] " Chen-Yu Tsai
2018-06-30  1:09         ` Chen-Yu Tsai
2018-06-30  1:09         ` Chen-Yu Tsai
2018-06-30  1:09         ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 07/24] drm/sun4i: Split out code for enumerating endpoints in output port Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-28  1:57   ` [linux-sunxi] " Chen-Yu Tsai
2018-06-28  1:57     ` Chen-Yu Tsai
2018-06-28  1:57     ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 08/24] drm/sun4i: Add support for traversing graph with TCON TOP Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-28  1:57   ` Chen-Yu Tsai
2018-06-28  1:57     ` Chen-Yu Tsai
2018-06-28  1:57     ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 09/24] drm/sun4i: Don't skip TCONs if they don't have channel 0 Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-28  1:51   ` Chen-Yu Tsai
2018-06-28  1:51     ` Chen-Yu Tsai
2018-06-28  1:51     ` Chen-Yu Tsai
2018-06-28  4:45     ` Jernej Škrabec
2018-06-28  4:45       ` Jernej Škrabec
2018-06-28  4:45       ` Jernej Škrabec
2018-06-28  6:24       ` [linux-sunxi] " Chen-Yu Tsai
2018-06-28  6:24         ` Chen-Yu Tsai
2018-06-28  6:24         ` Chen-Yu Tsai
2018-07-01  8:27         ` [linux-sunxi] " Jernej Škrabec
2018-07-01  8:27           ` Jernej Škrabec
2018-07-01  8:27           ` Jernej Škrabec
2018-07-01 15:11           ` [linux-sunxi] " Chen-Yu Tsai
2018-07-01 15:11             ` Chen-Yu Tsai
2018-07-01 15:11             ` Chen-Yu Tsai
2018-07-05  7:03             ` [linux-sunxi] " Maxime Ripard
2018-07-05  7:03               ` Maxime Ripard
2018-07-05  7:03               ` Maxime Ripard
2018-07-05 20:03               ` [linux-sunxi] " Jernej Škrabec
2018-07-05 20:03                 ` Jernej Škrabec
2018-07-05 20:03                 ` Jernej Škrabec
2018-07-09  8:59                 ` [linux-sunxi] " Maxime Ripard
2018-07-09  8:59                   ` Maxime Ripard
2018-07-09  8:59                   ` Maxime Ripard
2018-06-25 12:02 ` [PATCH v3 10/24] drm/sun4i: tcon: Generalize engine search algorithm Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-28  2:06   ` Chen-Yu Tsai
2018-06-28  2:06     ` Chen-Yu Tsai
2018-06-28  2:06     ` Chen-Yu Tsai
2018-06-28  4:48     ` Jernej Škrabec
2018-06-28  4:48       ` Jernej Škrabec
2018-06-28  4:48       ` Jernej Škrabec
2018-06-28 18:25       ` Maxime Ripard
2018-06-28 18:25         ` Maxime Ripard
2018-06-28 18:25         ` Maxime Ripard
2018-06-29 19:06         ` Jernej Škrabec
2018-06-29 19:06           ` Jernej Škrabec
2018-06-29 19:06           ` Jernej Škrabec
2018-07-01 19:09           ` [linux-sunxi] " Jernej Škrabec
2018-07-01 19:09             ` Jernej Škrabec
2018-07-01 19:09             ` Jernej Škrabec
2018-07-01 19:09             ` Jernej Škrabec
2018-07-02  8:56             ` [linux-sunxi] " Maxime Ripard
2018-07-02  8:56               ` Maxime Ripard
2018-07-02  8:56               ` Maxime Ripard
2018-06-25 12:02 ` [PATCH v3 11/24] drm/sun4i: Don't check for LVDS and RGB when TCON has only ch1 Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-28  2:08   ` Chen-Yu Tsai
2018-06-28  2:08     ` Chen-Yu Tsai
2018-06-28  2:08     ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 12/24] drm/sun4i: Don't check for panel or bridge on TV TCONs Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-28  2:17   ` Chen-Yu Tsai
2018-06-28  2:17     ` Chen-Yu Tsai
2018-06-28  2:17     ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 13/24] dt-bindings: display: sun4i-drm: Add R40 mixer compatibles Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-28  2:17   ` Chen-Yu Tsai
2018-06-28  2:17     ` Chen-Yu Tsai
2018-06-28  2:17     ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 14/24] drm/sun4i: Add support for R40 mixers Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-28  2:18   ` Chen-Yu Tsai
2018-06-28  2:18     ` Chen-Yu Tsai
2018-06-28  2:18     ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 15/24] dt-bindings: display: sun4i-drm: Add description of A64 HDMI PHY Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-28  2:19   ` Chen-Yu Tsai
2018-06-28  2:19     ` Chen-Yu Tsai
2018-06-28  2:19     ` Chen-Yu Tsai
2018-06-28  4:51     ` Jernej Škrabec
2018-06-28  4:51       ` Jernej Škrabec
2018-06-28  4:51       ` Jernej Škrabec
2018-06-28  7:00       ` [linux-sunxi] " Chen-Yu Tsai
2018-06-28  7:00         ` Chen-Yu Tsai
2018-06-28  7:00         ` Chen-Yu Tsai
2018-06-29 19:32         ` [linux-sunxi] " Jernej Škrabec
2018-06-29 19:32           ` Jernej Škrabec
2018-06-29 19:32           ` Jernej Škrabec
2018-07-04  4:05           ` [linux-sunxi] " Chen-Yu Tsai
2018-07-04  4:05             ` Chen-Yu Tsai
2018-07-04  4:05             ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 16/24] drm/sun4i: Enable DW HDMI PHY clock Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-28  2:22   ` Chen-Yu Tsai
2018-06-28  2:22     ` Chen-Yu Tsai
2018-06-28  2:22     ` Chen-Yu Tsai
2018-06-28  4:52     ` Jernej Škrabec
2018-06-28  4:52       ` Jernej Škrabec
2018-06-28  4:52       ` Jernej Škrabec
2018-06-29 19:19     ` Jernej Škrabec
2018-06-29 19:19       ` Jernej Škrabec
2018-06-29 19:19       ` Jernej Škrabec
2018-06-30  1:11       ` Chen-Yu Tsai
2018-06-30  1:11         ` Chen-Yu Tsai
2018-06-30  1:11         ` Chen-Yu Tsai
2018-06-25 12:02 ` [PATCH v3 17/24] drm/sun4i: Don't change clock bits in DW HDMI PHY driver Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-28  2:24   ` Chen-Yu Tsai
2018-06-28  2:24     ` Chen-Yu Tsai
2018-06-28  2:24     ` Chen-Yu Tsai
2018-06-29 19:23     ` Jernej Škrabec
2018-06-29 19:23       ` Jernej Škrabec
2018-06-29 19:23       ` Jernej Škrabec
2018-06-25 12:02 ` [PATCH v3 18/24] drm/sun4i: DW HDMI PHY: Add support for second PLL Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-28  2:25   ` Chen-Yu Tsai
2018-06-28  2:25     ` Chen-Yu Tsai
2018-06-28  2:25     ` Chen-Yu Tsai
2018-06-28  4:56     ` Jernej Škrabec
2018-06-28  4:56       ` Jernej Škrabec
2018-06-28  4:56       ` Jernej Škrabec
2018-06-28  6:59       ` [linux-sunxi] " Chen-Yu Tsai
2018-06-28  6:59         ` Chen-Yu Tsai
2018-06-28  6:59         ` Chen-Yu Tsai
2018-06-25 12:02 ` Jernej Skrabec [this message]
2018-06-25 12:02   ` [PATCH v3 19/24] drm/sun4i: Add support for second clock parent to DW HDMI PHY clk driver Jernej Skrabec
2018-06-25 12:02   ` Jernej Skrabec
2018-06-28  2:30   ` [linux-sunxi] " Chen-Yu Tsai
2018-06-28  2:30     ` Chen-Yu Tsai
2018-06-28  2:30     ` Chen-Yu Tsai
2018-06-25 12:03 ` [PATCH v3 20/24] drm/sun4i: Add support for A64 HDMI PHY Jernej Skrabec
2018-06-25 12:03   ` Jernej Skrabec
2018-06-25 12:03   ` Jernej Skrabec
2018-06-28  2:30   ` Chen-Yu Tsai
2018-06-28  2:30     ` Chen-Yu Tsai
2018-06-28  2:30     ` Chen-Yu Tsai
2018-06-25 12:03 ` [PATCH v3 21/24] drm: of: Export drm_crtc_port_mask() Jernej Skrabec
2018-06-25 12:03   ` Jernej Skrabec
2018-06-25 12:03   ` Jernej Skrabec
2018-06-28  2:32   ` Chen-Yu Tsai
2018-06-28  2:32     ` Chen-Yu Tsai
2018-06-28  2:32     ` Chen-Yu Tsai
2018-06-25 12:03 ` [PATCH v3 22/24] drm/sun4i: DW HDMI: Expand algorithm for possible crtcs Jernej Skrabec
2018-06-25 12:03   ` Jernej Skrabec
2018-06-25 12:03   ` Jernej Skrabec
2018-06-28  2:42   ` Chen-Yu Tsai
2018-06-28  2:42     ` Chen-Yu Tsai
2018-06-28  2:42     ` Chen-Yu Tsai
2018-06-25 12:03 ` [PATCH v3 23/24] ARM: dts: sun8i: r40: Add HDMI pipeline Jernej Skrabec
2018-06-25 12:03   ` Jernej Skrabec
2018-06-25 12:03   ` Jernej Skrabec
2018-06-28  2:50   ` Chen-Yu Tsai
2018-06-28  2:50     ` Chen-Yu Tsai
2018-06-28  2:50     ` Chen-Yu Tsai
2018-06-28  5:15     ` Jernej Škrabec
2018-06-28  5:15       ` Jernej Škrabec
2018-06-28  5:15       ` Jernej Škrabec
2018-06-28  6:51       ` [linux-sunxi] " Chen-Yu Tsai
2018-06-28  6:51         ` Chen-Yu Tsai
2018-06-28  6:51         ` Chen-Yu Tsai
2018-07-01 10:41         ` [linux-sunxi] " Jernej Škrabec
2018-07-01 10:41           ` Jernej Škrabec
2018-07-01 10:41           ` Jernej Škrabec
2018-07-01 13:52           ` [linux-sunxi] " Chen-Yu Tsai
2018-07-01 13:52             ` Chen-Yu Tsai
2018-07-01 13:52             ` Chen-Yu Tsai
2018-07-01 15:13             ` [linux-sunxi] " Jernej Škrabec
2018-07-01 15:13               ` Jernej Škrabec
2018-07-01 15:13               ` Jernej Škrabec
2018-07-01 15:35               ` [linux-sunxi] " Chen-Yu Tsai
2018-07-01 15:35                 ` Chen-Yu Tsai
2018-07-01 15:35                 ` Chen-Yu Tsai
2018-07-01 19:25                 ` [linux-sunxi] " Jernej Škrabec
2018-07-01 19:25                   ` Jernej Škrabec
2018-07-01 19:25                   ` Jernej Škrabec
2018-07-02 21:39                   ` [linux-sunxi] " Jernej Škrabec
2018-07-02 21:39                     ` Jernej Škrabec
2018-07-02 21:39                     ` Jernej Škrabec
2018-07-02 21:39                     ` Jernej Škrabec
2018-06-25 12:03 ` [PATCH v3 24/24] ARM: dts: sun8i: r40: Enable HDMI output on BananaPi M2 Ultra Jernej Skrabec
2018-06-25 12:03   ` Jernej Skrabec
2018-06-25 12:03   ` Jernej Skrabec
2018-06-28  2:51   ` [linux-sunxi] " Chen-Yu Tsai
2018-06-28  2:51     ` Chen-Yu Tsai
2018-06-28  2:51     ` Chen-Yu Tsai
2018-06-25 12:07 ` [linux-sunxi] [PATCH v3 00/24] Add support for R40 HDMI pipeline Jernej Škrabec
2018-06-25 12:07   ` Jernej Škrabec
2018-06-25 12:07   ` Jernej Škrabec
2018-06-25 16:43 ` Maxime Ripard
2018-06-25 16:43   ` Maxime Ripard
2018-06-25 16:43   ` Maxime Ripard
2018-06-27 18:02 ` Maxime Ripard
2018-06-27 18:02   ` Maxime Ripard
2018-06-27 18:02   ` Maxime Ripard
2018-06-27 19:50   ` Maxime Ripard
2018-06-27 19:50     ` Maxime Ripard
2018-06-27 19:50     ` Maxime Ripard
2018-06-27 20:25     ` Jernej Škrabec
2018-06-27 20:25       ` Jernej Škrabec
2018-06-27 20:25       ` Jernej Škrabec
2018-06-28  8:41       ` Maxime Ripard
2018-06-28  8:41         ` Maxime Ripard
2018-06-28  8:41         ` Maxime Ripard

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180625120304.7543-20-jernej.skrabec@siol.net \
    --to=jernej.skrabec@siol.net \
    --cc=airlied@linux.ie \
    --cc=devicetree@vger.kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gustavo@padovan.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sunxi@googlegroups.com \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=mark.rutland@arm.com \
    --cc=maxime.ripard@bootlin.com \
    --cc=robh+dt@kernel.org \
    --cc=seanpaul@chromium.org \
    --cc=wens@csie.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.