aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/controller/dwc/pci-imx6.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/controller/dwc/pci-imx6.c')
-rw-r--r--drivers/pci/controller/dwc/pci-imx6.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index 4a9a673b4777..21e03c6567da 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -97,6 +97,16 @@ struct imx6_pcie {
97#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17) 97#define PORT_LOGIC_SPEED_CHANGE (0x1 << 17)
98 98
99/* PHY registers (not memory-mapped) */ 99/* PHY registers (not memory-mapped) */
100#define PCIE_PHY_ATEOVRD 0x10
101#define PCIE_PHY_ATEOVRD_EN (0x1 << 2)
102#define PCIE_PHY_ATEOVRD_REF_CLKDIV_SHIFT 0
103#define PCIE_PHY_ATEOVRD_REF_CLKDIV_MASK 0x1
104
105#define PCIE_PHY_MPLL_OVRD_IN_LO 0x11
106#define PCIE_PHY_MPLL_MULTIPLIER_SHIFT 2
107#define PCIE_PHY_MPLL_MULTIPLIER_MASK 0x7f
108#define PCIE_PHY_MPLL_MULTIPLIER_OVRD (0x1 << 9)
109
100#define PCIE_PHY_RX_ASIC_OUT 0x100D 110#define PCIE_PHY_RX_ASIC_OUT 0x100D
101#define PCIE_PHY_RX_ASIC_OUT_VALID (1 << 0) 111#define PCIE_PHY_RX_ASIC_OUT_VALID (1 << 0)
102 112
@@ -508,6 +518,50 @@ static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
508 IMX6Q_GPR12_DEVICE_TYPE, PCI_EXP_TYPE_ROOT_PORT << 12); 518 IMX6Q_GPR12_DEVICE_TYPE, PCI_EXP_TYPE_ROOT_PORT << 12);
509} 519}
510 520
521static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie)
522{
523 unsigned long phy_rate = clk_get_rate(imx6_pcie->pcie_phy);
524 int mult, div;
525 u32 val;
526
527 switch (phy_rate) {
528 case 125000000:
529 /*
530 * The default settings of the MPLL are for a 125MHz input
531 * clock, so no need to reconfigure anything in that case.
532 */
533 return 0;
534 case 100000000:
535 mult = 25;
536 div = 0;
537 break;
538 case 200000000:
539 mult = 25;
540 div = 1;
541 break;
542 default:
543 dev_err(imx6_pcie->pci->dev,
544 "Unsupported PHY reference clock rate %lu\n", phy_rate);
545 return -EINVAL;
546 }
547
548 pcie_phy_read(imx6_pcie, PCIE_PHY_MPLL_OVRD_IN_LO, &val);
549 val &= ~(PCIE_PHY_MPLL_MULTIPLIER_MASK <<
550 PCIE_PHY_MPLL_MULTIPLIER_SHIFT);
551 val |= mult << PCIE_PHY_MPLL_MULTIPLIER_SHIFT;
552 val |= PCIE_PHY_MPLL_MULTIPLIER_OVRD;
553 pcie_phy_write(imx6_pcie, PCIE_PHY_MPLL_OVRD_IN_LO, val);
554
555 pcie_phy_read(imx6_pcie, PCIE_PHY_ATEOVRD, &val);
556 val &= ~(PCIE_PHY_ATEOVRD_REF_CLKDIV_MASK <<
557 PCIE_PHY_ATEOVRD_REF_CLKDIV_SHIFT);
558 val |= div << PCIE_PHY_ATEOVRD_REF_CLKDIV_SHIFT;
559 val |= PCIE_PHY_ATEOVRD_EN;
560 pcie_phy_write(imx6_pcie, PCIE_PHY_ATEOVRD, val);
561
562 return 0;
563}
564
511static int imx6_pcie_wait_for_link(struct imx6_pcie *imx6_pcie) 565static int imx6_pcie_wait_for_link(struct imx6_pcie *imx6_pcie)
512{ 566{
513 struct dw_pcie *pci = imx6_pcie->pci; 567 struct dw_pcie *pci = imx6_pcie->pci;
@@ -632,6 +686,7 @@ static int imx6_pcie_host_init(struct pcie_port *pp)
632 imx6_pcie_assert_core_reset(imx6_pcie); 686 imx6_pcie_assert_core_reset(imx6_pcie);
633 imx6_pcie_init_phy(imx6_pcie); 687 imx6_pcie_init_phy(imx6_pcie);
634 imx6_pcie_deassert_core_reset(imx6_pcie); 688 imx6_pcie_deassert_core_reset(imx6_pcie);
689 imx6_setup_phy_mpll(imx6_pcie);
635 dw_pcie_setup_rc(pp); 690 dw_pcie_setup_rc(pp);
636 imx6_pcie_establish_link(imx6_pcie); 691 imx6_pcie_establish_link(imx6_pcie);
637 692