From d982bbe9bbcba01f3ecc81c4bb7a75e9cda03208 Mon Sep 17 00:00:00 2001 From: Wyon Bi Date: Tue, 4 Jun 2019 15:46:21 +0800 Subject: [PATCH] phy/rockchip: inno-video-phy: Fix phy poweron failed in TTL mode Don't enable PLL in TTL mode, it's only validated for LVDS mode. [ 4.193355] inno-video-phy ff96c000.video-phy: PLL is not lock [ 4.193380] phy phy-ff96c000.video-phy.3: phy poweron failed --> -110 Change-Id: I353aebcaee5c53d675f9052c29c9e3c205c4ff4a Signed-off-by: Wyon Bi --- .../rockchip/phy-rockchip-inno-video-phy.c | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/drivers/phy/rockchip/phy-rockchip-inno-video-phy.c b/drivers/phy/rockchip/phy-rockchip-inno-video-phy.c index 65b152535870..0d8269aef562 100644 --- a/drivers/phy/rockchip/phy-rockchip-inno-video-phy.c +++ b/drivers/phy/rockchip/phy-rockchip-inno-video-phy.c @@ -80,34 +80,20 @@ static const struct reg_sequence lvds_mode_dual_channel[] = { { 0x0180, 0x44 }, }; -static int inno_video_phy_power_on(struct phy *phy) +static int inno_video_phy_lvds_mode_enable(struct inno_video_phy *inno, + bool dual_channel) { - struct inno_video_phy *inno = phy_get_drvdata(phy); const struct reg_sequence *wseq; - bool dual_channel = phy_get_bus_width(phy) == 2 ? true : false; int nregs; u32 status; int ret; - clk_prepare_enable(inno->pclk); - pm_runtime_get_sync(inno->dev); - - switch (inno->mode) { - case PHY_MODE_VIDEO_LVDS: - if (dual_channel) { - wseq = lvds_mode_dual_channel; - nregs = ARRAY_SIZE(lvds_mode_dual_channel); - } else { - wseq = lvds_mode_single_channel; - nregs = ARRAY_SIZE(lvds_mode_single_channel); - } - break; - case PHY_MODE_VIDEO_TTL: - wseq = ttl_mode; - nregs = ARRAY_SIZE(ttl_mode); - break; - default: - return -EINVAL; + if (dual_channel) { + wseq = lvds_mode_dual_channel; + nregs = ARRAY_SIZE(lvds_mode_dual_channel); + } else { + wseq = lvds_mode_single_channel; + nregs = ARRAY_SIZE(lvds_mode_single_channel); } regmap_multi_reg_write(inno->regmap, wseq, nregs); @@ -125,6 +111,28 @@ static int inno_video_phy_power_on(struct phy *phy) return 0; } +static int inno_video_phy_power_on(struct phy *phy) +{ + struct inno_video_phy *inno = phy_get_drvdata(phy); + + clk_prepare_enable(inno->pclk); + pm_runtime_get_sync(inno->dev); + + switch (inno->mode) { + case PHY_MODE_VIDEO_LVDS: + return inno_video_phy_lvds_mode_enable(inno, + phy_get_bus_width(phy) == 2 ? true : false); + case PHY_MODE_VIDEO_TTL: + regmap_multi_reg_write(inno->regmap, ttl_mode, + ARRAY_SIZE(ttl_mode)); + break; + default: + return -EINVAL; + } + + return 0; +} + static int inno_video_phy_power_off(struct phy *phy) { struct inno_video_phy *inno = phy_get_drvdata(phy);