aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy/phy-ti-pipe3.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/phy/phy-ti-pipe3.c')
-rw-r--r--drivers/phy/phy-ti-pipe3.c103
1 files changed, 82 insertions, 21 deletions
diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c
index 591367654613..6174f4b1a5de 100644
--- a/drivers/phy/phy-ti-pipe3.c
+++ b/drivers/phy/phy-ti-pipe3.c
@@ -80,7 +80,9 @@ struct ti_pipe3 {
80 struct clk *wkupclk; 80 struct clk *wkupclk;
81 struct clk *sys_clk; 81 struct clk *sys_clk;
82 struct clk *refclk; 82 struct clk *refclk;
83 struct clk *div_clk;
83 struct pipe3_dpll_map *dpll_map; 84 struct pipe3_dpll_map *dpll_map;
85 u8 id;
84}; 86};
85 87
86static struct pipe3_dpll_map dpll_map_usb[] = { 88static struct pipe3_dpll_map dpll_map_usb[] = {
@@ -215,6 +217,9 @@ static int ti_pipe3_init(struct phy *x)
215 u32 val; 217 u32 val;
216 int ret = 0; 218 int ret = 0;
217 219
220 if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie"))
221 return 0;
222
218 /* Bring it out of IDLE if it is IDLE */ 223 /* Bring it out of IDLE if it is IDLE */
219 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); 224 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2);
220 if (val & PLL_IDLE) { 225 if (val & PLL_IDLE) {
@@ -238,8 +243,11 @@ static int ti_pipe3_exit(struct phy *x)
238 u32 val; 243 u32 val;
239 unsigned long timeout; 244 unsigned long timeout;
240 245
241 /* SATA DPLL can't be powered down due to Errata i783 */ 246 /* SATA DPLL can't be powered down due to Errata i783 and PCIe
242 if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata")) 247 * does not have internal DPLL
248 */
249 if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata") ||
250 of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie"))
243 return 0; 251 return 0;
244 252
245 /* Put DPLL in IDLE mode */ 253 /* Put DPLL in IDLE mode */
@@ -286,32 +294,41 @@ static int ti_pipe3_probe(struct platform_device *pdev)
286 struct device_node *control_node; 294 struct device_node *control_node;
287 struct platform_device *control_pdev; 295 struct platform_device *control_pdev;
288 const struct of_device_id *match; 296 const struct of_device_id *match;
289 297 struct clk *clk;
290 match = of_match_device(of_match_ptr(ti_pipe3_id_table), &pdev->dev);
291 if (!match)
292 return -EINVAL;
293 298
294 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL); 299 phy = devm_kzalloc(&pdev->dev, sizeof(*phy), GFP_KERNEL);
295 if (!phy) { 300 if (!phy) {
296 dev_err(&pdev->dev, "unable to alloc mem for TI PIPE3 PHY\n"); 301 dev_err(&pdev->dev, "unable to alloc mem for TI PIPE3 PHY\n");
297 return -ENOMEM; 302 return -ENOMEM;
298 } 303 }
304 phy->dev = &pdev->dev;
299 305
300 phy->dpll_map = (struct pipe3_dpll_map *)match->data; 306 if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) {
301 if (!phy->dpll_map) { 307 match = of_match_device(of_match_ptr(ti_pipe3_id_table),
302 dev_err(&pdev->dev, "no DPLL data\n"); 308 &pdev->dev);
303 return -EINVAL; 309 if (!match)
304 } 310 return -EINVAL;
305 311
306 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pll_ctrl"); 312 phy->dpll_map = (struct pipe3_dpll_map *)match->data;
307 phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res); 313 if (!phy->dpll_map) {
308 if (IS_ERR(phy->pll_ctrl_base)) 314 dev_err(&pdev->dev, "no DPLL data\n");
309 return PTR_ERR(phy->pll_ctrl_base); 315 return -EINVAL;
316 }
310 317
311 phy->dev = &pdev->dev; 318 res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
319 "pll_ctrl");
320 phy->pll_ctrl_base = devm_ioremap_resource(&pdev->dev, res);
321 if (IS_ERR(phy->pll_ctrl_base))
322 return PTR_ERR(phy->pll_ctrl_base);
312 323
313 if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) { 324 phy->sys_clk = devm_clk_get(phy->dev, "sysclk");
325 if (IS_ERR(phy->sys_clk)) {
326 dev_err(&pdev->dev, "unable to get sysclk\n");
327 return -EINVAL;
328 }
329 }
314 330
331 if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) {
315 phy->wkupclk = devm_clk_get(phy->dev, "wkupclk"); 332 phy->wkupclk = devm_clk_get(phy->dev, "wkupclk");
316 if (IS_ERR(phy->wkupclk)) { 333 if (IS_ERR(phy->wkupclk)) {
317 dev_err(&pdev->dev, "unable to get wkupclk\n"); 334 dev_err(&pdev->dev, "unable to get wkupclk\n");
@@ -328,10 +345,38 @@ static int ti_pipe3_probe(struct platform_device *pdev)
328 phy->refclk = ERR_PTR(-ENODEV); 345 phy->refclk = ERR_PTR(-ENODEV);
329 } 346 }
330 347
331 phy->sys_clk = devm_clk_get(phy->dev, "sysclk"); 348 if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) {
332 if (IS_ERR(phy->sys_clk)) { 349 if (of_property_read_u8(node, "id", &phy->id) < 0)
333 dev_err(&pdev->dev, "unable to get sysclk\n"); 350 phy->id = 1;
334 return -EINVAL; 351
352 clk = devm_clk_get(phy->dev, "dpll_ref");
353 if (IS_ERR(clk)) {
354 dev_err(&pdev->dev, "unable to get dpll ref clk\n");
355 return PTR_ERR(clk);
356 }
357 clk_set_rate(clk, 1500000000);
358
359 clk = devm_clk_get(phy->dev, "dpll_ref_m2");
360 if (IS_ERR(clk)) {
361 dev_err(&pdev->dev, "unable to get dpll ref m2 clk\n");
362 return PTR_ERR(clk);
363 }
364 clk_set_rate(clk, 100000000);
365
366 clk = devm_clk_get(phy->dev, "phy-div");
367 if (IS_ERR(clk)) {
368 dev_err(&pdev->dev, "unable to get phy-div clk\n");
369 return PTR_ERR(clk);
370 }
371 clk_set_rate(clk, 100000000);
372
373 phy->div_clk = devm_clk_get(phy->dev, "div-clk");
374 if (IS_ERR(phy->div_clk)) {
375 dev_err(&pdev->dev, "unable to get div-clk\n");
376 return PTR_ERR(phy->div_clk);
377 }
378 } else {
379 phy->div_clk = ERR_PTR(-ENODEV);
335 } 380 }
336 381
337 control_node = of_parse_phandle(node, "ctrl-module", 0); 382 control_node = of_parse_phandle(node, "ctrl-module", 0);
@@ -387,6 +432,8 @@ static int ti_pipe3_runtime_suspend(struct device *dev)
387 clk_disable_unprepare(phy->wkupclk); 432 clk_disable_unprepare(phy->wkupclk);
388 if (!IS_ERR(phy->refclk)) 433 if (!IS_ERR(phy->refclk))
389 clk_disable_unprepare(phy->refclk); 434 clk_disable_unprepare(phy->refclk);
435 if (!IS_ERR(phy->div_clk))
436 clk_disable_unprepare(phy->div_clk);
390 437
391 return 0; 438 return 0;
392} 439}
@@ -412,8 +459,19 @@ static int ti_pipe3_runtime_resume(struct device *dev)
412 } 459 }
413 } 460 }
414 461
462 if (!IS_ERR(phy->div_clk)) {
463 ret = clk_prepare_enable(phy->div_clk);
464 if (ret) {
465 dev_err(phy->dev, "Failed to enable div_clk %d\n", ret);
466 goto err3;
467 }
468 }
415 return 0; 469 return 0;
416 470
471err3:
472 if (!IS_ERR(phy->wkupclk))
473 clk_disable_unprepare(phy->wkupclk);
474
417err2: 475err2:
418 if (!IS_ERR(phy->refclk)) 476 if (!IS_ERR(phy->refclk))
419 clk_disable_unprepare(phy->refclk); 477 clk_disable_unprepare(phy->refclk);
@@ -446,6 +504,9 @@ static const struct of_device_id ti_pipe3_id_table[] = {
446 .compatible = "ti,phy-pipe3-sata", 504 .compatible = "ti,phy-pipe3-sata",
447 .data = dpll_map_sata, 505 .data = dpll_map_sata,
448 }, 506 },
507 {
508 .compatible = "ti,phy-pipe3-pcie",
509 },
449 {} 510 {}
450}; 511};
451MODULE_DEVICE_TABLE(of, ti_pipe3_id_table); 512MODULE_DEVICE_TABLE(of, ti_pipe3_id_table);