• Home
  • Raw
  • Download

Lines Matching +full:syscon +full:- +full:pcie +full:- +full:ctrl

2  * phy-ti-pipe3 - PIPE3 PHY driver.
4 * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com
31 #include <linux/mfd/syscon.h>
137 struct regmap *phy_power_syscon; /* ctrl. reg. acces */
138 struct regmap *pcs_syscon; /* ctrl. reg. acces */
139 struct regmap *dpll_reset_syscon; /* ctrl. reg. acces */
140 unsigned int dpll_reset_reg; /* reg. index within syscon */
141 unsigned int power_reg; /* power reg. index within syscon */
142 unsigned int pcie_pcs_reg; /* pcs reg. index in syscon */
180 struct pipe3_dpll_map *dpll_map = phy->dpll_map; in ti_pipe3_get_dpll_params()
182 rate = clk_get_rate(phy->sys_clk); in ti_pipe3_get_dpll_params()
184 for (; dpll_map->rate; dpll_map++) { in ti_pipe3_get_dpll_params()
185 if (rate == dpll_map->rate) in ti_pipe3_get_dpll_params()
186 return &dpll_map->params; in ti_pipe3_get_dpll_params()
189 dev_err(phy->dev, "No DPLL configuration for %lu Hz SYS CLK\n", rate); in ti_pipe3_get_dpll_params()
203 if (!phy->phy_power_syscon) { in ti_pipe3_power_off()
204 omap_control_phy_power(phy->control_dev, 0); in ti_pipe3_power_off()
210 ret = regmap_update_bits(phy->phy_power_syscon, phy->power_reg, in ti_pipe3_power_off()
223 if (!phy->phy_power_syscon) { in ti_pipe3_power_on()
224 omap_control_phy_power(phy->control_dev, 1); in ti_pipe3_power_on()
228 rate = clk_get_rate(phy->sys_clk); in ti_pipe3_power_on()
230 dev_err(phy->dev, "Invalid clock rate\n"); in ti_pipe3_power_on()
231 return -EINVAL; in ti_pipe3_power_on()
239 ret = regmap_update_bits(phy->phy_power_syscon, phy->power_reg, in ti_pipe3_power_on()
252 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); in ti_pipe3_dpll_wait_lock()
257 dev_err(phy->dev, "DPLL failed to lock\n"); in ti_pipe3_dpll_wait_lock()
258 return -EBUSY; in ti_pipe3_dpll_wait_lock()
268 return -EINVAL; in ti_pipe3_dpll_program()
270 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); in ti_pipe3_dpll_program()
272 val |= dpll_params->n << PLL_REGN_SHIFT; in ti_pipe3_dpll_program()
273 ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); in ti_pipe3_dpll_program()
275 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); in ti_pipe3_dpll_program()
277 val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT; in ti_pipe3_dpll_program()
278 ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); in ti_pipe3_dpll_program()
280 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); in ti_pipe3_dpll_program()
282 val |= dpll_params->m << PLL_REGM_SHIFT; in ti_pipe3_dpll_program()
283 ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); in ti_pipe3_dpll_program()
285 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4); in ti_pipe3_dpll_program()
287 val |= dpll_params->mf << PLL_REGM_F_SHIFT; in ti_pipe3_dpll_program()
288 ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val); in ti_pipe3_dpll_program()
290 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3); in ti_pipe3_dpll_program()
292 val |= dpll_params->sd << PLL_SD_SHIFT; in ti_pipe3_dpll_program()
293 ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val); in ti_pipe3_dpll_program()
295 ti_pipe3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO); in ti_pipe3_dpll_program()
304 val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_ANA_PROGRAMMABILITY); in ti_pipe3_calibrate()
307 ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_ANA_PROGRAMMABILITY, val); in ti_pipe3_calibrate()
309 val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_DIGITAL_MODES); in ti_pipe3_calibrate()
314 ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_DIGITAL_MODES, val); in ti_pipe3_calibrate()
316 val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_TRIM); in ti_pipe3_calibrate()
319 ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_TRIM, val); in ti_pipe3_calibrate()
321 val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_DLL); in ti_pipe3_calibrate()
323 ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_DLL, val); in ti_pipe3_calibrate()
325 val = ti_pipe3_readl(phy->phy_rx, PCIEPHYRX_EQUALIZER); in ti_pipe3_calibrate()
328 ti_pipe3_writel(phy->phy_rx, PCIEPHYRX_EQUALIZER, val); in ti_pipe3_calibrate()
341 * 18-1804. in ti_pipe3_init()
343 if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) { in ti_pipe3_init()
344 if (!phy->pcs_syscon) { in ti_pipe3_init()
345 omap_control_pcie_pcs(phy->control_dev, 0x96); in ti_pipe3_init()
350 ret = regmap_update_bits(phy->pcs_syscon, phy->pcie_pcs_reg, in ti_pipe3_init()
361 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); in ti_pipe3_init()
364 ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); in ti_pipe3_init()
368 /* SATA has issues if re-programmed when locked */ in ti_pipe3_init()
369 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); in ti_pipe3_init()
370 if ((val & PLL_LOCK) && of_device_is_compatible(phy->dev->of_node, in ti_pipe3_init()
371 "ti,phy-pipe3-sata")) in ti_pipe3_init()
378 return -EINVAL; in ti_pipe3_init()
393 if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata") && in ti_pipe3_exit()
394 !phy->dpll_reset_syscon) in ti_pipe3_exit()
397 /* PCIe doesn't have internal DPLL */ in ti_pipe3_exit()
398 if (!of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) { in ti_pipe3_exit()
400 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); in ti_pipe3_exit()
402 ti_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); in ti_pipe3_exit()
408 val = ti_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); in ti_pipe3_exit()
414 dev_err(phy->dev, "Failed to power down: PLL_STATUS 0x%x\n", in ti_pipe3_exit()
416 return -EBUSY; in ti_pipe3_exit()
421 if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-sata")) { in ti_pipe3_exit()
422 regmap_update_bits(phy->dpll_reset_syscon, phy->dpll_reset_reg, in ti_pipe3_exit()
424 regmap_update_bits(phy->dpll_reset_syscon, phy->dpll_reset_reg, in ti_pipe3_exit()
445 struct device *dev = phy->dev; in ti_pipe3_get_clk()
446 struct device_node *node = dev->of_node; in ti_pipe3_get_clk()
448 phy->refclk = devm_clk_get(dev, "refclk"); in ti_pipe3_get_clk()
449 if (IS_ERR(phy->refclk)) { in ti_pipe3_get_clk()
454 if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) in ti_pipe3_get_clk()
455 return PTR_ERR(phy->refclk); in ti_pipe3_get_clk()
458 if (!of_device_is_compatible(node, "ti,phy-pipe3-sata")) { in ti_pipe3_get_clk()
459 phy->wkupclk = devm_clk_get(dev, "wkupclk"); in ti_pipe3_get_clk()
460 if (IS_ERR(phy->wkupclk)) { in ti_pipe3_get_clk()
462 return PTR_ERR(phy->wkupclk); in ti_pipe3_get_clk()
465 phy->wkupclk = ERR_PTR(-ENODEV); in ti_pipe3_get_clk()
468 if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie") || in ti_pipe3_get_clk()
469 phy->phy_power_syscon) { in ti_pipe3_get_clk()
470 phy->sys_clk = devm_clk_get(dev, "sysclk"); in ti_pipe3_get_clk()
471 if (IS_ERR(phy->sys_clk)) { in ti_pipe3_get_clk()
473 return -EINVAL; in ti_pipe3_get_clk()
477 if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { in ti_pipe3_get_clk()
492 clk = devm_clk_get(dev, "phy-div"); in ti_pipe3_get_clk()
494 dev_err(dev, "unable to get phy-div clk\n"); in ti_pipe3_get_clk()
499 phy->div_clk = devm_clk_get(dev, "div-clk"); in ti_pipe3_get_clk()
500 if (IS_ERR(phy->div_clk)) { in ti_pipe3_get_clk()
501 dev_err(dev, "unable to get div-clk\n"); in ti_pipe3_get_clk()
502 return PTR_ERR(phy->div_clk); in ti_pipe3_get_clk()
505 phy->div_clk = ERR_PTR(-ENODEV); in ti_pipe3_get_clk()
513 struct device *dev = phy->dev; in ti_pipe3_get_sysctrl()
514 struct device_node *node = dev->of_node; in ti_pipe3_get_sysctrl()
518 phy->phy_power_syscon = syscon_regmap_lookup_by_phandle(node, in ti_pipe3_get_sysctrl()
519 "syscon-phy-power"); in ti_pipe3_get_sysctrl()
520 if (IS_ERR(phy->phy_power_syscon)) { in ti_pipe3_get_sysctrl()
522 "can't get syscon-phy-power, using control device\n"); in ti_pipe3_get_sysctrl()
523 phy->phy_power_syscon = NULL; in ti_pipe3_get_sysctrl()
526 "syscon-phy-power", 1, in ti_pipe3_get_sysctrl()
527 &phy->power_reg)) { in ti_pipe3_get_sysctrl()
529 return -EINVAL; in ti_pipe3_get_sysctrl()
533 if (!phy->phy_power_syscon) { in ti_pipe3_get_sysctrl()
534 control_node = of_parse_phandle(node, "ctrl-module", 0); in ti_pipe3_get_sysctrl()
537 return -EINVAL; in ti_pipe3_get_sysctrl()
543 return -EINVAL; in ti_pipe3_get_sysctrl()
546 phy->control_dev = &control_pdev->dev; in ti_pipe3_get_sysctrl()
549 if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { in ti_pipe3_get_sysctrl()
550 phy->pcs_syscon = syscon_regmap_lookup_by_phandle(node, in ti_pipe3_get_sysctrl()
551 "syscon-pcs"); in ti_pipe3_get_sysctrl()
552 if (IS_ERR(phy->pcs_syscon)) { in ti_pipe3_get_sysctrl()
554 "can't get syscon-pcs, using omap control\n"); in ti_pipe3_get_sysctrl()
555 phy->pcs_syscon = NULL; in ti_pipe3_get_sysctrl()
558 "syscon-pcs", 1, in ti_pipe3_get_sysctrl()
559 &phy->pcie_pcs_reg)) { in ti_pipe3_get_sysctrl()
561 "couldn't get pcie pcs reg. offset\n"); in ti_pipe3_get_sysctrl()
562 return -EINVAL; in ti_pipe3_get_sysctrl()
567 if (of_device_is_compatible(node, "ti,phy-pipe3-sata")) { in ti_pipe3_get_sysctrl()
568 phy->dpll_reset_syscon = syscon_regmap_lookup_by_phandle(node, in ti_pipe3_get_sysctrl()
569 "syscon-pllreset"); in ti_pipe3_get_sysctrl()
570 if (IS_ERR(phy->dpll_reset_syscon)) { in ti_pipe3_get_sysctrl()
572 "can't get syscon-pllreset, sata dpll won't idle\n"); in ti_pipe3_get_sysctrl()
573 phy->dpll_reset_syscon = NULL; in ti_pipe3_get_sysctrl()
576 "syscon-pllreset", 1, in ti_pipe3_get_sysctrl()
577 &phy->dpll_reset_reg)) { in ti_pipe3_get_sysctrl()
580 return -EINVAL; in ti_pipe3_get_sysctrl()
591 struct device *dev = phy->dev; in ti_pipe3_get_tx_rx_base()
592 struct device_node *node = dev->of_node; in ti_pipe3_get_tx_rx_base()
595 if (!of_device_is_compatible(node, "ti,phy-pipe3-pcie")) in ti_pipe3_get_tx_rx_base()
600 phy->phy_rx = devm_ioremap_resource(dev, res); in ti_pipe3_get_tx_rx_base()
601 if (IS_ERR(phy->phy_rx)) in ti_pipe3_get_tx_rx_base()
602 return PTR_ERR(phy->phy_rx); in ti_pipe3_get_tx_rx_base()
606 phy->phy_tx = devm_ioremap_resource(dev, res); in ti_pipe3_get_tx_rx_base()
608 return PTR_ERR_OR_ZERO(phy->phy_tx); in ti_pipe3_get_tx_rx_base()
615 struct device *dev = phy->dev; in ti_pipe3_get_pll_base()
616 struct device_node *node = dev->of_node; in ti_pipe3_get_pll_base()
619 if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) in ti_pipe3_get_pll_base()
624 return -EINVAL; in ti_pipe3_get_pll_base()
626 phy->dpll_map = (struct pipe3_dpll_map *)match->data; in ti_pipe3_get_pll_base()
627 if (!phy->dpll_map) { in ti_pipe3_get_pll_base()
629 return -EINVAL; in ti_pipe3_get_pll_base()
634 phy->pll_ctrl_base = devm_ioremap_resource(dev, res); in ti_pipe3_get_pll_base()
635 return PTR_ERR_OR_ZERO(phy->pll_ctrl_base); in ti_pipe3_get_pll_base()
643 struct device_node *node = pdev->dev.of_node; in ti_pipe3_probe()
644 struct device *dev = &pdev->dev; in ti_pipe3_probe()
649 return -ENOMEM; in ti_pipe3_probe()
651 phy->dev = dev; in ti_pipe3_probe()
673 * Prevent auto-disable of refclk for SATA PHY due to Errata i783 in ti_pipe3_probe()
675 if (of_device_is_compatible(node, "ti,phy-pipe3-sata")) { in ti_pipe3_probe()
676 if (!IS_ERR(phy->refclk)) { in ti_pipe3_probe()
677 clk_prepare_enable(phy->refclk); in ti_pipe3_probe()
678 phy->sata_refclk_enabled = true; in ti_pipe3_probe()
696 pm_runtime_disable(&pdev->dev); in ti_pipe3_remove()
705 if (!IS_ERR(phy->refclk)) { in ti_pipe3_enable_clocks()
706 ret = clk_prepare_enable(phy->refclk); in ti_pipe3_enable_clocks()
708 dev_err(phy->dev, "Failed to enable refclk %d\n", ret); in ti_pipe3_enable_clocks()
713 if (!IS_ERR(phy->wkupclk)) { in ti_pipe3_enable_clocks()
714 ret = clk_prepare_enable(phy->wkupclk); in ti_pipe3_enable_clocks()
716 dev_err(phy->dev, "Failed to enable wkupclk %d\n", ret); in ti_pipe3_enable_clocks()
721 if (!IS_ERR(phy->div_clk)) { in ti_pipe3_enable_clocks()
722 ret = clk_prepare_enable(phy->div_clk); in ti_pipe3_enable_clocks()
724 dev_err(phy->dev, "Failed to enable div_clk %d\n", ret); in ti_pipe3_enable_clocks()
732 if (!IS_ERR(phy->wkupclk)) in ti_pipe3_enable_clocks()
733 clk_disable_unprepare(phy->wkupclk); in ti_pipe3_enable_clocks()
736 if (!IS_ERR(phy->refclk)) in ti_pipe3_enable_clocks()
737 clk_disable_unprepare(phy->refclk); in ti_pipe3_enable_clocks()
744 if (!IS_ERR(phy->wkupclk)) in ti_pipe3_disable_clocks()
745 clk_disable_unprepare(phy->wkupclk); in ti_pipe3_disable_clocks()
746 if (!IS_ERR(phy->refclk)) { in ti_pipe3_disable_clocks()
747 clk_disable_unprepare(phy->refclk); in ti_pipe3_disable_clocks()
752 if (phy->sata_refclk_enabled) { in ti_pipe3_disable_clocks()
753 clk_disable_unprepare(phy->refclk); in ti_pipe3_disable_clocks()
754 phy->sata_refclk_enabled = false; in ti_pipe3_disable_clocks()
758 if (!IS_ERR(phy->div_clk)) in ti_pipe3_disable_clocks()
759 clk_disable_unprepare(phy->div_clk); in ti_pipe3_disable_clocks()
764 .compatible = "ti,phy-usb3",
768 .compatible = "ti,omap-usb3",
772 .compatible = "ti,phy-pipe3-sata",
776 .compatible = "ti,phy-pipe3-pcie",
786 .name = "ti-pipe3",