Merge branch 'pci/ctrl/tegra194'
authorBjorn Helgaas <bhelgaas@google.com>
Thu, 4 Aug 2022 16:46:51 +0000 (11:46 -0500)
committerBjorn Helgaas <bhelgaas@google.com>
Thu, 4 Aug 2022 16:46:51 +0000 (11:46 -0500)
- Fix tegra_pcie_config_ep() power management in error path (Miaoqian Lin)

- Convert DT binding to json-schema (Vidya Sagar)

- Add DT bindings and driver support for Tegra234 Root Port and Endpoint
  mode (Vidya Sagar)

- Disable MSI for Tegra234 Root Ports so they use INTx for all events (PCIe
  doesn't allow mixing INTx and MSI/MSI-X) (Vidya Sagar)

- Search for Vendor-Specific RAS-DEC capability instead of hard-coding
  offset (Vidya Sagar)

- Fix unintentional APPL_INTR_STATUS_L0 value overwrite in Root Port
  interrupt handling (Vidya Sagar)

- Clear Bandwidth Management interrupt status bit to avoid interrupt storm
  (Vidya Sagar)

- Set default Max Payload Size to 256 bytes (Vidya Sagar)

- Fix offset when clearing bit in Data Link Feature capability (Vidya
  Sagar)

- Extend Endpoint mode support to devices beyond Controller-5 (Vidya Sagar)

* pci/ctrl/tegra194:
  PCI: tegra194: Add Tegra234 PCIe support
  PCI: tegra194: Extend Endpoint mode support
  PCI: tegra194: Fix link up retry sequence
  PCI: tegra194: Clean up the exit path for Endpoint mode
  PCI: tegra194: Enable support for 256 Byte payload
  PCI: tegra194: Clear bandwidth management status
  PCI: tegra194: Fix Root Port interrupt handling
  PCI: tegra194: Find RAS DES PCIe capability offset
  Revert "PCI: tegra194: Rename tegra_pcie_dw to tegra194_pcie"
  PCI: Disable MSI for Tegra234 Root Ports
  dt-bindings: PCI: tegra234: Add schema for tegra234 Endpoint mode
  dt-bindings: PCI: tegra234: Add schema for tegra234 Root Port mode
  dt-bindings: PCI: tegra194: Convert to json-schema
  PCI: tegra194: Fix PM error handling in tegra_pcie_config_ep()

# Conflicts:
# drivers/pci/controller/dwc/pcie-designware.h
# drivers/pci/controller/dwc/pcie-tegra194.c

1  2 
drivers/pci/controller/dwc/pcie-designware.h
drivers/pci/controller/dwc/pcie-tegra194.c
drivers/pci/quirks.c

@@@ -305,10 -315,10 +309,10 @@@ struct tegra_pcie_soc 
        enum dw_pcie_device_mode mode;
  };
  
 -static void apply_bad_link_workaround(struct pcie_port *pp)
 +static void apply_bad_link_workaround(struct dw_pcie_rp *pp)
  {
        struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
-       struct tegra194_pcie *pcie = to_tegra_pcie(pci);
+       struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
        u32 current_link_width;
        u16 val;
  
  
  static irqreturn_t tegra_pcie_rp_irq_handler(int irq, void *arg)
  {
-       struct tegra194_pcie *pcie = arg;
+       struct tegra_pcie_dw *pcie = arg;
        struct dw_pcie *pci = &pcie->pci;
 -      struct pcie_port *pp = &pci->pp;
 +      struct dw_pcie_rp *pp = &pci->pp;
-       u32 val, tmp;
+       u32 val, status_l0, status_l1;
        u16 val_w;
  
-       val = appl_readl(pcie, APPL_INTR_STATUS_L0);
-       if (val & APPL_INTR_STATUS_L0_LINK_STATE_INT) {
-               val = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0);
-               if (val & APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED) {
-                       appl_writel(pcie, val, APPL_INTR_STATUS_L1_0_0);
+       status_l0 = appl_readl(pcie, APPL_INTR_STATUS_L0);
+       if (status_l0 & APPL_INTR_STATUS_L0_LINK_STATE_INT) {
+               status_l1 = appl_readl(pcie, APPL_INTR_STATUS_L1_0_0);
+               appl_writel(pcie, status_l1, APPL_INTR_STATUS_L1_0_0);
+               if (!pcie->of_data->has_sbr_reset_fix &&
+                   status_l1 & APPL_INTR_STATUS_L1_0_0_LINK_REQ_RST_NOT_CHGED) {
                        /* SBR & Surprise Link Down WAR */
                        val = appl_readl(pcie, APPL_CAR_RESET_OVRD);
                        val &= ~APPL_CAR_RESET_OVRD_CYA_OVERRIDE_CORE_RST_N;
@@@ -529,9 -547,13 +541,13 @@@ static irqreturn_t tegra_pcie_ep_hard_i
        return IRQ_HANDLED;
  }
  
- static int tegra194_pcie_rd_own_conf(struct pci_bus *bus, u32 devfn, int where,
+ static int tegra_pcie_dw_rd_own_conf(struct pci_bus *bus, u32 devfn, int where,
                                     int size, u32 *val)
  {
 -      struct pcie_port *pp = bus->sysdata;
++      struct dw_pcie_rp *pp = bus->sysdata;
+       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+       struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
        /*
         * This is an endpoint mode specific register happen to appear even
         * when controller is operating in root port mode and system hangs
        return pci_generic_config_read(bus, devfn, where, size, val);
  }
  
- static int tegra194_pcie_wr_own_conf(struct pci_bus *bus, u32 devfn, int where,
+ static int tegra_pcie_dw_wr_own_conf(struct pci_bus *bus, u32 devfn, int where,
                                     int size, u32 val)
  {
 -      struct pcie_port *pp = bus->sysdata;
++      struct dw_pcie_rp *pp = bus->sysdata;
+       struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
+       struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
        /*
         * This is an endpoint mode specific register happen to appear even
         * when controller is operating in root port mode and system hangs
@@@ -686,16 -705,16 +699,16 @@@ static void init_debugfs(struct tegra_p
                                    aspm_state_cnt);
  }
  #else
- static inline void disable_aspm_l12(struct tegra194_pcie *pcie) { return; }
- static inline void disable_aspm_l11(struct tegra194_pcie *pcie) { return; }
- static inline void init_host_aspm(struct tegra194_pcie *pcie) { return; }
- static inline void init_debugfs(struct tegra194_pcie *pcie) { return; }
+ static inline void disable_aspm_l12(struct tegra_pcie_dw *pcie) { return; }
+ static inline void disable_aspm_l11(struct tegra_pcie_dw *pcie) { return; }
+ static inline void init_host_aspm(struct tegra_pcie_dw *pcie) { return; }
+ static inline void init_debugfs(struct tegra_pcie_dw *pcie) { return; }
  #endif
  
 -static void tegra_pcie_enable_system_interrupts(struct pcie_port *pp)
 +static void tegra_pcie_enable_system_interrupts(struct dw_pcie_rp *pp)
  {
        struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
-       struct tegra194_pcie *pcie = to_tegra_pcie(pci);
+       struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
        u32 val;
        u16 val_w;
  
                           val_w);
  }
  
 -static void tegra_pcie_enable_legacy_interrupts(struct pcie_port *pp)
 +static void tegra_pcie_enable_legacy_interrupts(struct dw_pcie_rp *pp)
  {
        struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
-       struct tegra194_pcie *pcie = to_tegra_pcie(pci);
+       struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
        u32 val;
  
        /* Enable legacy interrupt generation */
        appl_writel(pcie, val, APPL_INTR_EN_L1_8_0);
  }
  
 -static void tegra_pcie_enable_msi_interrupts(struct pcie_port *pp)
 +static void tegra_pcie_enable_msi_interrupts(struct dw_pcie_rp *pp)
  {
        struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
-       struct tegra194_pcie *pcie = to_tegra_pcie(pci);
+       struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
        u32 val;
  
        /* Enable MSI interrupt generation */
        appl_writel(pcie, val, APPL_INTR_EN_L0_0);
  }
  
 -static void tegra_pcie_enable_interrupts(struct pcie_port *pp)
 +static void tegra_pcie_enable_interrupts(struct dw_pcie_rp *pp)
  {
        struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
-       struct tegra194_pcie *pcie = to_tegra_pcie(pci);
+       struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
  
        /* Clear interrupt statuses before enabling interrupts */
        appl_writel(pcie, 0xFFFFFFFF, APPL_INTR_STATUS_L0);
@@@ -845,11 -867,12 +861,12 @@@ static void config_gen3_gen4_eq_presets
        dw_pcie_writel_dbi(pci, GEN3_RELATED_OFF, val);
  }
  
- static int tegra194_pcie_host_init(struct dw_pcie_rp *pp)
 -static int tegra_pcie_dw_host_init(struct pcie_port *pp)
++static int tegra_pcie_dw_host_init(struct dw_pcie_rp *pp)
  {
        struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
-       struct tegra194_pcie *pcie = to_tegra_pcie(pci);
+       struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
        u32 val;
+       u16 val_16;
  
        pp->bridge->ops = &tegra_pci_ops;
  
        return 0;
  }
  
- static int tegra194_pcie_start_link(struct dw_pcie *pci)
+ static int tegra_pcie_dw_start_link(struct dw_pcie *pci)
  {
        u32 val, offset, speed, tmp;
-       struct tegra194_pcie *pcie = to_tegra_pcie(pci);
+       struct tegra_pcie_dw *pcie = to_tegra_pcie(pci);
 -      struct pcie_port *pp = &pci->pp;
 +      struct dw_pcie_rp *pp = &pci->pp;
        bool retry = true;
  
-       if (pcie->mode == DW_PCIE_EP_TYPE) {
+       if (pcie->of_data->mode == DW_PCIE_EP_TYPE) {
                enable_irq(pcie->pex_rst_irq);
                return 0;
        }
@@@ -1204,9 -1260,9 +1254,9 @@@ static int tegra_pcie_bpmp_set_pll_stat
        return tegra_bpmp_transfer(pcie->bpmp, &msg);
  }
  
- static void tegra_pcie_downstream_dev_to_D0(struct tegra194_pcie *pcie)
+ static void tegra_pcie_downstream_dev_to_D0(struct tegra_pcie_dw *pcie)
  {
 -      struct pcie_port *pp = &pcie->pci.pp;
 +      struct dw_pcie_rp *pp = &pcie->pci.pp;
        struct pci_bus *child, *root_bus = NULL;
        struct pci_dev *pdev;
  
@@@ -1434,10 -1522,10 +1516,10 @@@ static void tegra_pcie_unconfig_control
                        pcie->cid, ret);
  }
  
- static int tegra_pcie_init_controller(struct tegra194_pcie *pcie)
+ static int tegra_pcie_init_controller(struct tegra_pcie_dw *pcie)
  {
        struct dw_pcie *pci = &pcie->pci;
 -      struct pcie_port *pp = &pci->pp;
 +      struct dw_pcie_rp *pp = &pci->pp;
        int ret;
  
        ret = tegra_pcie_config_controller(pcie, false);
@@@ -1949,13 -2082,13 +2076,13 @@@ static int tegra_pcie_config_ep(struct 
        return 0;
  }
  
- static int tegra194_pcie_probe(struct platform_device *pdev)
+ static int tegra_pcie_dw_probe(struct platform_device *pdev)
  {
-       const struct tegra194_pcie_of_data *data;
+       const struct tegra_pcie_dw_of_data *data;
        struct device *dev = &pdev->dev;
        struct resource *atu_dma_res;
-       struct tegra194_pcie *pcie;
+       struct tegra_pcie_dw *pcie;
 -      struct pcie_port *pp;
 +      struct dw_pcie_rp *pp;
        struct dw_pcie *pci;
        struct phy **phys;
        char *name;
        pci = &pcie->pci;
        pci->dev = &pdev->dev;
        pci->ops = &tegra_dw_pcie_ops;
-       pci->n_fts[0] = N_FTS_VAL;
-       pci->n_fts[1] = FTS_VAL;
+       pcie->dev = &pdev->dev;
+       pcie->of_data = (struct tegra_pcie_dw_of_data *)data;
+       pci->n_fts[0] = pcie->of_data->n_fts[0];
+       pci->n_fts[1] = pcie->of_data->n_fts[1];
 -      pci->version = pcie->of_data->version;
        pp = &pci->pp;
        pp->num_vectors = MAX_MSI_IRQS;
-       pcie->dev = &pdev->dev;
-       pcie->mode = (enum dw_pcie_device_mode)data->mode;
  
-       ret = tegra194_pcie_parse_dt(pcie);
+       ret = tegra_pcie_dw_parse_dt(pcie);
        if (ret < 0) {
                const char *level = KERN_ERR;
  
@@@ -2243,36 -2392,75 +2385,75 @@@ static int tegra_pcie_dw_resume_early(s
        return 0;
  }
  
- static void tegra194_pcie_shutdown(struct platform_device *pdev)
+ static void tegra_pcie_dw_shutdown(struct platform_device *pdev)
  {
-       struct tegra194_pcie *pcie = platform_get_drvdata(pdev);
+       struct tegra_pcie_dw *pcie = platform_get_drvdata(pdev);
  
-       if (!pcie->link_state)
-               return;
+       if (pcie->of_data->mode == DW_PCIE_RC_TYPE) {
+               if (!pcie->link_state)
+                       return;
  
-       debugfs_remove_recursive(pcie->debugfs);
-       tegra_pcie_downstream_dev_to_D0(pcie);
+               debugfs_remove_recursive(pcie->debugfs);
+               tegra_pcie_downstream_dev_to_D0(pcie);
  
-       disable_irq(pcie->pci.pp.irq);
-       if (IS_ENABLED(CONFIG_PCI_MSI))
-               disable_irq(pcie->pci.pp.msi_irq[0]);
+               disable_irq(pcie->pci.pp.irq);
+               if (IS_ENABLED(CONFIG_PCI_MSI))
 -                      disable_irq(pcie->pci.pp.msi_irq);
++                      disable_irq(pcie->pci.pp.msi_irq[0]);
  
-       tegra194_pcie_pme_turnoff(pcie);
-       tegra_pcie_unconfig_controller(pcie);
+               tegra_pcie_dw_pme_turnoff(pcie);
+               tegra_pcie_unconfig_controller(pcie);
+               pm_runtime_put_sync(pcie->dev);
+       } else {
+               disable_irq(pcie->pex_rst_irq);
+               pex_ep_event_pex_rst_assert(pcie);
+       }
  }
  
- static const struct tegra194_pcie_of_data tegra194_pcie_rc_of_data = {
+ static const struct tegra_pcie_dw_of_data tegra194_pcie_dw_rc_of_data = {
+       .version = TEGRA194_DWC_IP_VER,
+       .mode = DW_PCIE_RC_TYPE,
+       .cdm_chk_int_en_bit = BIT(19),
+       /* Gen4 - 5, 6, 8 and 9 presets enabled */
+       .gen4_preset_vec = 0x360,
+       .n_fts = { 52, 52 },
+ };
+ static const struct tegra_pcie_dw_of_data tegra194_pcie_dw_ep_of_data = {
+       .version = TEGRA194_DWC_IP_VER,
+       .mode = DW_PCIE_EP_TYPE,
+       .cdm_chk_int_en_bit = BIT(19),
+       /* Gen4 - 5, 6, 8 and 9 presets enabled */
+       .gen4_preset_vec = 0x360,
+       .n_fts = { 52, 52 },
+ };
+ static const struct tegra_pcie_dw_of_data tegra234_pcie_dw_rc_of_data = {
+       .version = TEGRA234_DWC_IP_VER,
        .mode = DW_PCIE_RC_TYPE,
+       .has_msix_doorbell_access_fix = true,
+       .has_sbr_reset_fix = true,
+       .has_l1ss_exit_fix = true,
+       .cdm_chk_int_en_bit = BIT(18),
+       /* Gen4 - 6, 8 and 9 presets enabled */
+       .gen4_preset_vec = 0x340,
+       .n_fts = { 52, 80 },
  };
  
- static const struct tegra194_pcie_of_data tegra194_pcie_ep_of_data = {
+ static const struct tegra_pcie_dw_of_data tegra234_pcie_dw_ep_of_data = {
+       .version = TEGRA234_DWC_IP_VER,
        .mode = DW_PCIE_EP_TYPE,
+       .has_l1ss_exit_fix = true,
+       .has_ltr_req_fix = true,
+       .cdm_chk_int_en_bit = BIT(18),
+       /* Gen4 - 6, 8 and 9 presets enabled */
+       .gen4_preset_vec = 0x340,
+       .n_fts = { 52, 80 },
  };
  
- static const struct of_device_id tegra194_pcie_of_match[] = {
+ static const struct of_device_id tegra_pcie_dw_of_match[] = {
        {
                .compatible = "nvidia,tegra194-pcie",
-               .data = &tegra194_pcie_rc_of_data,
+               .data = &tegra194_pcie_dw_rc_of_data,
        },
        {
                .compatible = "nvidia,tegra194-pcie-ep",
Simple merge