-
Notifications
You must be signed in to change notification settings - Fork 2
/
0012-rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch
194 lines (182 loc) · 7.93 KB
/
0012-rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
From ceae51b1cc0e5a5b42999274657bd55606193661 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jari=20H=C3=A4m=C3=A4l=C3=A4inen?= <[email protected]>
Date: Sun, 22 Nov 2020 15:24:49 +0200
Subject: [PATCH] nuumio: pcie: Reimplement rockchip PCIe bus scan delay
Reimplementation of my old Rockchip PCIe bus scan delay patch for
kernels >= 5.9.
Delay may fix panix with some PCIe devices, like LSI SAS 9201-8i with
SAS2008 chipset in my case.
Crash dump (customized Manjaro kernel before this patch):
[ 1.229856] SError Interrupt on CPU4, code 0xbf000002 -- SError
[ 1.229860] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.9.9-2.0-MANJARO-ARM #1
[ 1.229862] Hardware name: Pine64 RockPro64 v2.1 (DT)
[ 1.229864] pstate: 60000085 (nZCv daIf -PAN -UAO BTYPE=--)
[ 1.229866] pc : rockchip_pcie_rd_conf+0xb4/0x270
[ 1.229868] lr : rockchip_pcie_rd_conf+0x1b4/0x270
[ 1.229870] sp : ffff80001004b850
[ 1.229872] x29: ffff80001004b850 x28: 0000000000000001
[ 1.229877] x27: 0000000000000000 x26: ffff00007a795000
[ 1.229882] x25: ffff00007a7910b0 x24: 0000000000000000
[ 1.229887] x23: 0000000000000000 x22: ffff00007b3a4380
[ 1.229891] x21: ffff80001004b8c4 x20: 0000000000000004
[ 1.229895] x19: 0000000000100000 x18: 0000000000000020
[ 1.229900] x17: 0000000000000001 x16: 0000000000000019
[ 1.229904] x15: ffff00007b222fd8 x14: ffffffffffffffff
[ 1.229908] x13: ffff00007a79ba1c x12: ffff00007a79b290
[ 1.229912] x11: 0101010101010101 x10: 7f7f7f7f7f7f7f7f
[ 1.229917] x9 : ff72646268756463 x8 : 0000000000000391
[ 1.229921] x7 : ffff80001004b880 x6 : 0000000000000001
[ 1.229925] x5 : 0000000000000000 x4 : 0000000000000000
[ 1.229930] x3 : 0000000000c00008 x2 : 000000000080000a
[ 1.229934] x1 : 0000000000000000 x0 : ffff800014000000
[ 1.229939] Kernel panic - not syncing: Asynchronous SError Interrupt
[ 1.229942] CPU: 4 PID: 1 Comm: swapper/0 Not tainted 5.9.9-2.0-MANJARO-ARM #1
[ 1.229944] Hardware name: Pine64 RockPro64 v2.1 (DT)
[ 1.229946] Call trace:
[ 1.229948] dump_backtrace+0x0/0x1d0
[ 1.229949] show_stack+0x18/0x24
[ 1.229951] dump_stack+0xc0/0x118
[ 1.229953] panic+0x148/0x320
[ 1.229955] nmi_panic+0x8c/0x90
[ 1.229956] arm64_serror_panic+0x78/0x84
[ 1.229958] do_serror+0x15c/0x160
[ 1.229960] el1_error+0x84/0x100
[ 1.229962] rockchip_pcie_rd_conf+0xb4/0x270
[ 1.229964] pci_bus_read_config_dword+0x6c/0xd0
[ 1.229966] pci_bus_generic_read_dev_vendor_id+0x34/0x1b0
[ 1.229968] pci_scan_single_device+0xa4/0x144
[ 1.229970] pci_scan_slot+0x40/0x12c
[ 1.229972] pci_scan_child_bus_extend+0x58/0x34c
[ 1.229974] pci_scan_bridge_extend+0x310/0x590
[ 1.229976] pci_scan_child_bus_extend+0x210/0x34c
[ 1.229978] pci_scan_root_bus_bridge+0x68/0xdc
[ 1.229980] pci_host_probe+0x18/0xc4
[ 1.229981] rockchip_pcie_probe+0x204/0x330
[ 1.229984] platform_drv_probe+0x54/0xb0
[ 1.229985] really_probe+0xe8/0x500
[ 1.229987] driver_probe_device+0xd8/0xf0
[ 1.229989] device_driver_attach+0xc0/0xcc
[ 1.229991] __driver_attach+0xa4/0x170
[ 1.229993] bus_for_each_dev+0x70/0xc0
[ 1.229994] driver_attach+0x24/0x30
[ 1.229996] bus_add_driver+0x140/0x234
[ 1.229998] driver_register+0x78/0x130
[ 1.230000] __platform_driver_register+0x4c/0x60
[ 1.230002] rockchip_pcie_driver_init+0x1c/0x28
[ 1.230004] do_one_initcall+0x54/0x1c0
[ 1.230005] do_initcalls+0xf4/0x130
[ 1.230007] kernel_init_freeable+0x144/0x19c
[ 1.230009] kernel_init+0x14/0x11c
[ 1.230011] ret_from_fork+0x10/0x34
[ 1.230035] SMP: stopping secondary CPUs
[ 1.230037] Kernel Offset: disabled
[ 1.230039] CPU features: 0x0240022,2100200c
[ 1.230041] Memory Limit: none
---
.../admin-guide/kernel-parameters.txt | 8 ++++++
.../boot/dts/rockchip/rk3399-rockpro64.dtsi | 1 +
drivers/pci/controller/pcie-rockchip-host.c | 25 +++++++++++++++++++
drivers/pci/controller/pcie-rockchip.c | 6 +++++
drivers/pci/controller/pcie-rockchip.h | 2 ++
5 files changed, 42 insertions(+)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 44fde25bb221..941dc943eb84 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -3816,6 +3816,14 @@
nomsi Do not use MSI for native PCIe PME signaling (this makes
all PCIe root ports use INTx for all services).
+ pcie_rockchip_host.bus_scan_delay= [PCIE] Delay in ms before
+ scanning PCIe bus in Rockchip PCIe host driver. Some PCIe
+ cards seem to need delays that can be several hundred ms.
+ If set to greater than or equal to 0 this parameter will
+ override delay that can be set in device tree.
+ Values less than 0 mean that this parameter is ignored.
+ default=-1
+
pcmv= [HW,PCMCIA] BadgePAD 4
pd_ignore_unused
diff --git a/drivers/pci/controller/pcie-rockchip-host.c b/drivers/pci/controller/pcie-rockchip-host.c
index 9705059523a6..632dac43a037 100644
--- a/drivers/pci/controller/pcie-rockchip-host.c
+++ b/drivers/pci/controller/pcie-rockchip-host.c
@@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
+#include <linux/moduleparam.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_pci.h>
@@ -39,6 +40,9 @@
#include "../pci.h"
#include "pcie-rockchip.h"
+static int bus_scan_delay = -1;
+module_param_named(bus_scan_delay, bus_scan_delay, int, S_IRUGO);
+
static void rockchip_pcie_enable_bw_int(struct rockchip_pcie *rockchip)
{
u32 status;
@@ -942,6 +946,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct pci_host_bridge *bridge;
int err;
+ u32 delay = 0;
if (!dev->of_node)
return -ENODEV;
@@ -993,6 +998,26 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
bridge->sysdata = rockchip;
bridge->ops = &rockchip_pcie_ops;
+ /* Checking if bus scan delay was given from command line and prefer
+ * that over the value in device tree (which defaults to 0 if not set).
+ */
+ if (bus_scan_delay >= 0) {
+ delay = bus_scan_delay;
+ dev_info(dev, "wait %u ms (from command-line) before bus scan\n", delay);
+ } else {
+ delay = rockchip->bus_scan_delay;
+ dev_info(dev, "wait %u ms (from device tree) before bus scan\n", delay);
+ }
+ /* Workaround for some devices crashing on pci_host_probe / pci_scan_root_bus_bridge
+ * calls: sleep a bit before bus scan. Call trace gets to rockchip_pcie_rd_conf when
+ * trying to read vendor id (pci_bus_generic_read_dev_vendor_id is in call stack)
+ * before panicing. I have no idea why this works or what causes the panic. I just
+ * found this hack by luck when trying to "make it break differently if possible".
+ */
+ if (delay > 0) {
+ msleep(delay);
+ }
+
err = pci_host_probe(bridge);
if (err < 0)
goto err_remove_irq_domain;
diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c
index 904dec0d3a88..e6c97f9944ba 100644
--- a/drivers/pci/controller/pcie-rockchip.c
+++ b/drivers/pci/controller/pcie-rockchip.c
@@ -149,6 +149,12 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
return PTR_ERR(rockchip->clk_pcie_pm);
}
+ err = of_property_read_u32(node, "bus-scan-delay-ms", &rockchip->bus_scan_delay);
+ if (err) {
+ dev_info(dev, "no bus scan delay, default to 0 ms\n");
+ rockchip->bus_scan_delay = 0;
+ }
+
return 0;
}
EXPORT_SYMBOL_GPL(rockchip_pcie_parse_dt);
diff --git a/drivers/pci/controller/pcie-rockchip.h b/drivers/pci/controller/pcie-rockchip.h
index c7d0178fc8c2..52fd2108b704 100644
--- a/drivers/pci/controller/pcie-rockchip.h
+++ b/drivers/pci/controller/pcie-rockchip.h
@@ -306,6 +306,8 @@ struct rockchip_pcie {
phys_addr_t msg_bus_addr;
bool is_rc;
struct resource *mem_res;
+ /* Bus scan delay is a workaround for some pcie devices causing crashes */
+ u32 bus_scan_delay;
};
static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg)
--
2.29.2