PCI: tegra: Implement PCA enable workaround
[platform/kernel/linux-rpi.git] / drivers / pci / host / pci-tegra.c
index d5206fa..4bfaac6 100644 (file)
 #define RP_VEND_XP     0x00000f00
 #define  RP_VEND_XP_DL_UP      (1 << 30)
 
+#define RP_VEND_CTL2 0x00000fa8
+#define  RP_VEND_CTL2_PCA_ENABLE (1 << 7)
+
 #define RP_PRIV_MISC   0x00000fe0
 #define  RP_PRIV_MISC_PRSNT_MAP_EP_PRSNT (0xe << 0)
 #define  RP_PRIV_MISC_PRSNT_MAP_EP_ABSNT (0xf << 0)
@@ -252,6 +255,7 @@ struct tegra_pcie_soc {
        bool has_intr_prsnt_sense;
        bool has_cml_clk;
        bool has_gen2;
+       bool force_pca_enable;
 };
 
 static inline struct tegra_msi *to_tegra_msi(struct msi_controller *chip)
@@ -556,6 +560,12 @@ static void tegra_pcie_port_enable(struct tegra_pcie_port *port)
        afi_writel(port->pcie, value, ctrl);
 
        tegra_pcie_port_reset(port);
+
+       if (soc->force_pca_enable) {
+               value = readl(port->base + RP_VEND_CTL2);
+               value |= RP_VEND_CTL2_PCA_ENABLE;
+               writel(value, port->base + RP_VEND_CTL2);
+       }
 }
 
 static void tegra_pcie_port_disable(struct tegra_pcie_port *port)
@@ -2046,6 +2056,7 @@ static const struct tegra_pcie_soc tegra20_pcie = {
        .has_intr_prsnt_sense = false,
        .has_cml_clk = false,
        .has_gen2 = false,
+       .force_pca_enable = false,
 };
 
 static const struct tegra_pcie_soc tegra30_pcie = {
@@ -2060,6 +2071,7 @@ static const struct tegra_pcie_soc tegra30_pcie = {
        .has_intr_prsnt_sense = true,
        .has_cml_clk = true,
        .has_gen2 = false,
+       .force_pca_enable = false,
 };
 
 static const struct tegra_pcie_soc tegra124_pcie = {
@@ -2073,6 +2085,7 @@ static const struct tegra_pcie_soc tegra124_pcie = {
        .has_intr_prsnt_sense = true,
        .has_cml_clk = true,
        .has_gen2 = true,
+       .force_pca_enable = false,
 };
 
 static const struct of_device_id tegra_pcie_of_match[] = {