aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoger Quadros <rogerq@ti.com>2014-03-07 01:13:39 -0500
committerKishon Vijay Abraham I <kishon@ti.com>2014-03-09 03:15:10 -0400
commit61f546747715683c334ef231fd648522312dc5ff (patch)
treea5134105df1218bb67fc6ea9c5ced0c0baeda8f9
parent1562864f0f034ea393230b470d104e1196b4a5f1 (diff)
phy: ti-pipe3: Add SATA DPLL support
USB and SATA DPLLs need different settings. Provide the SATA DPLL settings and use the proper DPLL settings based on device tree node's compatible_id. Signed-off-by: Roger Quadros <rogerq@ti.com> Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
-rw-r--r--drivers/phy/phy-ti-pipe3.c76
1 files changed, 55 insertions, 21 deletions
diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c
index 211703c87fb9..f141237131c3 100644
--- a/drivers/phy/phy-ti-pipe3.c
+++ b/drivers/phy/phy-ti-pipe3.c
@@ -66,6 +66,11 @@ struct pipe3_dpll_params {
66 u32 mf; 66 u32 mf;
67}; 67};
68 68
69struct pipe3_dpll_map {
70 unsigned long rate;
71 struct pipe3_dpll_params params;
72};
73
69struct ti_pipe3 { 74struct ti_pipe3 {
70 void __iomem *pll_ctrl_base; 75 void __iomem *pll_ctrl_base;
71 struct device *dev; 76 struct device *dev;
@@ -73,20 +78,27 @@ struct ti_pipe3 {
73 struct clk *wkupclk; 78 struct clk *wkupclk;
74 struct clk *sys_clk; 79 struct clk *sys_clk;
75 struct clk *refclk; 80 struct clk *refclk;
81 struct pipe3_dpll_map *dpll_map;
76}; 82};
77 83
78struct pipe3_dpll_map { 84static struct pipe3_dpll_map dpll_map_usb[] = {
79 unsigned long rate;
80 struct pipe3_dpll_params params;
81};
82
83static struct pipe3_dpll_map dpll_map[] = {
84 {12000000, {1250, 5, 4, 20, 0} }, /* 12 MHz */ 85 {12000000, {1250, 5, 4, 20, 0} }, /* 12 MHz */
85 {16800000, {3125, 20, 4, 20, 0} }, /* 16.8 MHz */ 86 {16800000, {3125, 20, 4, 20, 0} }, /* 16.8 MHz */
86 {19200000, {1172, 8, 4, 20, 65537} }, /* 19.2 MHz */ 87 {19200000, {1172, 8, 4, 20, 65537} }, /* 19.2 MHz */
87 {20000000, {1000, 7, 4, 10, 0} }, /* 20 MHz */ 88 {20000000, {1000, 7, 4, 10, 0} }, /* 20 MHz */
88 {26000000, {1250, 12, 4, 20, 0} }, /* 26 MHz */ 89 {26000000, {1250, 12, 4, 20, 0} }, /* 26 MHz */
89 {38400000, {3125, 47, 4, 20, 92843} }, /* 38.4 MHz */ 90 {38400000, {3125, 47, 4, 20, 92843} }, /* 38.4 MHz */
91 { }, /* Terminator */
92};
93
94static struct pipe3_dpll_map dpll_map_sata[] = {
95 {12000000, {1000, 7, 4, 6, 0} }, /* 12 MHz */
96 {16800000, {714, 7, 4, 6, 0} }, /* 16.8 MHz */
97 {19200000, {625, 7, 4, 6, 0} }, /* 19.2 MHz */
98 {20000000, {600, 7, 4, 6, 0} }, /* 20 MHz */
99 {26000000, {461, 7, 4, 6, 0} }, /* 26 MHz */
100 {38400000, {312, 7, 4, 6, 0} }, /* 38.4 MHz */
101 { }, /* Terminator */
90}; 102};
91 103
92static inline u32 ti_pipe3_readl(void __iomem *addr, unsigned offset) 104static inline u32 ti_pipe3_readl(void __iomem *addr, unsigned offset)
@@ -100,15 +112,20 @@ static inline void ti_pipe3_writel(void __iomem *addr, unsigned offset,
100 __raw_writel(data, addr + offset); 112 __raw_writel(data, addr + offset);
101} 113}
102 114
103static struct pipe3_dpll_params *ti_pipe3_get_dpll_params(unsigned long rate) 115static struct pipe3_dpll_params *ti_pipe3_get_dpll_params(struct ti_pipe3 *phy)
104{ 116{
105 int i; 117 unsigned long rate;
118 struct pipe3_dpll_map *dpll_map = phy->dpll_map;
106 119
107 for (i = 0; i < ARRAY_SIZE(dpll_map); i++) { 120 rate = clk_get_rate(phy->sys_clk);
108 if (rate == dpll_map[i].rate) 121
109 return &dpll_map[i].params; 122 for (; dpll_map->rate; dpll_map++) {
123 if (rate == dpll_map->rate)
124 return &dpll_map->params;
110 } 125 }
111 126
127 dev_err(phy->dev, "No DPLL configuration for %lu Hz SYS CLK\n", rate);
128
112 return NULL; 129 return NULL;
113} 130}
114 131
@@ -182,16 +199,11 @@ static void ti_pipe3_dpll_relock(struct ti_pipe3 *phy)
182static int ti_pipe3_dpll_lock(struct ti_pipe3 *phy) 199static int ti_pipe3_dpll_lock(struct ti_pipe3 *phy)
183{ 200{
184 u32 val; 201 u32 val;
185 unsigned long rate;
186 struct pipe3_dpll_params *dpll_params; 202 struct pipe3_dpll_params *dpll_params;
187 203
188 rate = clk_get_rate(phy->sys_clk); 204 dpll_params = ti_pipe3_get_dpll_params(phy);
189 dpll_params = ti_pipe3_get_dpll_params(rate); 205 if (!dpll_params)
190 if (!dpll_params) {
191 dev_err(phy->dev,
192 "No DPLL configuration for %lu Hz SYS CLK\n", rate);
193 return -EINVAL; 206 return -EINVAL;
194 }
195 207
196 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); 208 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1);
197 val &= ~PLL_REGN_MASK; 209 val &= ~PLL_REGN_MASK;
@@ -244,6 +256,10 @@ static struct phy_ops ops = {
244 .owner = THIS_MODULE, 256 .owner = THIS_MODULE,
245}; 257};
246 258
259#ifdef CONFIG_OF
260static const struct of_device_id ti_pipe3_id_table[];
261#endif
262
247static int ti_pipe3_probe(struct platform_device *pdev) 263static int ti_pipe3_probe(struct platform_device *pdev)
248{ 264{
249 struct ti_pipe3 *phy; 265 struct ti_pipe3 *phy;
@@ -253,8 +269,10 @@ static int ti_pipe3_probe(struct platform_device *pdev)
253 struct device_node *node = pdev->dev.of_node; 269 struct device_node *node = pdev->dev.of_node;
254 struct device_node *control_node; 270 struct device_node *control_node;
255 struct platform_device *control_pdev; 271 struct platform_device *control_pdev;
272 const struct of_device_id *match;
256 273
257 if (!node) 274 match = of_match_device(of_match_ptr(ti_pipe3_id_table), &pdev->dev);
275 if (!match)
258 return -EINVAL; 276 return -EINVAL;
259 277
260 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); 278 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
@@ -263,6 +281,12 @@ static int ti_pipe3_probe(struct platform_device *pdev)
263 return -ENOMEM; 281 return -ENOMEM;
264 } 282 }
265 283
284 phy->dpll_map = (struct pipe3_dpll_map *)match->data;
285 if (!phy->dpll_map) {
286 dev_err(&pdev->dev, "no DPLL data\n");
287 return -EINVAL;
288 }
289
266 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl"); 290 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl");
267 phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res); 291 phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res);
268 if (IS_ERR(phy->pll_ctrl_base)) 292 if (IS_ERR(phy->pll_ctrl_base))
@@ -388,8 +412,18 @@ static const struct dev_pm_ops ti_pipe3_pm_ops = {
388 412
389#ifdef CONFIG_OF 413#ifdef CONFIG_OF
390static const struct of_device_id ti_pipe3_id_table[] = { 414static const struct of_device_id ti_pipe3_id_table[] = {
391 { .compatible = "ti,phy-usb3" }, 415 {
392 { .compatible = "ti,omap-usb3" }, 416 .compatible = "ti,phy-usb3",
417 .data = dpll_map_usb,
418 },
419 {
420 .compatible = "ti,omap-usb3",
421 .data = dpll_map_usb,
422 },
423 {
424 .compatible = "ti,phy-pipe3-sata",
425 .data = dpll_map_sata,
426 },
393 {} 427 {}
394}; 428};
395MODULE_DEVICE_TABLE(of, ti_pipe3_id_table); 429MODULE_DEVICE_TABLE(of, ti_pipe3_id_table);