USB and SATA DPLLs need different settings. Provide
the SATA DPLL settings and use the proper DPLL settings
based on device tree compatible_id.

Signed-off-by: Roger Quadros <rog...@ti.com>
---
 drivers/phy/phy-omap-pipe3.c   |   82 ++++++++++++++++++++++++++--------------
 include/linux/phy/omap_pipe3.h |    6 +++
 2 files changed, 60 insertions(+), 28 deletions(-)

diff --git a/drivers/phy/phy-omap-pipe3.c b/drivers/phy/phy-omap-pipe3.c
index 807ab8a..19d1664 100644
--- a/drivers/phy/phy-omap-pipe3.c
+++ b/drivers/phy/phy-omap-pipe3.c
@@ -58,29 +58,41 @@
  */
 # define PLL_IDLE_TIME  100;
 
-struct pipe3_dpll_map {
-       unsigned long rate;
-       struct pipe3_dpll_params params;
-};
-
-static struct pipe3_dpll_map dpll_map[] = {
+static struct pipe3_dpll_map dpll_map_usb[] = {
        {12000000, {1250, 5, 4, 20, 0} },       /* 12 MHz */
        {16800000, {3125, 20, 4, 20, 0} },      /* 16.8 MHz */
        {19200000, {1172, 8, 4, 20, 65537} },   /* 19.2 MHz */
        {20000000, {1000, 7, 4, 10, 0} },       /* 20 MHz */
        {26000000, {1250, 12, 4, 20, 0} },      /* 26 MHz */
        {38400000, {3125, 47, 4, 20, 92843} },  /* 38.4 MHz */
+       { },                                    /* Terminator */
+};
+
+static struct pipe3_dpll_map dpll_map_sata[] = {
+       {12000000, {1000, 7, 4, 6, 0} },        /* 12 MHz */
+       {16800000, {714, 7, 4, 6, 0} },         /* 16.8 MHz */
+       {19200000, {625, 7, 4, 6, 0} },         /* 19.2 MHz */
+       {20000000, {600, 7, 4, 6, 0} },         /* 20 MHz */
+       {26000000, {461, 7, 4, 6, 0} },         /* 26 MHz */
+       {38400000, {312, 7, 4, 6, 0} },         /* 38.4 MHz */
+       { },                                    /* Terminator */
 };
 
-static struct pipe3_dpll_params *omap_pipe3_get_dpll_params(unsigned long rate)
+static struct pipe3_dpll_params *omap_pipe3_get_dpll_params(struct omap_pipe3
+                                                                       *pipe3)
 {
-       int i;
+       unsigned long rate;
+       struct pipe3_dpll_map *dpll_map = pipe3->dpll_map;
 
-       for (i = 0; i < ARRAY_SIZE(dpll_map); i++) {
-               if (rate == dpll_map[i].rate)
-                       return &dpll_map[i].params;
+       rate = clk_get_rate(pipe3->sys_clk);
+
+       for (; dpll_map->rate; dpll_map++) {
+               if (rate == dpll_map->rate)
+                       return &dpll_map->params;
        }
 
+       dev_err(pipe3->dev,
+                 "No DPLL configuration for %lu Hz SYS CLK\n", rate);
        return 0;
 }
 
@@ -148,10 +160,8 @@ static int omap_pipe3_dpll_lock(struct omap_pipe3 *phy)
        struct pipe3_dpll_params *dpll_params;
 
        rate = clk_get_rate(phy->sys_clk);
-       dpll_params = omap_pipe3_get_dpll_params(rate);
+       dpll_params = omap_pipe3_get_dpll_params(phy);
        if (!dpll_params) {
-               dev_err(phy->dev,
-                         "No DPLL configuration for %lu Hz SYS CLK\n", rate);
                return -EINVAL;
        }
 
@@ -206,6 +216,25 @@ static struct phy_ops ops = {
        .owner          = THIS_MODULE,
 };
 
+#ifdef CONFIG_OF
+static const struct of_device_id omap_pipe3_id_table[] = {
+       {
+               .compatible = "ti,omap-pipe3",
+               .data = dpll_map_usb,
+       },
+       {
+               .compatible = "ti,omap-sata",
+               .data = dpll_map_sata,
+       },
+       {
+               .compatible = "ti,omap-usb3",
+               .data = dpll_map_usb,
+       },
+       {},
+};
+MODULE_DEVICE_TABLE(of, omap_pipe3_id_table);
+#endif
+
 static int omap_pipe3_probe(struct platform_device *pdev)
 {
        struct omap_pipe3 *phy;
@@ -215,9 +244,7 @@ static int omap_pipe3_probe(struct platform_device *pdev)
        struct device_node *node = pdev->dev.of_node;
        struct device_node *control_node;
        struct platform_device *control_pdev;
-
-       if (!node)
-               return -EINVAL;
+       const struct of_device_id *match;
 
        phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
        if (!phy) {
@@ -225,6 +252,16 @@ static int omap_pipe3_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
+       match = of_match_device(of_match_ptr(omap_pipe3_id_table), &pdev->dev);
+       if (!match)
+               return -EINVAL;
+
+       phy->dpll_map = (struct pipe3_dpll_map *)match->data;
+       if (!phy->dpll_map) {
+               dev_err(&pdev->dev, "no dpll data\n");
+               return -EINVAL;
+       }
+
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl");
        phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res);
        if (IS_ERR(phy->pll_ctrl_base))
@@ -354,17 +391,6 @@ static const struct dev_pm_ops omap_pipe3_pm_ops = {
 #define DEV_PM_OPS     NULL
 #endif
 
-#ifdef CONFIG_OF
-static const struct of_device_id omap_pipe3_id_table[] = {
-       { .compatible = "ti,omap-pipe3" },
-       { .compatible = "ti,omap-sata" },
-       { .compatible = "ti,omap-pcie" },
-       { .compatible = "ti,omap-usb3" },
-       {}
-};
-MODULE_DEVICE_TABLE(of, omap_pipe3_id_table);
-#endif
-
 static struct platform_driver omap_pipe3_driver = {
        .probe          = omap_pipe3_probe,
        .remove         = omap_pipe3_remove,
diff --git a/include/linux/phy/omap_pipe3.h b/include/linux/phy/omap_pipe3.h
index 7329056..86825ca 100644
--- a/include/linux/phy/omap_pipe3.h
+++ b/include/linux/phy/omap_pipe3.h
@@ -29,6 +29,11 @@ struct pipe3_dpll_params {
        u32     mf;
 };
 
+struct pipe3_dpll_map {
+       unsigned long rate;
+       struct pipe3_dpll_params params;
+};
+
 struct omap_pipe3 {
        void __iomem            *pll_ctrl_base;
        struct device           *dev;
@@ -36,6 +41,7 @@ struct omap_pipe3 {
        struct clk              *wkupclk;
        struct clk              *sys_clk;
        struct clk              *optclk;
+       struct pipe3_dpll_map   *dpll_map;
 };
 
 static inline u32 omap_pipe3_readl(void __iomem *addr, unsigned offset)
-- 
1.7.4.1

--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to