From: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
To: Maxime Ripard
<maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>,
Chen-Yu Tsai <wens-jdAy2FN1RRM@public.gmane.org>,
Icenowy Zheng <icenowy-h8G6r0blFSE@public.gmane.org>,
Jernej Skrabec <jernej.skrabec-gGgVlfcn5nU@public.gmane.org>,
Rob Herring <robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>,
Catalin Marinas <catalin.marinas-5wv7dgnIgG8@public.gmane.org>,
Will Deacon <will.deacon-5wv7dgnIgG8@public.gmane.org>,
David Airlie <airlied-cv59FeDIM0c@public.gmane.org>,
dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
Michael Turquette
<mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>,
Stephen Boyd <sboyd-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Michael Trimarchi
<michael-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org
Cc: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
Subject: [PATCH v2 12/26] drm/sun4i: Add support for multiple DW HDMI PHY clock parents
Date: Fri, 18 May 2018 15:15:22 +0530 [thread overview]
Message-ID: <20180518094536.17201-13-jagan@amarulasolutions.com> (raw)
In-Reply-To: <20180518094536.17201-1-jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
From: Jernej Skrabec <jernej.skrabec-gGgVlfcn5nU@public.gmane.org>
Some SoCs with DW HDMI have multiple possible clock parents, like A64
and R40.
Expand HDMI PHY clock driver to support second clock parent.
Signed-off-by: Jernej Skrabec <jernej.skrabec-gGgVlfcn5nU@public.gmane.org>
Signed-off-by: Jagan Teki <jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
---
Changes for v2:
- new patch
drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h | 9 ++-
drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c | 33 ++++++++---
drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c | 89 ++++++++++++++++++++++--------
3 files changed, 96 insertions(+), 35 deletions(-)
diff --git a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
index 79154f0f674a..303189d6602c 100644
--- a/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
+++ b/drivers/gpu/drm/sun4i/sun8i_dw_hdmi.h
@@ -98,7 +98,8 @@
#define SUN8I_HDMI_PHY_PLL_CFG1_LDO2_EN BIT(29)
#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 BIT(26)
+#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)
@@ -146,7 +147,7 @@
struct sun8i_hdmi_phy;
struct sun8i_hdmi_phy_variant {
- bool has_phy_clk;
+ int phy_clk_num;
void (*phy_init)(struct sun8i_hdmi_phy *phy);
void (*phy_disable)(struct dw_hdmi *hdmi,
struct sun8i_hdmi_phy *phy);
@@ -160,6 +161,7 @@ struct sun8i_hdmi_phy {
struct clk *clk_mod;
struct clk *clk_phy;
struct clk *clk_pll0;
+ struct clk *clk_pll1;
unsigned int rcal;
struct regmap *regs;
struct reset_control *rst_phy;
@@ -188,6 +190,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,
+ int clk_num);
#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 5a52fc489a9d..0eadf087fc46 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy.c
@@ -183,7 +183,13 @@ static int sun8i_hdmi_phy_config_h3(struct dw_hdmi *hdmi,
regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_ANA_CFG1_REG,
SUN8I_HDMI_PHY_ANA_CFG1_TXEN_MASK, 0);
- regmap_write(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG, pll_cfg1_init);
+ /*
+ * NOTE: We have to be careful not to overwrite PHY parent
+ * clock selection bit and clock divider.
+ */
+ regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG1_REG,
+ (u32)~SUN8I_HDMI_PHY_PLL_CFG1_CKIN_SEL_MSK,
+ pll_cfg1_init);
regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_PLL_CFG2_REG,
(u32)~SUN8I_HDMI_PHY_PLL_CFG2_PREDIV_MSK,
pll_cfg2_init);
@@ -232,7 +238,7 @@ static int sun8i_hdmi_phy_config(struct dw_hdmi *hdmi, void *data,
regmap_update_bits(phy->regs, SUN8I_HDMI_PHY_DBG_CTRL_REG,
SUN8I_HDMI_PHY_DBG_CTRL_POL_MASK, val);
- if (phy->variant->has_phy_clk)
+ if (phy->variant->phy_clk_num)
clk_set_rate(phy->clk_phy, mode->crtc_clock * 1000);
return phy->variant->phy_config(hdmi, phy, mode->crtc_clock * 1000);
@@ -393,7 +399,7 @@ static const struct sun8i_hdmi_phy_variant sun8i_a83t_hdmi_phy = {
};
static const struct sun8i_hdmi_phy_variant sun8i_h3_hdmi_phy = {
- .has_phy_clk = true,
+ .phy_clk_num = 1,
.phy_init = &sun8i_hdmi_phy_init_h3,
.phy_disable = &sun8i_hdmi_phy_disable_h3,
.phy_config = &sun8i_hdmi_phy_config_h3,
@@ -464,7 +470,7 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
goto err_put_clk_bus;
}
- if (phy->variant->has_phy_clk) {
+ if (phy->variant->phy_clk_num) {
phy->clk_pll0 = of_clk_get_by_name(node, "pll-0");
if (IS_ERR(phy->clk_pll0)) {
dev_err(dev, "Could not get pll-0 clock\n");
@@ -472,7 +478,16 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
goto err_put_clk_mod;
}
- ret = sun8i_phy_clk_create(phy, dev);
+ if (phy->variant->phy_clk_num) {
+ phy->clk_pll1 = of_clk_get_by_name(node, "pll-1");
+ if (IS_ERR(phy->clk_pll1)) {
+ dev_err(dev, "Could not get pll-1 clock\n");
+ ret = PTR_ERR(phy->clk_pll1);
+ goto err_put_clk_mod;
+ }
+ }
+
+ ret = sun8i_phy_clk_create(phy, dev, phy->variant->phy_clk_num);
if (ret) {
dev_err(dev, "Couldn't create the PHY clock\n");
goto err_put_clk_pll0;
@@ -515,8 +530,8 @@ int sun8i_hdmi_phy_probe(struct sun8i_dw_hdmi *hdmi, struct device_node *node)
err_put_rst_phy:
reset_control_put(phy->rst_phy);
err_put_clk_pll0:
- if (phy->variant->has_phy_clk)
- clk_put(phy->clk_pll0);
+ clk_put(phy->clk_pll0);
+ clk_put(phy->clk_pll1);
err_put_clk_mod:
clk_put(phy->clk_mod);
err_put_clk_bus:
@@ -536,8 +551,8 @@ void sun8i_hdmi_phy_remove(struct sun8i_dw_hdmi *hdmi)
reset_control_put(phy->rst_phy);
- if (phy->variant->has_phy_clk)
- clk_put(phy->clk_pll0);
+ clk_put(phy->clk_pll0);
+ clk_put(phy->clk_pll1);
clk_put(phy->clk_mod);
clk_put(phy->clk_bus);
}
diff --git a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
index faea449812f8..85b12fc96dbc 100644
--- a/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
+++ b/drivers/gpu/drm/sun4i/sun8i_hdmi_phy_clk.c
@@ -22,29 +22,36 @@ static int sun8i_phy_clk_determine_rate(struct clk_hw *hw,
{
unsigned long rate = req->rate;
unsigned long best_rate = 0;
- struct clk_hw *parent;
+ struct clk_hw *best_parent = NULL;
+ struct clk_hw *parent = NULL;
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);
-
- if (rounded == ideal) {
- best_rate = rounded;
- best_div = i;
- break;
- }
+ for (p = 0; p < clk_hw_get_num_parents(hw); p++) {
+ parent = clk_hw_get_parent_by_index(hw, p);
+ if (!parent)
+ continue;
- if (!best_rate ||
- abs(rate - rounded / i) <
- abs(rate - best_rate / best_div)) {
- best_rate = rounded;
- best_div = i;
+ 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;
+ }
}
}
@@ -95,22 +102,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 & 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,
+ int clk_num)
{
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 (clk_num == 2) {
+ 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 +161,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 = clk_num;
init.flags = CLK_SET_RATE_PARENT;
priv->phy = phy;
--
2.14.3
next prev parent reply other threads:[~2018-05-18 9:45 UTC|newest]
Thread overview: 42+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-18 9:45 [PATCH v2 00/26] arm64: allwinner: Add A64 DE2 HDMI support Jagan Teki
[not found] ` <20180518094536.17201-1-jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
2018-05-18 9:45 ` [PATCH v2 01/26] dt-bindings: clock: Add compatible for A64 DE2 CCU Jagan Teki
2018-05-18 9:45 ` [PATCH v2 02/26] arm64: dts: allwinner: a64: Add " Jagan Teki
2018-05-18 9:45 ` [PATCH v2 03/26] clk: sunxi-ng: Enable DE2_CCU for SUN8I and SUN50I Jagan Teki
2018-05-18 9:45 ` [PATCH v2 04/26] clk: sunxi-ng: a64: Add minimal rate for video PLLs Jagan Teki
2018-05-18 9:45 ` [PATCH v2 05/26] drm/sun4i: DE2 mixer: Add index quirk Jagan Teki
2018-05-18 9:45 ` [PATCH v2 06/26] drm/sun4i: Add support for A64 mixer1 Jagan Teki
2018-05-18 9:45 ` [PATCH v2 07/26] dt-bindings: display: Add compatible for A64 DE2 tcon1 blocks Jagan Teki
[not found] ` <20180518094536.17201-8-jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
2018-05-22 18:10 ` Rob Herring
2018-05-18 9:45 ` [PATCH v2 08/26] drm/sun4i: Add support for A64 display engine Jagan Teki
2018-05-18 9:45 ` [PATCH v2 09/26] arm64: dts: allwinner: a64: Add DE2 tcon1 pipeline Jagan Teki
2018-05-18 9:45 ` [PATCH v2 10/26] drm/sun4i: Enable DE2 Mixer for SUN8I and SUN50I Jagan Teki
2018-05-18 9:45 ` [PATCH v2 11/26] arm64: defconfig: Enable CONFIG_DRM_SUN4I Jagan Teki
2018-05-18 9:45 ` Jagan Teki [this message]
[not found] ` <20180518094536.17201-13-jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
2018-05-18 10:01 ` [PATCH v2 12/26] drm/sun4i: Add support for multiple DW HDMI PHY clock parents Maxime Ripard
2018-05-18 14:46 ` Jernej Škrabec
2018-05-18 15:09 ` Sergey Suloev
2018-05-18 15:15 ` Jernej Škrabec
2018-05-18 15:21 ` Sergey Suloev
2018-05-18 15:26 ` Maxime Ripard
2018-05-18 15:34 ` Jernej Škrabec
2018-05-19 7:11 ` Jernej Škrabec
2018-05-18 9:45 ` [PATCH v2 13/26] drm/sun4i: Add support for A64 HDMI PHY Jagan Teki
2018-05-18 9:45 ` [PATCH v2 14/26] dt-bindings: display: Add compatible for A64 HDMI Jagan Teki
[not found] ` <20180518094536.17201-15-jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
2018-05-22 18:10 ` Rob Herring
2018-05-18 9:45 ` [PATCH v2 15/26] dt-bindings: display: Add compatible for A64 HDMI PHY Jagan Teki
2018-05-18 9:45 ` [PATCH v2 16/26] dt-bindings: clock: sun50i-a64-ccu: Add PLL_VIDEO[0-1] macros Jagan Teki
[not found] ` <20180518094536.17201-17-jagan-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org>
2018-05-18 14:23 ` Rob Herring
2018-05-18 9:45 ` [PATCH v2 17/26] arm64: dts: allwinner: a64: Add HDMI support Jagan Teki
2018-05-18 9:45 ` [PATCH v2 18/26] drm/sun4i: Enable DesignWare HDMI for SUN8I and SUN50I Jagan Teki
2018-05-18 9:45 ` [PATCH v2 19/26] arm64: dts: allwinner: a64: Add HDMI pipeline Jagan Teki
2018-05-18 9:45 ` [PATCH v2 20/26] drm: sun4i: add support for HVCC regulator for DWC HDMI glue Jagan Teki
2018-05-18 9:45 ` [PATCH v2 21/26] arm64: dts: allwinner: a64: bananapi-m64: Enable HDMI output Jagan Teki
2018-05-18 9:45 ` [PATCH v2 22/26] arm64: dts: allwinner: a64: nanopi-a64: " Jagan Teki
2018-05-18 9:45 ` [PATCH v2 23/26] arm64: dts: allwinner: a64: orangepi-win: " Jagan Teki
2018-05-18 9:45 ` [PATCH v2 24/26] arm64: dts: allwinner: a64: a64-olinuxino: " Jagan Teki
2018-05-18 9:45 ` [PATCH v2 25/26] arm64: dts: allwinner: a64: pine64: " Jagan Teki
2018-05-18 9:45 ` [PATCH v2 26/26] arm64: dts: allwinner: a64: sopine: " Jagan Teki
2018-05-18 9:59 ` [PATCH v2 00/26] arm64: allwinner: Add A64 DE2 HDMI support Maxime Ripard
2018-06-05 12:53 ` Jagan Teki
[not found] ` <CAMty3ZC13J+bCWK_=9816Lu-5ctC0UfF4-XR3yNSpHdH8q8Faw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2018-06-05 13:25 ` Maxime Ripard
2018-06-05 13:58 ` [linux-sunxi] " Icenowy Zheng
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=20180518094536.17201-13-jagan@amarulasolutions.com \
--to=jagan-dyjbcgdgk7pe9whmmfpqlfatqe2ktcn/@public.gmane.org \
--cc=airlied-cv59FeDIM0c@public.gmane.org \
--cc=catalin.marinas-5wv7dgnIgG8@public.gmane.org \
--cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
--cc=icenowy-h8G6r0blFSE@public.gmane.org \
--cc=jernej.skrabec-gGgVlfcn5nU@public.gmane.org \
--cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
--cc=linux-clk-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-sunxi-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org \
--cc=mark.rutland-5wv7dgnIgG8@public.gmane.org \
--cc=maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org \
--cc=michael-dyjBcgdgk7Pe9wHmmfpqLFaTQe2KTcn/@public.gmane.org \
--cc=mturquette-rdvid1DuHRBWk0Htik3J/w@public.gmane.org \
--cc=robh+dt-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
--cc=sboyd-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
--cc=wens-jdAy2FN1RRM@public.gmane.org \
--cc=will.deacon-5wv7dgnIgG8@public.gmane.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).