aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/pci/qcom,pcie.txt20
-rw-r--r--drivers/pci/dwc/pcie-qcom.c435
2 files changed, 396 insertions, 59 deletions
diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.txt b/Documentation/devicetree/bindings/pci/qcom,pcie.txt
index e15f9b19901f..9d418b71774f 100644
--- a/Documentation/devicetree/bindings/pci/qcom,pcie.txt
+++ b/Documentation/devicetree/bindings/pci/qcom,pcie.txt
@@ -8,6 +8,7 @@
8 - "qcom,pcie-apq8064" for apq8064 8 - "qcom,pcie-apq8064" for apq8064
9 - "qcom,pcie-apq8084" for apq8084 9 - "qcom,pcie-apq8084" for apq8084
10 - "qcom,pcie-msm8996" for msm8996 or apq8096 10 - "qcom,pcie-msm8996" for msm8996 or apq8096
11 - "qcom,pcie-ipq4019" for ipq4019
11 12
12- reg: 13- reg:
13 Usage: required 14 Usage: required
@@ -87,7 +88,7 @@
87 - "core" Clocks the pcie hw block 88 - "core" Clocks the pcie hw block
88 - "phy" Clocks the pcie PHY block 89 - "phy" Clocks the pcie PHY block
89- clock-names: 90- clock-names:
90 Usage: required for apq8084 91 Usage: required for apq8084/ipq4019
91 Value type: <stringlist> 92 Value type: <stringlist>
92 Definition: Should contain the following entries 93 Definition: Should contain the following entries
93 - "aux" Auxiliary (AUX) clock 94 - "aux" Auxiliary (AUX) clock
@@ -126,6 +127,23 @@
126 Definition: Should contain the following entries 127 Definition: Should contain the following entries
127 - "core" Core reset 128 - "core" Core reset
128 129
130- reset-names:
131 Usage: required for ipq/apq8064
132 Value type: <stringlist>
133 Definition: Should contain the following entries
134 - "axi_m" AXI master reset
135 - "axi_s" AXI slave reset
136 - "pipe" PIPE reset
137 - "axi_m_vmid" VMID reset
138 - "axi_s_xpu" XPU reset
139 - "parf" PARF reset
140 - "phy" PHY reset
141 - "axi_m_sticky" AXI sticky reset
142 - "pipe_sticky" PIPE sticky reset
143 - "pwr" PWR reset
144 - "ahb" AHB reset
145 - "phy_ahb" PHY AHB reset
146
129- power-domains: 147- power-domains:
130 Usage: required for apq8084 and msm8996/apq8096 148 Usage: required for apq8084 and msm8996/apq8096
131 Value type: <prop-encoded-array> 149 Value type: <prop-encoded-array>
diff --git a/drivers/pci/dwc/pcie-qcom.c b/drivers/pci/dwc/pcie-qcom.c
index 39e8c0095715..68c5f2ab5bc8 100644
--- a/drivers/pci/dwc/pcie-qcom.c
+++ b/drivers/pci/dwc/pcie-qcom.c
@@ -51,6 +51,12 @@
51#define PCIE20_ELBI_SYS_CTRL 0x04 51#define PCIE20_ELBI_SYS_CTRL 0x04
52#define PCIE20_ELBI_SYS_CTRL_LT_ENABLE BIT(0) 52#define PCIE20_ELBI_SYS_CTRL_LT_ENABLE BIT(0)
53 53
54#define PCIE20_AXI_MSTR_RESP_COMP_CTRL0 0x818
55#define CFG_REMOTE_RD_REQ_BRIDGE_SIZE_2K 0x4
56#define CFG_REMOTE_RD_REQ_BRIDGE_SIZE_4K 0x5
57#define PCIE20_AXI_MSTR_RESP_COMP_CTRL1 0x81c
58#define CFG_BRIDGE_SB_INIT BIT(0)
59
54#define PCIE20_CAP 0x70 60#define PCIE20_CAP 0x70
55 61
56#define PERST_DELAY_US 1000 62#define PERST_DELAY_US 1000
@@ -86,10 +92,29 @@ struct qcom_pcie_resources_v2 {
86 struct clk *pipe_clk; 92 struct clk *pipe_clk;
87}; 93};
88 94
95struct qcom_pcie_resources_v3 {
96 struct clk *aux_clk;
97 struct clk *master_clk;
98 struct clk *slave_clk;
99 struct reset_control *axi_m_reset;
100 struct reset_control *axi_s_reset;
101 struct reset_control *pipe_reset;
102 struct reset_control *axi_m_vmid_reset;
103 struct reset_control *axi_s_xpu_reset;
104 struct reset_control *parf_reset;
105 struct reset_control *phy_reset;
106 struct reset_control *axi_m_sticky_reset;
107 struct reset_control *pipe_sticky_reset;
108 struct reset_control *pwr_reset;
109 struct reset_control *ahb_reset;
110 struct reset_control *phy_ahb_reset;
111};
112
89union qcom_pcie_resources { 113union qcom_pcie_resources {
90 struct qcom_pcie_resources_v0 v0; 114 struct qcom_pcie_resources_v0 v0;
91 struct qcom_pcie_resources_v1 v1; 115 struct qcom_pcie_resources_v1 v1;
92 struct qcom_pcie_resources_v2 v2; 116 struct qcom_pcie_resources_v2 v2;
117 struct qcom_pcie_resources_v3 v3;
93}; 118};
94 119
95struct qcom_pcie; 120struct qcom_pcie;
@@ -133,26 +158,6 @@ static irqreturn_t qcom_pcie_msi_irq_handler(int irq, void *arg)
133 return dw_handle_msi_irq(pp); 158 return dw_handle_msi_irq(pp);
134} 159}
135 160
136static void qcom_pcie_v0_v1_ltssm_enable(struct qcom_pcie *pcie)
137{
138 u32 val;
139
140 /* enable link training */
141 val = readl(pcie->elbi + PCIE20_ELBI_SYS_CTRL);
142 val |= PCIE20_ELBI_SYS_CTRL_LT_ENABLE;
143 writel(val, pcie->elbi + PCIE20_ELBI_SYS_CTRL);
144}
145
146static void qcom_pcie_v2_ltssm_enable(struct qcom_pcie *pcie)
147{
148 u32 val;
149
150 /* enable link training */
151 val = readl(pcie->parf + PCIE20_PARF_LTSSM);
152 val |= BIT(8);
153 writel(val, pcie->parf + PCIE20_PARF_LTSSM);
154}
155
156static int qcom_pcie_establish_link(struct qcom_pcie *pcie) 161static int qcom_pcie_establish_link(struct qcom_pcie *pcie)
157{ 162{
158 struct dw_pcie *pci = pcie->pci; 163 struct dw_pcie *pci = pcie->pci;
@@ -167,6 +172,16 @@ static int qcom_pcie_establish_link(struct qcom_pcie *pcie)
167 return dw_pcie_wait_for_link(pci); 172 return dw_pcie_wait_for_link(pci);
168} 173}
169 174
175static void qcom_pcie_v0_v1_ltssm_enable(struct qcom_pcie *pcie)
176{
177 u32 val;
178
179 /* enable link training */
180 val = readl(pcie->elbi + PCIE20_ELBI_SYS_CTRL);
181 val |= PCIE20_ELBI_SYS_CTRL_LT_ENABLE;
182 writel(val, pcie->elbi + PCIE20_ELBI_SYS_CTRL);
183}
184
170static int qcom_pcie_get_resources_v0(struct qcom_pcie *pcie) 185static int qcom_pcie_get_resources_v0(struct qcom_pcie *pcie)
171{ 186{
172 struct qcom_pcie_resources_v0 *res = &pcie->res.v0; 187 struct qcom_pcie_resources_v0 *res = &pcie->res.v0;
@@ -217,36 +232,6 @@ static int qcom_pcie_get_resources_v0(struct qcom_pcie *pcie)
217 return PTR_ERR_OR_ZERO(res->phy_reset); 232 return PTR_ERR_OR_ZERO(res->phy_reset);
218} 233}
219 234
220static int qcom_pcie_get_resources_v1(struct qcom_pcie *pcie)
221{
222 struct qcom_pcie_resources_v1 *res = &pcie->res.v1;
223 struct dw_pcie *pci = pcie->pci;
224 struct device *dev = pci->dev;
225
226 res->vdda = devm_regulator_get(dev, "vdda");
227 if (IS_ERR(res->vdda))
228 return PTR_ERR(res->vdda);
229
230 res->iface = devm_clk_get(dev, "iface");
231 if (IS_ERR(res->iface))
232 return PTR_ERR(res->iface);
233
234 res->aux = devm_clk_get(dev, "aux");
235 if (IS_ERR(res->aux))
236 return PTR_ERR(res->aux);
237
238 res->master_bus = devm_clk_get(dev, "master_bus");
239 if (IS_ERR(res->master_bus))
240 return PTR_ERR(res->master_bus);
241
242 res->slave_bus = devm_clk_get(dev, "slave_bus");
243 if (IS_ERR(res->slave_bus))
244 return PTR_ERR(res->slave_bus);
245
246 res->core = devm_reset_control_get(dev, "core");
247 return PTR_ERR_OR_ZERO(res->core);
248}
249
250static void qcom_pcie_deinit_v0(struct qcom_pcie *pcie) 235static void qcom_pcie_deinit_v0(struct qcom_pcie *pcie)
251{ 236{
252 struct qcom_pcie_resources_v0 *res = &pcie->res.v0; 237 struct qcom_pcie_resources_v0 *res = &pcie->res.v0;
@@ -357,6 +342,13 @@ static int qcom_pcie_init_v0(struct qcom_pcie *pcie)
357 /* wait for clock acquisition */ 342 /* wait for clock acquisition */
358 usleep_range(1000, 1500); 343 usleep_range(1000, 1500);
359 344
345
346 /* Set the Max TLP size to 2K, instead of using default of 4K */
347 writel(CFG_REMOTE_RD_REQ_BRIDGE_SIZE_2K,
348 pci->dbi_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL0);
349 writel(CFG_BRIDGE_SB_INIT,
350 pci->dbi_base + PCIE20_AXI_MSTR_RESP_COMP_CTRL1);
351
360 return 0; 352 return 0;
361 353
362err_deassert_ahb: 354err_deassert_ahb:
@@ -375,6 +367,36 @@ err_refclk:
375 return ret; 367 return ret;
376} 368}
377 369
370static int qcom_pcie_get_resources_v1(struct qcom_pcie *pcie)
371{
372 struct qcom_pcie_resources_v1 *res = &pcie->res.v1;
373 struct dw_pcie *pci = pcie->pci;
374 struct device *dev = pci->dev;
375
376 res->vdda = devm_regulator_get(dev, "vdda");
377 if (IS_ERR(res->vdda))
378 return PTR_ERR(res->vdda);
379
380 res->iface = devm_clk_get(dev, "iface");
381 if (IS_ERR(res->iface))
382 return PTR_ERR(res->iface);
383
384 res->aux = devm_clk_get(dev, "aux");
385 if (IS_ERR(res->aux))
386 return PTR_ERR(res->aux);
387
388 res->master_bus = devm_clk_get(dev, "master_bus");
389 if (IS_ERR(res->master_bus))
390 return PTR_ERR(res->master_bus);
391
392 res->slave_bus = devm_clk_get(dev, "slave_bus");
393 if (IS_ERR(res->slave_bus))
394 return PTR_ERR(res->slave_bus);
395
396 res->core = devm_reset_control_get(dev, "core");
397 return PTR_ERR_OR_ZERO(res->core);
398}
399
378static void qcom_pcie_deinit_v1(struct qcom_pcie *pcie) 400static void qcom_pcie_deinit_v1(struct qcom_pcie *pcie)
379{ 401{
380 struct qcom_pcie_resources_v1 *res = &pcie->res.v1; 402 struct qcom_pcie_resources_v1 *res = &pcie->res.v1;
@@ -455,6 +477,16 @@ err_res:
455 return ret; 477 return ret;
456} 478}
457 479
480static void qcom_pcie_v2_ltssm_enable(struct qcom_pcie *pcie)
481{
482 u32 val;
483
484 /* enable link training */
485 val = readl(pcie->parf + PCIE20_PARF_LTSSM);
486 val |= BIT(8);
487 writel(val, pcie->parf + PCIE20_PARF_LTSSM);
488}
489
458static int qcom_pcie_get_resources_v2(struct qcom_pcie *pcie) 490static int qcom_pcie_get_resources_v2(struct qcom_pcie *pcie)
459{ 491{
460 struct qcom_pcie_resources_v2 *res = &pcie->res.v2; 492 struct qcom_pcie_resources_v2 *res = &pcie->res.v2;
@@ -481,6 +513,17 @@ static int qcom_pcie_get_resources_v2(struct qcom_pcie *pcie)
481 return PTR_ERR_OR_ZERO(res->pipe_clk); 513 return PTR_ERR_OR_ZERO(res->pipe_clk);
482} 514}
483 515
516static void qcom_pcie_deinit_v2(struct qcom_pcie *pcie)
517{
518 struct qcom_pcie_resources_v2 *res = &pcie->res.v2;
519
520 clk_disable_unprepare(res->pipe_clk);
521 clk_disable_unprepare(res->slave_clk);
522 clk_disable_unprepare(res->master_clk);
523 clk_disable_unprepare(res->cfg_clk);
524 clk_disable_unprepare(res->aux_clk);
525}
526
484static int qcom_pcie_init_v2(struct qcom_pcie *pcie) 527static int qcom_pcie_init_v2(struct qcom_pcie *pcie)
485{ 528{
486 struct qcom_pcie_resources_v2 *res = &pcie->res.v2; 529 struct qcom_pcie_resources_v2 *res = &pcie->res.v2;
@@ -562,22 +605,290 @@ static int qcom_pcie_post_init_v2(struct qcom_pcie *pcie)
562 return 0; 605 return 0;
563} 606}
564 607
565static int qcom_pcie_link_up(struct dw_pcie *pci) 608static int qcom_pcie_get_resources_v3(struct qcom_pcie *pcie)
566{ 609{
567 u16 val = readw(pci->dbi_base + PCIE20_CAP + PCI_EXP_LNKSTA); 610 struct qcom_pcie_resources_v3 *res = &pcie->res.v3;
611 struct dw_pcie *pci = pcie->pci;
612 struct device *dev = pci->dev;
568 613
569 return !!(val & PCI_EXP_LNKSTA_DLLLA); 614 res->aux_clk = devm_clk_get(dev, "aux");
615 if (IS_ERR(res->aux_clk))
616 return PTR_ERR(res->aux_clk);
617
618 res->master_clk = devm_clk_get(dev, "master_bus");
619 if (IS_ERR(res->master_clk))
620 return PTR_ERR(res->master_clk);
621
622 res->slave_clk = devm_clk_get(dev, "slave_bus");
623 if (IS_ERR(res->slave_clk))
624 return PTR_ERR(res->slave_clk);
625
626 res->axi_m_reset = devm_reset_control_get(dev, "axi_m");
627 if (IS_ERR(res->axi_m_reset))
628 return PTR_ERR(res->axi_m_reset);
629
630 res->axi_s_reset = devm_reset_control_get(dev, "axi_s");
631 if (IS_ERR(res->axi_s_reset))
632 return PTR_ERR(res->axi_s_reset);
633
634 res->pipe_reset = devm_reset_control_get(dev, "pipe");
635 if (IS_ERR(res->pipe_reset))
636 return PTR_ERR(res->pipe_reset);
637
638 res->axi_m_vmid_reset = devm_reset_control_get(dev, "axi_m_vmid");
639 if (IS_ERR(res->axi_m_vmid_reset))
640 return PTR_ERR(res->axi_m_vmid_reset);
641
642 res->axi_s_xpu_reset = devm_reset_control_get(dev, "axi_s_xpu");
643 if (IS_ERR(res->axi_s_xpu_reset))
644 return PTR_ERR(res->axi_s_xpu_reset);
645
646 res->parf_reset = devm_reset_control_get(dev, "parf");
647 if (IS_ERR(res->parf_reset))
648 return PTR_ERR(res->parf_reset);
649
650 res->phy_reset = devm_reset_control_get(dev, "phy");
651 if (IS_ERR(res->phy_reset))
652 return PTR_ERR(res->phy_reset);
653
654 res->axi_m_sticky_reset = devm_reset_control_get(dev, "axi_m_sticky");
655 if (IS_ERR(res->axi_m_sticky_reset))
656 return PTR_ERR(res->axi_m_sticky_reset);
657
658 res->pipe_sticky_reset = devm_reset_control_get(dev, "pipe_sticky");
659 if (IS_ERR(res->pipe_sticky_reset))
660 return PTR_ERR(res->pipe_sticky_reset);
661
662 res->pwr_reset = devm_reset_control_get(dev, "pwr");
663 if (IS_ERR(res->pwr_reset))
664 return PTR_ERR(res->pwr_reset);
665
666 res->ahb_reset = devm_reset_control_get(dev, "ahb");
667 if (IS_ERR(res->ahb_reset))
668 return PTR_ERR(res->ahb_reset);
669
670 res->phy_ahb_reset = devm_reset_control_get(dev, "phy_ahb");
671 if (IS_ERR(res->phy_ahb_reset))
672 return PTR_ERR(res->phy_ahb_reset);
673
674 return 0;
570} 675}
571 676
572static void qcom_pcie_deinit_v2(struct qcom_pcie *pcie) 677static void qcom_pcie_deinit_v3(struct qcom_pcie *pcie)
573{ 678{
574 struct qcom_pcie_resources_v2 *res = &pcie->res.v2; 679 struct qcom_pcie_resources_v3 *res = &pcie->res.v3;
575 680
576 clk_disable_unprepare(res->pipe_clk); 681 reset_control_assert(res->axi_m_reset);
682 reset_control_assert(res->axi_s_reset);
683 reset_control_assert(res->pipe_reset);
684 reset_control_assert(res->pipe_sticky_reset);
685 reset_control_assert(res->phy_reset);
686 reset_control_assert(res->phy_ahb_reset);
687 reset_control_assert(res->axi_m_sticky_reset);
688 reset_control_assert(res->pwr_reset);
689 reset_control_assert(res->ahb_reset);
690 clk_disable_unprepare(res->aux_clk);
691 clk_disable_unprepare(res->master_clk);
577 clk_disable_unprepare(res->slave_clk); 692 clk_disable_unprepare(res->slave_clk);
693}
694
695static int qcom_pcie_init_v3(struct qcom_pcie *pcie)
696{
697 struct qcom_pcie_resources_v3 *res = &pcie->res.v3;
698 struct dw_pcie *pci = pcie->pci;
699 struct device *dev = pci->dev;
700 u32 val;
701 int ret;
702
703 ret = reset_control_assert(res->axi_m_reset);
704 if (ret) {
705 dev_err(dev, "cannot assert axi master reset\n");
706 return ret;
707 }
708
709 ret = reset_control_assert(res->axi_s_reset);
710 if (ret) {
711 dev_err(dev, "cannot assert axi slave reset\n");
712 return ret;
713 }
714
715 usleep_range(10000, 12000);
716
717 ret = reset_control_assert(res->pipe_reset);
718 if (ret) {
719 dev_err(dev, "cannot assert pipe reset\n");
720 return ret;
721 }
722
723 ret = reset_control_assert(res->pipe_sticky_reset);
724 if (ret) {
725 dev_err(dev, "cannot assert pipe sticky reset\n");
726 return ret;
727 }
728
729 ret = reset_control_assert(res->phy_reset);
730 if (ret) {
731 dev_err(dev, "cannot assert phy reset\n");
732 return ret;
733 }
734
735 ret = reset_control_assert(res->phy_ahb_reset);
736 if (ret) {
737 dev_err(dev, "cannot assert phy ahb reset\n");
738 return ret;
739 }
740
741 usleep_range(10000, 12000);
742
743 ret = reset_control_assert(res->axi_m_sticky_reset);
744 if (ret) {
745 dev_err(dev, "cannot assert axi master sticky reset\n");
746 return ret;
747 }
748
749 ret = reset_control_assert(res->pwr_reset);
750 if (ret) {
751 dev_err(dev, "cannot assert power reset\n");
752 return ret;
753 }
754
755 ret = reset_control_assert(res->ahb_reset);
756 if (ret) {
757 dev_err(dev, "cannot assert ahb reset\n");
758 return ret;
759 }
760
761 usleep_range(10000, 12000);
762
763 ret = reset_control_deassert(res->phy_ahb_reset);
764 if (ret) {
765 dev_err(dev, "cannot deassert phy ahb reset\n");
766 return ret;
767 }
768
769 ret = reset_control_deassert(res->phy_reset);
770 if (ret) {
771 dev_err(dev, "cannot deassert phy reset\n");
772 goto err_rst_phy;
773 }
774
775 ret = reset_control_deassert(res->pipe_reset);
776 if (ret) {
777 dev_err(dev, "cannot deassert pipe reset\n");
778 goto err_rst_pipe;
779 }
780
781 ret = reset_control_deassert(res->pipe_sticky_reset);
782 if (ret) {
783 dev_err(dev, "cannot deassert pipe sticky reset\n");
784 goto err_rst_pipe_sticky;
785 }
786
787 usleep_range(10000, 12000);
788
789 ret = reset_control_deassert(res->axi_m_reset);
790 if (ret) {
791 dev_err(dev, "cannot deassert axi master reset\n");
792 goto err_rst_axi_m;
793 }
794
795 ret = reset_control_deassert(res->axi_m_sticky_reset);
796 if (ret) {
797 dev_err(dev, "cannot deassert axi master sticky reset\n");
798 goto err_rst_axi_m_sticky;
799 }
800
801 ret = reset_control_deassert(res->axi_s_reset);
802 if (ret) {
803 dev_err(dev, "cannot deassert axi slave reset\n");
804 goto err_rst_axi_s;
805 }
806
807 ret = reset_control_deassert(res->pwr_reset);
808 if (ret) {
809 dev_err(dev, "cannot deassert power reset\n");
810 goto err_rst_pwr;
811 }
812
813 ret = reset_control_deassert(res->ahb_reset);
814 if (ret) {
815 dev_err(dev, "cannot deassert ahb reset\n");
816 goto err_rst_ahb;
817 }
818
819 usleep_range(10000, 12000);
820
821 ret = clk_prepare_enable(res->aux_clk);
822 if (ret) {
823 dev_err(dev, "cannot prepare/enable iface clock\n");
824 goto err_clk_aux;
825 }
826
827 ret = clk_prepare_enable(res->master_clk);
828 if (ret) {
829 dev_err(dev, "cannot prepare/enable core clock\n");
830 goto err_clk_axi_m;
831 }
832
833 ret = clk_prepare_enable(res->slave_clk);
834 if (ret) {
835 dev_err(dev, "cannot prepare/enable phy clock\n");
836 goto err_clk_axi_s;
837 }
838
839 /* enable PCIe clocks and resets */
840 val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
841 val &= !BIT(0);
842 writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
843
844 /* change DBI base address */
845 writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
846
847 /* MAC PHY_POWERDOWN MUX DISABLE */
848 val = readl(pcie->parf + PCIE20_PARF_SYS_CTRL);
849 val &= ~BIT(29);
850 writel(val, pcie->parf + PCIE20_PARF_SYS_CTRL);
851
852 val = readl(pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
853 val |= BIT(4);
854 writel(val, pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
855
856 val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
857 val |= BIT(31);
858 writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
859
860 return 0;
861
862err_clk_axi_s:
578 clk_disable_unprepare(res->master_clk); 863 clk_disable_unprepare(res->master_clk);
579 clk_disable_unprepare(res->cfg_clk); 864err_clk_axi_m:
580 clk_disable_unprepare(res->aux_clk); 865 clk_disable_unprepare(res->aux_clk);
866err_clk_aux:
867 reset_control_assert(res->ahb_reset);
868err_rst_ahb:
869 reset_control_assert(res->pwr_reset);
870err_rst_pwr:
871 reset_control_assert(res->axi_s_reset);
872err_rst_axi_s:
873 reset_control_assert(res->axi_m_sticky_reset);
874err_rst_axi_m_sticky:
875 reset_control_assert(res->axi_m_reset);
876err_rst_axi_m:
877 reset_control_assert(res->pipe_sticky_reset);
878err_rst_pipe_sticky:
879 reset_control_assert(res->pipe_reset);
880err_rst_pipe:
881 reset_control_assert(res->phy_reset);
882err_rst_phy:
883 reset_control_assert(res->phy_ahb_reset);
884 return ret;
885}
886
887static int qcom_pcie_link_up(struct dw_pcie *pci)
888{
889 u16 val = readw(pci->dbi_base + PCIE20_CAP + PCI_EXP_LNKSTA);
890
891 return !!(val & PCI_EXP_LNKSTA_DLLLA);
581} 892}
582 893
583static void qcom_pcie_host_init(struct pcie_port *pp) 894static void qcom_pcie_host_init(struct pcie_port *pp)
@@ -665,6 +976,13 @@ static const struct dw_pcie_ops dw_pcie_ops = {
665 .link_up = qcom_pcie_link_up, 976 .link_up = qcom_pcie_link_up,
666}; 977};
667 978
979static const struct qcom_pcie_ops ops_v3 = {
980 .get_resources = qcom_pcie_get_resources_v3,
981 .init = qcom_pcie_init_v3,
982 .deinit = qcom_pcie_deinit_v3,
983 .ltssm_enable = qcom_pcie_v2_ltssm_enable,
984};
985
668static int qcom_pcie_probe(struct platform_device *pdev) 986static int qcom_pcie_probe(struct platform_device *pdev)
669{ 987{
670 struct device *dev = &pdev->dev; 988 struct device *dev = &pdev->dev;
@@ -755,6 +1073,7 @@ static const struct of_device_id qcom_pcie_match[] = {
755 { .compatible = "qcom,pcie-apq8064", .data = &ops_v0 }, 1073 { .compatible = "qcom,pcie-apq8064", .data = &ops_v0 },
756 { .compatible = "qcom,pcie-apq8084", .data = &ops_v1 }, 1074 { .compatible = "qcom,pcie-apq8084", .data = &ops_v1 },
757 { .compatible = "qcom,pcie-msm8996", .data = &ops_v2 }, 1075 { .compatible = "qcom,pcie-msm8996", .data = &ops_v2 },
1076 { .compatible = "qcom,pcie-ipq4019", .data = &ops_v3 },
758 { } 1077 { }
759}; 1078};
760 1079