forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/arch/powerpc/platforms/pasemi/pci.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2006 PA Semi, Inc
34 *
....@@ -7,19 +8,6 @@
78 * Maintained by: Olof Johansson <olof@lixom.net>
89 *
910 * Based on arch/powerpc/platforms/maple/pci.c
10
- *
11
- * This program is free software; you can redistribute it and/or modify
12
- * it under the terms of the GNU General Public License version 2 as
13
- * published by the Free Software Foundation.
14
- *
15
- * This program is distributed in the hope that it will be useful,
16
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
- * GNU General Public License for more details.
19
- *
20
- * You should have received a copy of the GNU General Public License
21
- * along with this program; if not, write to the Free Software
22
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
2311 */
2412
2513
....@@ -27,6 +15,7 @@
2715 #include <linux/pci.h>
2816
2917 #include <asm/pci-bridge.h>
18
+#include <asm/isa-bridge.h>
3019 #include <asm/machdep.h>
3120
3221 #include <asm/ppc-pci.h>
....@@ -108,6 +97,61 @@
10897 return 1;
10998 }
11099
100
+#ifdef CONFIG_PPC_PASEMI_NEMO
101
+#define PXP_ERR_CFG_REG 0x4
102
+#define PXP_IGNORE_PCIE_ERRORS 0x800
103
+#define SB600_BUS 5
104
+
105
+static void sb600_set_flag(int bus)
106
+{
107
+ static void __iomem *iob_mapbase = NULL;
108
+ struct resource res;
109
+ struct device_node *dn;
110
+ int err;
111
+
112
+ if (iob_mapbase == NULL) {
113
+ dn = of_find_compatible_node(NULL, "isa", "pasemi,1682m-iob");
114
+ if (!dn) {
115
+ pr_crit("NEMO SB600 missing iob node\n");
116
+ return;
117
+ }
118
+
119
+ err = of_address_to_resource(dn, 0, &res);
120
+ of_node_put(dn);
121
+
122
+ if (err) {
123
+ pr_crit("NEMO SB600 missing resource\n");
124
+ return;
125
+ }
126
+
127
+ pr_info("NEMO SB600 IOB base %08llx\n",res.start);
128
+
129
+ iob_mapbase = ioremap(res.start + 0x100, 0x94);
130
+ }
131
+
132
+ if (iob_mapbase != NULL) {
133
+ if (bus == SB600_BUS) {
134
+ /*
135
+ * This is the SB600's bus, tell the PCI-e root port
136
+ * to allow non-zero devices to enumerate.
137
+ */
138
+ out_le32(iob_mapbase + PXP_ERR_CFG_REG, in_le32(iob_mapbase + PXP_ERR_CFG_REG) | PXP_IGNORE_PCIE_ERRORS);
139
+ } else {
140
+ /*
141
+ * Only scan device 0 on other busses
142
+ */
143
+ out_le32(iob_mapbase + PXP_ERR_CFG_REG, in_le32(iob_mapbase + PXP_ERR_CFG_REG) & ~PXP_IGNORE_PCIE_ERRORS);
144
+ }
145
+ }
146
+}
147
+
148
+#else
149
+
150
+static void sb600_set_flag(int bus)
151
+{
152
+}
153
+#endif
154
+
111155 static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn,
112156 int offset, int len, u32 *val)
113157 {
....@@ -125,6 +169,8 @@
125169 return PCIBIOS_SUCCESSFUL;
126170
127171 addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);
172
+
173
+ sb600_set_flag(bus->number);
128174
129175 /*
130176 * Note: the caller has already checked that offset is
....@@ -159,6 +205,8 @@
159205 return PCIBIOS_BAD_REGISTER_NUMBER;
160206
161207 addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);
208
+
209
+ sb600_set_flag(bus->number);
162210
163211 /*
164212 * Note: the caller has already checked that offset is
....@@ -210,6 +258,12 @@
210258 /* Interpret the "ranges" property */
211259 pci_process_bridge_OF_ranges(hose, dev, 1);
212260
261
+ /*
262
+ * Scan for an isa bridge. This is needed to find the SB600 on the nemo
263
+ * and does nothing on machines without one.
264
+ */
265
+ isa_bridge_find_early(hose);
266
+
213267 return 0;
214268 }
215269