ath79/mikrotik: use routerbootpart partitions
[oweals/openwrt.git] / target / linux / layerscape / patches-5.4 / 812-pcie-0013-PCI-mobiveil-ls_pcie_g4-add-Workaround-for-A-011577.patch
1 From 7f38d09c9fd7906cea160e198299a7e378f9c796 Mon Sep 17 00:00:00 2001
2 From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
3 Date: Tue, 6 Nov 2018 09:44:05 +0800
4 Subject: [PATCH] PCI: mobiveil: ls_pcie_g4: add Workaround for A-011577
5
6 PCIe configuration access to non-existent function triggered
7 SERROR interrupt exception.
8
9 Workaround:
10 Disable error reporting on AXI bus during the Vendor ID read
11 transactions in enumeration.
12
13 This ERRATA is only for LX2160A Rev1.0, and it will be fixed
14 in Rev2.0.
15
16 Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
17 ---
18  .../pci/controller/mobiveil/pcie-layerscape-gen4.c | 36 ++++++++++++++++++++++
19  .../pci/controller/mobiveil/pcie-mobiveil-host.c   | 17 +++++++++-
20  drivers/pci/controller/mobiveil/pcie-mobiveil.h    |  3 ++
21  3 files changed, 55 insertions(+), 1 deletion(-)
22
23 --- a/drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c
24 +++ b/drivers/pci/controller/mobiveil/pcie-layerscape-gen4.c
25 @@ -22,8 +22,12 @@
26  
27  #include "pcie-mobiveil.h"
28  
29 +#define REV_1_0                                (0x10)
30 +
31  /* LUT and PF control registers */
32  #define PCIE_LUT_OFF                   0x80000
33 +#define PCIE_LUT_GCR                   (0x28)
34 +#define PCIE_LUT_GCR_RRE               (0)
35  #define PCIE_PF_OFF                    0xc0000
36  #define PCIE_PF_INT_STAT               0x18
37  #define PF_INT_STAT_PABRST             BIT(31)
38 @@ -40,6 +44,7 @@ struct ls_pcie_g4 {
39         struct mobiveil_pcie pci;
40         struct delayed_work dwork;
41         int irq;
42 +       u8 rev;
43  };
44  
45  static inline u32 ls_pcie_g4_lut_readl(struct ls_pcie_g4 *pcie, u32 off)
46 @@ -75,6 +80,15 @@ static bool ls_pcie_g4_is_bridge(struct
47         return header_type == PCI_HEADER_TYPE_BRIDGE;
48  }
49  
50 +static int ls_pcie_g4_host_init(struct mobiveil_pcie *pci)
51 +{
52 +       struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
53 +
54 +       pcie->rev = csr_readb(pci, PCI_REVISION_ID);
55 +
56 +       return 0;
57 +}
58 +
59  static int ls_pcie_g4_link_up(struct mobiveil_pcie *pci)
60  {
61         struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
62 @@ -206,12 +220,34 @@ static void ls_pcie_g4_reset(struct work
63         ls_pcie_g4_enable_interrupt(pcie);
64  }
65  
66 +static int ls_pcie_g4_read_other_conf(struct pci_bus *bus, unsigned int devfn,
67 +                                  int where, int size, u32 *val)
68 +{
69 +       struct mobiveil_pcie *pci = bus->sysdata;
70 +       struct ls_pcie_g4 *pcie = to_ls_pcie_g4(pci);
71 +       int ret;
72 +
73 +       if (pcie->rev == REV_1_0 && where == PCI_VENDOR_ID)
74 +               ls_pcie_g4_lut_writel(pcie, PCIE_LUT_GCR,
75 +                                     0 << PCIE_LUT_GCR_RRE);
76 +
77 +       ret = pci_generic_config_read(bus, devfn, where, size, val);
78 +
79 +       if (pcie->rev == REV_1_0 && where == PCI_VENDOR_ID)
80 +               ls_pcie_g4_lut_writel(pcie, PCIE_LUT_GCR,
81 +                                     1 << PCIE_LUT_GCR_RRE);
82 +
83 +       return ret;
84 +}
85 +
86  static struct mobiveil_rp_ops ls_pcie_g4_rp_ops = {
87         .interrupt_init = ls_pcie_g4_interrupt_init,
88 +       .read_other_conf = ls_pcie_g4_read_other_conf,
89  };
90  
91  static const struct mobiveil_pab_ops ls_pcie_g4_pab_ops = {
92         .link_up = ls_pcie_g4_link_up,
93 +       .host_init = ls_pcie_g4_host_init,
94  };
95  
96  static int __init ls_pcie_g4_probe(struct platform_device *pdev)
97 --- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
98 +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
99 @@ -77,9 +77,20 @@ static void __iomem *mobiveil_pcie_map_b
100         return pcie->rp.config_axi_slave_base + where;
101  }
102  
103 +static int mobiveil_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
104 +                                    int where, int size, u32 *val)
105 +{
106 +       struct mobiveil_pcie *pcie = bus->sysdata;
107 +       struct root_port *rp = &pcie->rp;
108 +
109 +       if (bus->number > rp->root_bus_nr && rp->ops->read_other_conf)
110 +               return rp->ops->read_other_conf(bus, devfn, where, size, val);
111 +
112 +       return pci_generic_config_read(bus, devfn, where, size, val);
113 +}
114  static struct pci_ops mobiveil_pcie_ops = {
115         .map_bus = mobiveil_pcie_map_bus,
116 -       .read = pci_generic_config_read,
117 +       .read = mobiveil_pcie_config_read,
118         .write = pci_generic_config_write,
119  };
120  
121 @@ -300,6 +311,10 @@ int mobiveil_host_init(struct mobiveil_p
122         value |= (PCI_CLASS_BRIDGE_PCI << 16);
123         csr_writel(pcie, value, PAB_INTP_AXI_PIO_CLASS);
124  
125 +       /* Platform specific host init */
126 +       if (pcie->ops->host_init)
127 +               return pcie->ops->host_init(pcie);
128 +
129         return 0;
130  }
131  
132 --- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
133 +++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
134 @@ -146,6 +146,8 @@ struct mobiveil_msi {                       /* MSI informati
135  
136  struct mobiveil_rp_ops {
137         int (*interrupt_init)(struct mobiveil_pcie *pcie);
138 +       int (*read_other_conf)(struct pci_bus *bus, unsigned int devfn,
139 +                              int where, int size, u32 *val);
140  };
141  
142  struct root_port {
143 @@ -161,6 +163,7 @@ struct root_port {
144  
145  struct mobiveil_pab_ops {
146         int (*link_up)(struct mobiveil_pcie *pcie);
147 +       int (*host_init)(struct mobiveil_pcie *pcie);
148  };
149  
150  struct mobiveil_pcie {