aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/controller/dwc/pci-dra7xx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/controller/dwc/pci-dra7xx.c')
-rw-r--r--drivers/pci/controller/dwc/pci-dra7xx.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
index a32d6dde7a57..5c72acb49c11 100644
--- a/drivers/pci/controller/dwc/pci-dra7xx.c
+++ b/drivers/pci/controller/dwc/pci-dra7xx.c
@@ -81,6 +81,10 @@
81#define MSI_REQ_GRANT BIT(0) 81#define MSI_REQ_GRANT BIT(0)
82#define MSI_VECTOR_SHIFT 7 82#define MSI_VECTOR_SHIFT 7
83 83
84#define PCIE_1LANE_2LANE_SELECTION BIT(13)
85#define PCIE_B1C0_MODE_SEL BIT(2)
86#define PCIE_B0_B1_TSYNCEN BIT(0)
87
84struct dra7xx_pcie { 88struct dra7xx_pcie {
85 struct dw_pcie *pci; 89 struct dw_pcie *pci;
86 void __iomem *base; /* DT ti_conf */ 90 void __iomem *base; /* DT ti_conf */
@@ -93,6 +97,7 @@ struct dra7xx_pcie {
93 97
94struct dra7xx_pcie_of_data { 98struct dra7xx_pcie_of_data {
95 enum dw_pcie_device_mode mode; 99 enum dw_pcie_device_mode mode;
100 u32 b1co_mode_sel_mask;
96}; 101};
97 102
98#define to_dra7xx_pcie(x) dev_get_drvdata((x)->dev) 103#define to_dra7xx_pcie(x) dev_get_drvdata((x)->dev)
@@ -529,6 +534,26 @@ static const struct dra7xx_pcie_of_data dra7xx_pcie_ep_of_data = {
529 .mode = DW_PCIE_EP_TYPE, 534 .mode = DW_PCIE_EP_TYPE,
530}; 535};
531 536
537static const struct dra7xx_pcie_of_data dra746_pcie_rc_of_data = {
538 .b1co_mode_sel_mask = BIT(2),
539 .mode = DW_PCIE_RC_TYPE,
540};
541
542static const struct dra7xx_pcie_of_data dra726_pcie_rc_of_data = {
543 .b1co_mode_sel_mask = GENMASK(3, 2),
544 .mode = DW_PCIE_RC_TYPE,
545};
546
547static const struct dra7xx_pcie_of_data dra746_pcie_ep_of_data = {
548 .b1co_mode_sel_mask = BIT(2),
549 .mode = DW_PCIE_EP_TYPE,
550};
551
552static const struct dra7xx_pcie_of_data dra726_pcie_ep_of_data = {
553 .b1co_mode_sel_mask = GENMASK(3, 2),
554 .mode = DW_PCIE_EP_TYPE,
555};
556
532static const struct of_device_id of_dra7xx_pcie_match[] = { 557static const struct of_device_id of_dra7xx_pcie_match[] = {
533 { 558 {
534 .compatible = "ti,dra7-pcie", 559 .compatible = "ti,dra7-pcie",
@@ -538,6 +563,22 @@ static const struct of_device_id of_dra7xx_pcie_match[] = {
538 .compatible = "ti,dra7-pcie-ep", 563 .compatible = "ti,dra7-pcie-ep",
539 .data = &dra7xx_pcie_ep_of_data, 564 .data = &dra7xx_pcie_ep_of_data,
540 }, 565 },
566 {
567 .compatible = "ti,dra746-pcie-rc",
568 .data = &dra746_pcie_rc_of_data,
569 },
570 {
571 .compatible = "ti,dra726-pcie-rc",
572 .data = &dra726_pcie_rc_of_data,
573 },
574 {
575 .compatible = "ti,dra746-pcie-ep",
576 .data = &dra746_pcie_ep_of_data,
577 },
578 {
579 .compatible = "ti,dra726-pcie-ep",
580 .data = &dra726_pcie_ep_of_data,
581 },
541 {}, 582 {},
542}; 583};
543 584
@@ -583,6 +624,34 @@ static int dra7xx_pcie_unaligned_memaccess(struct device *dev)
583 return ret; 624 return ret;
584} 625}
585 626
627static int dra7xx_pcie_configure_two_lane(struct device *dev,
628 u32 b1co_mode_sel_mask)
629{
630 struct device_node *np = dev->of_node;
631 struct regmap *pcie_syscon;
632 unsigned int pcie_reg;
633 u32 mask;
634 u32 val;
635
636 pcie_syscon = syscon_regmap_lookup_by_phandle(np, "ti,syscon-lane-sel");
637 if (IS_ERR(pcie_syscon)) {
638 dev_err(dev, "unable to get ti,syscon-lane-sel\n");
639 return -EINVAL;
640 }
641
642 if (of_property_read_u32_index(np, "ti,syscon-lane-sel", 1,
643 &pcie_reg)) {
644 dev_err(dev, "couldn't get lane selection reg offset\n");
645 return -EINVAL;
646 }
647
648 mask = b1co_mode_sel_mask | PCIE_B0_B1_TSYNCEN;
649 val = PCIE_B1C0_MODE_SEL | PCIE_B0_B1_TSYNCEN;
650 regmap_update_bits(pcie_syscon, pcie_reg, mask, val);
651
652 return 0;
653}
654
586static int __init dra7xx_pcie_probe(struct platform_device *pdev) 655static int __init dra7xx_pcie_probe(struct platform_device *pdev)
587{ 656{
588 u32 reg; 657 u32 reg;
@@ -603,6 +672,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
603 const struct of_device_id *match; 672 const struct of_device_id *match;
604 const struct dra7xx_pcie_of_data *data; 673 const struct dra7xx_pcie_of_data *data;
605 enum dw_pcie_device_mode mode; 674 enum dw_pcie_device_mode mode;
675 u32 b1co_mode_sel_mask;
606 676
607 match = of_match_device(of_match_ptr(of_dra7xx_pcie_match), dev); 677 match = of_match_device(of_match_ptr(of_dra7xx_pcie_match), dev);
608 if (!match) 678 if (!match)
@@ -610,6 +680,7 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
610 680
611 data = (struct dra7xx_pcie_of_data *)match->data; 681 data = (struct dra7xx_pcie_of_data *)match->data;
612 mode = (enum dw_pcie_device_mode)data->mode; 682 mode = (enum dw_pcie_device_mode)data->mode;
683 b1co_mode_sel_mask = data->b1co_mode_sel_mask;
613 684
614 dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL); 685 dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL);
615 if (!dra7xx) 686 if (!dra7xx)
@@ -665,6 +736,12 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
665 dra7xx->pci = pci; 736 dra7xx->pci = pci;
666 dra7xx->phy_count = phy_count; 737 dra7xx->phy_count = phy_count;
667 738
739 if (phy_count == 2) {
740 ret = dra7xx_pcie_configure_two_lane(dev, b1co_mode_sel_mask);
741 if (ret < 0)
742 dra7xx->phy_count = 1; /* Fallback to x1 lane mode */
743 }
744
668 ret = dra7xx_pcie_enable_phy(dra7xx); 745 ret = dra7xx_pcie_enable_phy(dra7xx);
669 if (ret) { 746 if (ret) {
670 dev_err(dev, "failed to enable phy\n"); 747 dev_err(dev, "failed to enable phy\n");