From: WeiYong Bi Date: Sat, 25 Mar 2017 03:13:55 +0000 (+0800) Subject: phy: rockchip-dp: Add support for rk3368 Display Port PHY X-Git-Tag: firefly_0821_release~221 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=2404f87aa5386bcc82f9420b04d7301205f6d3e8;p=firefly-linux-kernel-4.4.55.git phy: rockchip-dp: Add support for rk3368 Display Port PHY Change-Id: Ic2134ba719dadba121dc2fcc944662ef06b2ecfa Signed-off-by: WeiYong Bi --- diff --git a/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt b/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt index e3b4809fbe82..b837bb828329 100644 --- a/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt +++ b/Documentation/devicetree/bindings/phy/rockchip-dp-phy.txt @@ -4,14 +4,21 @@ Rockchip specific extensions to the Analogix Display Port PHY Required properties: - compatible : should be one of the following supported values: - "rockchip.rk3288-dp-phy" + - "rockchip.rk3368-dp-phy" - clocks: from common clock binding: handle to dp clock. of memory mapped region. - clock-names: from common clock binding: Required elements: "24m" - #phy-cells : from the generic PHY bindings, must be 0; +Optional properties + - resets : phandle to the reset of eDP 24m clock domain. + - reset-names : should be "edp_24m". + Example: +For Rockchip RK3288: + grf: syscon@ff770000 { compatible = "rockchip,rk3288-grf", "syscon", "simple-mfd"; @@ -24,3 +31,20 @@ grf: syscon@ff770000 { #phy-cells = <0>; }; }; + +For Rockchip RK3368: + +grf: syscon@ff770000 { + compatible = "rockchip,rk3368-grf", "syscon", "simple-mfd"; + +... + + edp_phy: edp-phy { + compatible = "rockchip,rk3368-dp-phy"; + clocks = <&cru SCLK_EDP_24M>; + clock-names = "24m"; + resets = <&cru SRST_EDP_24M>; + reset-names = "edp_24m"; + #phy-cells = <0>; + }; +}; diff --git a/drivers/phy/phy-rockchip-dp.c b/drivers/phy/phy-rockchip-dp.c index 793ecb6d87bc..79576e99ab3e 100644 --- a/drivers/phy/phy-rockchip-dp.c +++ b/drivers/phy/phy-rockchip-dp.c @@ -10,37 +10,47 @@ */ #include +#include #include #include #include +#include #include #include #include +#include -#define GRF_SOC_CON12 0x0274 - -#define GRF_EDP_REF_CLK_SEL_INTER_HIWORD_MASK BIT(20) -#define GRF_EDP_REF_CLK_SEL_INTER BIT(4) - -#define GRF_EDP_PHY_SIDDQ_HIWORD_MASK BIT(21) -#define GRF_EDP_PHY_SIDDQ_ON 0 -#define GRF_EDP_PHY_SIDDQ_OFF BIT(5) +struct rockchip_dp_phy_drv_data { + u32 grf_reg_offset; + u32 ref_clk_sel_inter; + u32 siddq_on; + u32 siddq_off; +}; struct rockchip_dp_phy { struct device *dev; struct regmap *grf; struct clk *phy_24m; + struct reset_control *rst_24m; + + const struct rockchip_dp_phy_drv_data *drv_data; }; static int rockchip_set_phy_state(struct phy *phy, bool enable) { struct rockchip_dp_phy *dp = phy_get_drvdata(phy); + const struct rockchip_dp_phy_drv_data *drv_data = dp->drv_data; int ret; if (enable) { - ret = regmap_write(dp->grf, GRF_SOC_CON12, - GRF_EDP_PHY_SIDDQ_HIWORD_MASK | - GRF_EDP_PHY_SIDDQ_ON); + /* EDP 24m clock domain software reset request. */ + reset_control_assert(dp->rst_24m); + usleep_range(20, 40); + reset_control_deassert(dp->rst_24m); + usleep_range(20, 40); + + ret = regmap_write(dp->grf, drv_data->grf_reg_offset, + drv_data->siddq_on); if (ret < 0) { dev_err(dp->dev, "Can't enable PHY power %d\n", ret); return ret; @@ -50,9 +60,8 @@ static int rockchip_set_phy_state(struct phy *phy, bool enable) } else { clk_disable_unprepare(dp->phy_24m); - ret = regmap_write(dp->grf, GRF_SOC_CON12, - GRF_EDP_PHY_SIDDQ_HIWORD_MASK | - GRF_EDP_PHY_SIDDQ_OFF); + ret = regmap_write(dp->grf, drv_data->grf_reg_offset, + drv_data->siddq_off); } return ret; @@ -80,6 +89,7 @@ static int rockchip_dp_phy_probe(struct platform_device *pdev) struct device_node *np = dev->of_node; struct phy_provider *phy_provider; struct rockchip_dp_phy *dp; + const struct rockchip_dp_phy_drv_data *drv_data; struct phy *phy; int ret; @@ -89,11 +99,18 @@ static int rockchip_dp_phy_probe(struct platform_device *pdev) if (!dev->parent || !dev->parent->of_node) return -ENODEV; + drv_data = of_device_get_match_data(dev); + if (!drv_data) { + dev_err(dev, "No OF match data provided\n"); + return -EINVAL; + } + dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL); if (IS_ERR(dp)) return -ENOMEM; dp->dev = dev; + dp->drv_data = drv_data; dp->phy_24m = devm_clk_get(dev, "24m"); if (IS_ERR(dp->phy_24m)) { @@ -107,15 +124,22 @@ static int rockchip_dp_phy_probe(struct platform_device *pdev) return ret; } + /* optional */ + dp->rst_24m = devm_reset_control_get_optional(&pdev->dev, "edp_24m"); + if (IS_ERR(dp->rst_24m)) { + dev_info(dev, "No edp_24m reset control specified\n"); + dp->rst_24m = NULL; + } + dp->grf = syscon_node_to_regmap(dev->parent->of_node); if (IS_ERR(dp->grf)) { dev_err(dev, "rk3288-dp needs the General Register Files syscon\n"); return PTR_ERR(dp->grf); } - ret = regmap_write(dp->grf, GRF_SOC_CON12, GRF_EDP_REF_CLK_SEL_INTER | - GRF_EDP_REF_CLK_SEL_INTER_HIWORD_MASK); - if (ret != 0) { + ret = regmap_write(dp->grf, drv_data->grf_reg_offset, + drv_data->ref_clk_sel_inter); + if (ret) { dev_err(dp->dev, "Could not config GRF edp ref clk: %d\n", ret); return ret; } @@ -132,8 +156,25 @@ static int rockchip_dp_phy_probe(struct platform_device *pdev) return PTR_ERR_OR_ZERO(phy_provider); } +static const struct rockchip_dp_phy_drv_data rk3288_dp_phy_drv_data = { + .grf_reg_offset = 0x274, + .ref_clk_sel_inter = BIT(4) | BIT(20), + .siddq_on = 0 | BIT(21), + .siddq_off = BIT(5) | BIT(21), +}; + +static const struct rockchip_dp_phy_drv_data rk3368_dp_phy_drv_data = { + .grf_reg_offset = 0x410, + .ref_clk_sel_inter = BIT(0) | BIT(16), + .siddq_on = 0 | BIT(17), + .siddq_off = BIT(1) | BIT(17), +}; + static const struct of_device_id rockchip_dp_phy_dt_ids[] = { - { .compatible = "rockchip,rk3288-dp-phy" }, + { .compatible = "rockchip,rk3288-dp-phy", + .data = &rk3288_dp_phy_drv_data }, + { .compatible = "rockchip,rk3368-dp-phy", + .data = &rk3368_dp_phy_drv_data }, {} };