phy: rockchip-inno-mipi-dphy: use phy_set_bus_width() to set the lane mbps
[firefly-linux-kernel-4.4.55.git] / drivers / phy / phy-rockchip-inno-mipi-dphy.c
index 9a3a670d3154a187ca9fe1d4e12ecfbdccd8ec31..648cd2e07b17e5ecd4895e43b84b27df0a3aab0f 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/phy/phy.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
+#include <linux/reset.h>
 
 #include <drm/drm_mipi_dsi.h>
 
@@ -233,9 +234,11 @@ struct dsi_panel {
 
 struct inno_mipi_dphy {
        struct device *dev;
+       struct phy *phy;
        void __iomem *regs;
        struct clk *ref_clk;
        struct clk *pclk;
+       struct reset_control *rst;
 
        struct dsi_panel *panel;
        u32 lanes;
@@ -473,7 +476,8 @@ static void inno_mipi_dphy_pll_init(struct inno_mipi_dphy *inno)
                        break;
        }
 
-       inno->lane_mbps = pllref / prediv * fbdiv;
+       inno->lane_mbps = pllref * fbdiv / prediv;
+       phy_set_bus_width(inno->phy, inno->lane_mbps);
 
        mask = M_FBDIV_8 | M_PREDIV;
        val = V_FBDIV_8(fbdiv >> 8) | V_PREDIV(prediv);
@@ -560,6 +564,13 @@ static int inno_mipi_dphy_power_on(struct phy *phy)
        clk_prepare_enable(inno->ref_clk);
        clk_prepare_enable(inno->pclk);
 
+       if (inno->rst) {
+               /* MIPI DSI PHY APB software reset request. */
+               reset_control_assert(inno->rst);
+               usleep_range(20, 40);
+               reset_control_deassert(inno->rst);
+       }
+
        inno_mipi_dphy_pll_init(inno);
        inno_mipi_dphy_pll_ldo_enable(inno);
        inno_mipi_dphy_lane_enable(inno);
@@ -665,7 +676,6 @@ static int inno_mipi_dphy_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
        struct inno_mipi_dphy *inno;
-       struct phy *phy;
        struct phy_provider *phy_provider;
        struct resource *res;
        int ret;
@@ -693,19 +703,27 @@ static int inno_mipi_dphy_probe(struct platform_device *pdev)
                return PTR_ERR(inno->ref_clk);
        }
 
+       clk_set_rate(inno->ref_clk, 24000000);
+
        inno->pclk = devm_clk_get(&pdev->dev, "pclk");
        if (IS_ERR(inno->pclk)) {
                dev_err(&pdev->dev, "failed to get mipi dphy pclk\n");
                return PTR_ERR(inno->pclk);
-       };
+       }
+
+       inno->rst = devm_reset_control_get_optional(&pdev->dev, "apb");
+       if (IS_ERR(inno->rst)) {
+               dev_info(&pdev->dev, "No reset control specified\n");
+               inno->rst = NULL;
+       }
 
-       phy = devm_phy_create(&pdev->dev, NULL, &inno_mipi_dphy_ops);
-       if (IS_ERR(phy)) {
+       inno->phy = devm_phy_create(&pdev->dev, NULL, &inno_mipi_dphy_ops);
+       if (IS_ERR(inno->phy)) {
                dev_err(&pdev->dev, "failed to create MIPI D-PHY\n");
-               return PTR_ERR(phy);
+               return PTR_ERR(inno->phy);
        }
 
-       phy_set_drvdata(phy, inno);
+       phy_set_drvdata(inno->phy, inno);
 
        phy_provider = devm_of_phy_provider_register(&pdev->dev,
                                                     of_phy_simple_xlate);