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;
        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
                                    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);
        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;
        }
        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;
  
                        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);
        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;
  
        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",