aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/rockchip
diff options
context:
space:
mode:
authorMark Yao <mark.yao@rock-chips.com>2017-06-09 15:10:41 +0800
committerMark Yao <mark.yao@rock-chips.com>2017-06-23 08:52:03 +0800
commit5e3bc6d1ab48a20cbce3d59d42937bc977ec61cf (patch)
treefd9f992c12f98a8004540d3b1b529955fac96dcf /drivers/gpu/drm/rockchip
parentdrm/rockchip: dw_hdmi: add RK3399 HDMI support (diff)
downloadlinux-dev-5e3bc6d1ab48a20cbce3d59d42937bc977ec61cf.tar.xz
linux-dev-5e3bc6d1ab48a20cbce3d59d42937bc977ec61cf.zip
drm/rockchip: dw_hdmi: introduce the VPLL clock setting
For RK3399 HDMI, there is an external clock need for HDMI PHY, and it should keep the same clock rate with VOP DCLK. VPLL have supported the clock for HDMI PHY, but there is no clock divider bewteen VPLL and HDMI PHY. So we need to set the VPLL rate manually in HDMI driver. Signed-off-by: Yakir Yang <ykk@rock-chips.com> Signed-off-by: Mark Yao <mark.yao@rock-chips.com> Acked-by: Rob Herring <robh@kernel.org>
Diffstat (limited to 'drivers/gpu/drm/rockchip')
-rw-r--r--drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
index e7bab14134da..c00d7e273e84 100644
--- a/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
+++ b/drivers/gpu/drm/rockchip/dw_hdmi-rockchip.c
@@ -7,10 +7,12 @@
* (at your option) any later version.
*/
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/platform_device.h>
-#include <linux/mfd/syscon.h>
#include <linux/regmap.h>
+
#include <drm/drm_of.h>
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
@@ -44,6 +46,7 @@ struct rockchip_hdmi {
struct regmap *regmap;
struct drm_encoder encoder;
const struct rockchip_hdmi_chip_data *chip_data;
+ struct clk *vpll_clk;
};
#define to_rockchip_hdmi(x) container_of(x, struct rockchip_hdmi, x)
@@ -160,6 +163,7 @@ static const struct dw_hdmi_phy_config rockchip_phy_config[] = {
static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
{
struct device_node *np = hdmi->dev->of_node;
+ int ret;
hdmi->regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
if (IS_ERR(hdmi->regmap)) {
@@ -167,6 +171,22 @@ static int rockchip_hdmi_parse_dt(struct rockchip_hdmi *hdmi)
return PTR_ERR(hdmi->regmap);
}
+ hdmi->vpll_clk = devm_clk_get(hdmi->dev, "vpll");
+ if (PTR_ERR(hdmi->vpll_clk) == -ENOENT) {
+ hdmi->vpll_clk = NULL;
+ } else if (PTR_ERR(hdmi->vpll_clk) == -EPROBE_DEFER) {
+ return -EPROBE_DEFER;
+ } else if (IS_ERR(hdmi->vpll_clk)) {
+ dev_err(hdmi->dev, "failed to get grf clock\n");
+ return PTR_ERR(hdmi->vpll_clk);
+ }
+
+ ret = clk_prepare_enable(hdmi->vpll_clk);
+ if (ret) {
+ dev_err(hdmi->dev, "Failed to enable HDMI vpll: %d\n", ret);
+ return ret;
+ }
+
return 0;
}
@@ -209,6 +229,9 @@ static void dw_hdmi_rockchip_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adj_mode)
{
+ struct rockchip_hdmi *hdmi = to_rockchip_hdmi(encoder);
+
+ clk_set_rate(hdmi->vpll_clk, adj_mode->clock * 1000);
}
static void dw_hdmi_rockchip_encoder_enable(struct drm_encoder *encoder)