Lines Matching +full:imx7d +full:- +full:clock
1 // SPDX-License-Identifier: GPL-2.0
16 #include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
17 #include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
31 #include "pcie-designware.h"
33 #define to_imx6_pcie(x) dev_get_drvdata((x)->dev)
39 IMX7D, enumerator
68 /* PCIe Root Complex registers (memory-mapped) */
77 /* PCIe Port Logic registers (memory-mapped) */
98 /* PHY registers (not memory-mapped) */
108 struct dw_pcie *pci = imx6_pcie->pci; in pcie_phy_poll_ack()
124 return -ETIMEDOUT; in pcie_phy_poll_ack()
129 struct dw_pcie *pci = imx6_pcie->pci; in pcie_phy_wait_ack()
149 /* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */
152 struct dw_pcie *pci = imx6_pcie->pci; in pcie_phy_read()
179 struct dw_pcie *pci = imx6_pcie->pci; in pcie_phy_write()
204 /* wait for ack de-assertion */ in pcie_phy_write()
222 /* wait for ack de-assertion */ in pcie_phy_write()
259 * make it look like it read all-ones. in imx6q_pcie_abort_handler()
267 val = -1; in imx6q_pcie_abort_handler()
269 regs->uregs[reg] = val; in imx6q_pcie_abort_handler()
270 regs->ARM_pc += 4; in imx6q_pcie_abort_handler()
275 regs->uregs[reg] = -1; in imx6q_pcie_abort_handler()
276 regs->ARM_pc += 4; in imx6q_pcie_abort_handler()
285 struct device *dev = imx6_pcie->pci->dev; in imx6_pcie_assert_core_reset()
287 switch (imx6_pcie->variant) { in imx6_pcie_assert_core_reset()
288 case IMX7D: in imx6_pcie_assert_core_reset()
289 reset_control_assert(imx6_pcie->pciephy_reset); in imx6_pcie_assert_core_reset()
290 reset_control_assert(imx6_pcie->apps_reset); in imx6_pcie_assert_core_reset()
293 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, in imx6_pcie_assert_core_reset()
297 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5, in imx6_pcie_assert_core_reset()
302 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, in imx6_pcie_assert_core_reset()
307 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, in imx6_pcie_assert_core_reset()
309 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, in imx6_pcie_assert_core_reset()
314 if (imx6_pcie->vpcie && regulator_is_enabled(imx6_pcie->vpcie) > 0) { in imx6_pcie_assert_core_reset()
315 int ret = regulator_disable(imx6_pcie->vpcie); in imx6_pcie_assert_core_reset()
325 struct dw_pcie *pci = imx6_pcie->pci; in imx6_pcie_enable_ref_clk()
326 struct device *dev = pci->dev; in imx6_pcie_enable_ref_clk()
329 switch (imx6_pcie->variant) { in imx6_pcie_enable_ref_clk()
331 ret = clk_prepare_enable(imx6_pcie->pcie_inbound_axi); in imx6_pcie_enable_ref_clk()
333 dev_err(dev, "unable to enable pcie_axi clock\n"); in imx6_pcie_enable_ref_clk()
337 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, in imx6_pcie_enable_ref_clk()
342 /* power up core phy and enable ref clock */ in imx6_pcie_enable_ref_clk()
343 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, in imx6_pcie_enable_ref_clk()
346 * the async reset input need ref clock to sync internally, in imx6_pcie_enable_ref_clk()
347 * when the ref clock comes after reset, internal synced in imx6_pcie_enable_ref_clk()
352 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, in imx6_pcie_enable_ref_clk()
355 case IMX7D: in imx6_pcie_enable_ref_clk()
366 struct device *dev = imx6_pcie->pci->dev; in imx7d_pcie_wait_for_phy_pll_lock()
369 regmap_read(imx6_pcie->iomuxc_gpr, IOMUXC_GPR22, &val); in imx7d_pcie_wait_for_phy_pll_lock()
383 struct dw_pcie *pci = imx6_pcie->pci; in imx6_pcie_deassert_core_reset()
384 struct device *dev = pci->dev; in imx6_pcie_deassert_core_reset()
387 if (imx6_pcie->vpcie && !regulator_is_enabled(imx6_pcie->vpcie)) { in imx6_pcie_deassert_core_reset()
388 ret = regulator_enable(imx6_pcie->vpcie); in imx6_pcie_deassert_core_reset()
396 ret = clk_prepare_enable(imx6_pcie->pcie_phy); in imx6_pcie_deassert_core_reset()
398 dev_err(dev, "unable to enable pcie_phy clock\n"); in imx6_pcie_deassert_core_reset()
402 ret = clk_prepare_enable(imx6_pcie->pcie_bus); in imx6_pcie_deassert_core_reset()
404 dev_err(dev, "unable to enable pcie_bus clock\n"); in imx6_pcie_deassert_core_reset()
408 ret = clk_prepare_enable(imx6_pcie->pcie); in imx6_pcie_deassert_core_reset()
410 dev_err(dev, "unable to enable pcie clock\n"); in imx6_pcie_deassert_core_reset()
416 dev_err(dev, "unable to enable pcie ref clock\n"); in imx6_pcie_deassert_core_reset()
424 if (gpio_is_valid(imx6_pcie->reset_gpio)) { in imx6_pcie_deassert_core_reset()
425 gpio_set_value_cansleep(imx6_pcie->reset_gpio, in imx6_pcie_deassert_core_reset()
426 imx6_pcie->gpio_active_high); in imx6_pcie_deassert_core_reset()
428 gpio_set_value_cansleep(imx6_pcie->reset_gpio, in imx6_pcie_deassert_core_reset()
429 !imx6_pcie->gpio_active_high); in imx6_pcie_deassert_core_reset()
432 switch (imx6_pcie->variant) { in imx6_pcie_deassert_core_reset()
433 case IMX7D: in imx6_pcie_deassert_core_reset()
434 reset_control_deassert(imx6_pcie->pciephy_reset); in imx6_pcie_deassert_core_reset()
438 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR5, in imx6_pcie_deassert_core_reset()
442 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR1, in imx6_pcie_deassert_core_reset()
454 clk_disable_unprepare(imx6_pcie->pcie); in imx6_pcie_deassert_core_reset()
456 clk_disable_unprepare(imx6_pcie->pcie_bus); in imx6_pcie_deassert_core_reset()
458 clk_disable_unprepare(imx6_pcie->pcie_phy); in imx6_pcie_deassert_core_reset()
460 if (imx6_pcie->vpcie && regulator_is_enabled(imx6_pcie->vpcie) > 0) { in imx6_pcie_deassert_core_reset()
461 ret = regulator_disable(imx6_pcie->vpcie); in imx6_pcie_deassert_core_reset()
470 switch (imx6_pcie->variant) { in imx6_pcie_init_phy()
471 case IMX7D: in imx6_pcie_init_phy()
472 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, in imx6_pcie_init_phy()
476 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, in imx6_pcie_init_phy()
481 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, in imx6_pcie_init_phy()
485 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, in imx6_pcie_init_phy()
488 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, in imx6_pcie_init_phy()
490 imx6_pcie->tx_deemph_gen1 << 0); in imx6_pcie_init_phy()
491 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, in imx6_pcie_init_phy()
493 imx6_pcie->tx_deemph_gen2_3p5db << 6); in imx6_pcie_init_phy()
494 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, in imx6_pcie_init_phy()
496 imx6_pcie->tx_deemph_gen2_6db << 12); in imx6_pcie_init_phy()
497 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, in imx6_pcie_init_phy()
499 imx6_pcie->tx_swing_full << 18); in imx6_pcie_init_phy()
500 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, in imx6_pcie_init_phy()
502 imx6_pcie->tx_swing_low << 25); in imx6_pcie_init_phy()
506 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, in imx6_pcie_init_phy()
512 struct dw_pcie *pci = imx6_pcie->pci; in imx6_pcie_wait_for_link()
513 struct device *dev = pci->dev; in imx6_pcie_wait_for_link()
522 return -ETIMEDOUT; in imx6_pcie_wait_for_link()
527 struct dw_pcie *pci = imx6_pcie->pci; in imx6_pcie_wait_for_speed_change()
528 struct device *dev = pci->dev; in imx6_pcie_wait_for_speed_change()
541 return -EINVAL; in imx6_pcie_wait_for_speed_change()
546 struct dw_pcie *pci = imx6_pcie->pci; in imx6_pcie_establish_link()
547 struct device *dev = pci->dev; in imx6_pcie_establish_link()
562 if (imx6_pcie->variant == IMX7D) in imx6_pcie_establish_link()
563 reset_control_deassert(imx6_pcie->apps_reset); in imx6_pcie_establish_link()
565 regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, in imx6_pcie_establish_link()
572 if (imx6_pcie->link_gen == 2) { in imx6_pcie_establish_link()
587 if (imx6_pcie->variant != IMX7D) { in imx6_pcie_establish_link()
591 * occurs and we go Gen1 -> yep, Gen1. The difference in imx6_pcie_establish_link()
650 struct dw_pcie *pci = imx6_pcie->pci; in imx6_add_pcie_port()
651 struct pcie_port *pp = &pci->pp; in imx6_add_pcie_port()
652 struct device *dev = &pdev->dev; in imx6_add_pcie_port()
656 pp->msi_irq = platform_get_irq_byname(pdev, "msi"); in imx6_add_pcie_port()
657 if (pp->msi_irq <= 0) { in imx6_add_pcie_port()
659 return -ENODEV; in imx6_add_pcie_port()
663 pp->ops = &imx6_pcie_host_ops; in imx6_add_pcie_port()
675 /* No special ops needed, but pcie-designware still expects this struct */
680 struct device *dev = &pdev->dev; in imx6_pcie_probe()
684 struct device_node *node = dev->of_node; in imx6_pcie_probe()
690 return -ENOMEM; in imx6_pcie_probe()
694 return -ENOMEM; in imx6_pcie_probe()
696 pci->dev = dev; in imx6_pcie_probe()
697 pci->ops = &dw_pcie_ops; in imx6_pcie_probe()
699 imx6_pcie->pci = pci; in imx6_pcie_probe()
700 imx6_pcie->variant = in imx6_pcie_probe()
704 pci->dbi_base = devm_ioremap_resource(dev, dbi_base); in imx6_pcie_probe()
705 if (IS_ERR(pci->dbi_base)) in imx6_pcie_probe()
706 return PTR_ERR(pci->dbi_base); in imx6_pcie_probe()
709 imx6_pcie->reset_gpio = of_get_named_gpio(node, "reset-gpio", 0); in imx6_pcie_probe()
710 imx6_pcie->gpio_active_high = of_property_read_bool(node, in imx6_pcie_probe()
711 "reset-gpio-active-high"); in imx6_pcie_probe()
712 if (gpio_is_valid(imx6_pcie->reset_gpio)) { in imx6_pcie_probe()
713 ret = devm_gpio_request_one(dev, imx6_pcie->reset_gpio, in imx6_pcie_probe()
714 imx6_pcie->gpio_active_high ? in imx6_pcie_probe()
722 } else if (imx6_pcie->reset_gpio == -EPROBE_DEFER) { in imx6_pcie_probe()
723 return imx6_pcie->reset_gpio; in imx6_pcie_probe()
727 imx6_pcie->pcie_phy = devm_clk_get(dev, "pcie_phy"); in imx6_pcie_probe()
728 if (IS_ERR(imx6_pcie->pcie_phy)) { in imx6_pcie_probe()
729 dev_err(dev, "pcie_phy clock source missing or invalid\n"); in imx6_pcie_probe()
730 return PTR_ERR(imx6_pcie->pcie_phy); in imx6_pcie_probe()
733 imx6_pcie->pcie_bus = devm_clk_get(dev, "pcie_bus"); in imx6_pcie_probe()
734 if (IS_ERR(imx6_pcie->pcie_bus)) { in imx6_pcie_probe()
735 dev_err(dev, "pcie_bus clock source missing or invalid\n"); in imx6_pcie_probe()
736 return PTR_ERR(imx6_pcie->pcie_bus); in imx6_pcie_probe()
739 imx6_pcie->pcie = devm_clk_get(dev, "pcie"); in imx6_pcie_probe()
740 if (IS_ERR(imx6_pcie->pcie)) { in imx6_pcie_probe()
741 dev_err(dev, "pcie clock source missing or invalid\n"); in imx6_pcie_probe()
742 return PTR_ERR(imx6_pcie->pcie); in imx6_pcie_probe()
745 switch (imx6_pcie->variant) { in imx6_pcie_probe()
747 imx6_pcie->pcie_inbound_axi = devm_clk_get(dev, in imx6_pcie_probe()
749 if (IS_ERR(imx6_pcie->pcie_inbound_axi)) { in imx6_pcie_probe()
750 dev_err(dev, "pcie_inbound_axi clock missing or invalid\n"); in imx6_pcie_probe()
751 return PTR_ERR(imx6_pcie->pcie_inbound_axi); in imx6_pcie_probe()
754 case IMX7D: in imx6_pcie_probe()
755 imx6_pcie->pciephy_reset = devm_reset_control_get_exclusive(dev, in imx6_pcie_probe()
757 if (IS_ERR(imx6_pcie->pciephy_reset)) { in imx6_pcie_probe()
759 return PTR_ERR(imx6_pcie->pciephy_reset); in imx6_pcie_probe()
762 imx6_pcie->apps_reset = devm_reset_control_get_exclusive(dev, in imx6_pcie_probe()
764 if (IS_ERR(imx6_pcie->apps_reset)) { in imx6_pcie_probe()
766 return PTR_ERR(imx6_pcie->apps_reset); in imx6_pcie_probe()
774 imx6_pcie->iomuxc_gpr = in imx6_pcie_probe()
775 syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr"); in imx6_pcie_probe()
776 if (IS_ERR(imx6_pcie->iomuxc_gpr)) { in imx6_pcie_probe()
778 return PTR_ERR(imx6_pcie->iomuxc_gpr); in imx6_pcie_probe()
782 if (of_property_read_u32(node, "fsl,tx-deemph-gen1", in imx6_pcie_probe()
783 &imx6_pcie->tx_deemph_gen1)) in imx6_pcie_probe()
784 imx6_pcie->tx_deemph_gen1 = 0; in imx6_pcie_probe()
786 if (of_property_read_u32(node, "fsl,tx-deemph-gen2-3p5db", in imx6_pcie_probe()
787 &imx6_pcie->tx_deemph_gen2_3p5db)) in imx6_pcie_probe()
788 imx6_pcie->tx_deemph_gen2_3p5db = 0; in imx6_pcie_probe()
790 if (of_property_read_u32(node, "fsl,tx-deemph-gen2-6db", in imx6_pcie_probe()
791 &imx6_pcie->tx_deemph_gen2_6db)) in imx6_pcie_probe()
792 imx6_pcie->tx_deemph_gen2_6db = 20; in imx6_pcie_probe()
794 if (of_property_read_u32(node, "fsl,tx-swing-full", in imx6_pcie_probe()
795 &imx6_pcie->tx_swing_full)) in imx6_pcie_probe()
796 imx6_pcie->tx_swing_full = 127; in imx6_pcie_probe()
798 if (of_property_read_u32(node, "fsl,tx-swing-low", in imx6_pcie_probe()
799 &imx6_pcie->tx_swing_low)) in imx6_pcie_probe()
800 imx6_pcie->tx_swing_low = 127; in imx6_pcie_probe()
803 ret = of_property_read_u32(node, "fsl,max-link-speed", in imx6_pcie_probe()
804 &imx6_pcie->link_gen); in imx6_pcie_probe()
806 imx6_pcie->link_gen = 1; in imx6_pcie_probe()
808 imx6_pcie->vpcie = devm_regulator_get_optional(&pdev->dev, "vpcie"); in imx6_pcie_probe()
809 if (IS_ERR(imx6_pcie->vpcie)) { in imx6_pcie_probe()
810 if (PTR_ERR(imx6_pcie->vpcie) != -ENODEV) in imx6_pcie_probe()
811 return PTR_ERR(imx6_pcie->vpcie); in imx6_pcie_probe()
812 imx6_pcie->vpcie = NULL; in imx6_pcie_probe()
841 { .compatible = "fsl,imx6q-pcie", .data = (void *)IMX6Q, },
842 { .compatible = "fsl,imx6sx-pcie", .data = (void *)IMX6SX, },
843 { .compatible = "fsl,imx6qp-pcie", .data = (void *)IMX6QP, },
844 { .compatible = "fsl,imx7d-pcie", .data = (void *)IMX7D, },
850 .name = "imx6q-pcie",
863 * by kernel and since imx6q_pcie_abort_handler() is a no-op, in imx6_pcie_init()
868 "external abort on non-linefetch"); in imx6_pcie_init()