diff options
Diffstat (limited to 'drivers/pci/controller/dwc/pci-imx6.c')
-rw-r--r-- | drivers/pci/controller/dwc/pci-imx6.c | 55 |
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 | ||
521 | static 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 | |||
511 | static int imx6_pcie_wait_for_link(struct imx6_pcie *imx6_pcie) | 565 | static 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 | ||