From 7be9e8b99590e32c0594365d00a2a2cfc3c4bd5a Mon Sep 17 00:00:00 2001 From: Dan Pasanen Date: Thu, 16 Dec 2021 04:17:33 -0600 Subject: [PATCH] rockchip-[current,edge]: add pcie hack and lsi scsi/sas support (#3351) * build: kernel: rockchip64-[current,edge]: add pcie bus scan delay patches These are needed for cards like the LSI SAS2008 which needs a little extra time to initialize or they'll cause a kernel panic. References: https://gitlab.manjaro.org/manjaro-arm/packages/core/linux/-/blob/master/0013-rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch https://gitlab.manjaro.org/manjaro-arm/packages/core/linux/-/blob/master/0022-arm64-dts-rockchip-Add-pcie-bus-scan-delay-to-rockpr.patch * config: linux-rockchip64-[current,edge]: enable lsi sata/sas support --- config/kernel/linux-rockchip64-current.config | 8 +- config/kernel/linux-rockchip64-edge.config | 8 +- ...99-rockpro64-Add-pcie-bus-scan-delay.patch | 12 ++ ...plement-rockchip-PCIe-bus-scan-delay.patch | 106 ++++++++++++++++++ ...99-rockpro64-Add-pcie-bus-scan-delay.patch | 12 ++ ...plement-rockchip-PCIe-bus-scan-delay.patch | 106 ++++++++++++++++++ 6 files changed, 246 insertions(+), 6 deletions(-) create mode 100644 patch/kernel/archive/rockchip64-5.10/board-rockpis-0031-arm64-dts-rk3399-rockpro64-Add-pcie-bus-scan-delay.patch create mode 100644 patch/kernel/archive/rockchip64-5.10/rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch create mode 100644 patch/kernel/archive/rockchip64-5.15/board-rockpis-0031-arm64-dts-rk3399-rockpro64-Add-pcie-bus-scan-delay.patch create mode 100644 patch/kernel/archive/rockchip64-5.15/rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch diff --git a/config/kernel/linux-rockchip64-current.config b/config/kernel/linux-rockchip64-current.config index f0ee0c8808..5195407565 100644 --- a/config/kernel/linux-rockchip64-current.config +++ b/config/kernel/linux-rockchip64-current.config @@ -2281,7 +2281,7 @@ CONFIG_HABANA_AI=m # SCSI device support # CONFIG_SCSI_MOD=y -# CONFIG_RAID_ATTRS is not set +CONFIG_RAID_ATTRS=m CONFIG_SCSI=y CONFIG_SCSI_DMA=y # CONFIG_SCSI_PROC_FS is not set @@ -2336,8 +2336,10 @@ CONFIG_SCSI_HISI_SAS=y # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_MPT3SAS is not set -# CONFIG_SCSI_MPT2SAS is not set +CONFIG_SCSI_MPT3SAS=m +CONFIG_SCSI_MPT2SAS_MAX_SGE=128 +CONFIG_SCSI_MPT3SAS_MAX_SGE=128 +CONFIG_SCSI_MPT2SAS=m # CONFIG_SCSI_SMARTPQI is not set # CONFIG_SCSI_UFSHCD is not set # CONFIG_SCSI_HPTIOP is not set diff --git a/config/kernel/linux-rockchip64-edge.config b/config/kernel/linux-rockchip64-edge.config index 2e4c32030e..60ad077858 100644 --- a/config/kernel/linux-rockchip64-edge.config +++ b/config/kernel/linux-rockchip64-edge.config @@ -2377,7 +2377,7 @@ CONFIG_HABANA_AI=m # SCSI device support # CONFIG_SCSI_MOD=y -# CONFIG_RAID_ATTRS is not set +CONFIG_RAID_ATTRS=m CONFIG_SCSI_COMMON=y CONFIG_SCSI=y CONFIG_SCSI_DMA=y @@ -2435,8 +2435,10 @@ CONFIG_SCSI_HISI_SAS=y # CONFIG_MEGARAID_NEWGEN is not set # CONFIG_MEGARAID_LEGACY is not set # CONFIG_MEGARAID_SAS is not set -# CONFIG_SCSI_MPT3SAS is not set -# CONFIG_SCSI_MPT2SAS is not set +CONFIG_SCSI_MPT3SAS=m +CONFIG_SCSI_MPT2SAS_MAX_SGE=128 +CONFIG_SCSI_MPT3SAS_MAX_SGE=128 +CONFIG_SCSI_MPT2SAS=m CONFIG_SCSI_MPI3MR=m # CONFIG_SCSI_SMARTPQI is not set # CONFIG_SCSI_UFSHCD is not set diff --git a/patch/kernel/archive/rockchip64-5.10/board-rockpis-0031-arm64-dts-rk3399-rockpro64-Add-pcie-bus-scan-delay.patch b/patch/kernel/archive/rockchip64-5.10/board-rockpis-0031-arm64-dts-rk3399-rockpro64-Add-pcie-bus-scan-delay.patch new file mode 100644 index 0000000000..a8d60d01a9 --- /dev/null +++ b/patch/kernel/archive/rockchip64-5.10/board-rockpis-0031-arm64-dts-rk3399-rockpro64-Add-pcie-bus-scan-delay.patch @@ -0,0 +1,12 @@ +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi +index bfd57f6f0..5374753cd 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi +@@ -579,6 +579,7 @@ &pcie0 { + pinctrl-0 = <&pcie_perst>; + vpcie12v-supply = <&vcc12v_dcin>; + vpcie3v3-supply = <&vcc3v3_pcie>; ++ bus-scan-delay-ms = <1000>; + status = "okay"; + }; + diff --git a/patch/kernel/archive/rockchip64-5.10/rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch b/patch/kernel/archive/rockchip64-5.10/rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch new file mode 100644 index 0000000000..540435944f --- /dev/null +++ b/patch/kernel/archive/rockchip64-5.10/rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch @@ -0,0 +1,106 @@ +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index 1396fd2d9..4d583446c 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -4079,6 +4079,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 c52316d0b..a7974007d 100644 +--- a/drivers/pci/controller/pcie-rockchip-host.c ++++ b/drivers/pci/controller/pcie-rockchip-host.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -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; +@@ -935,6 +939,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; +@@ -984,6 +989,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 = rockchip_pcie_setup_irq(rockchip); + if (err) + goto err_remove_irq_domain; +diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c +index 193d26562..ec6cbaadd 100644 +--- a/drivers/pci/controller/pcie-rockchip.c ++++ b/drivers/pci/controller/pcie-rockchip.c +@@ -148,6 +148,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 1650a5087..35a8cf157 100644 +--- a/drivers/pci/controller/pcie-rockchip.h ++++ b/drivers/pci/controller/pcie-rockchip.h +@@ -300,6 +300,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) diff --git a/patch/kernel/archive/rockchip64-5.15/board-rockpis-0031-arm64-dts-rk3399-rockpro64-Add-pcie-bus-scan-delay.patch b/patch/kernel/archive/rockchip64-5.15/board-rockpis-0031-arm64-dts-rk3399-rockpro64-Add-pcie-bus-scan-delay.patch new file mode 100644 index 0000000000..a8d60d01a9 --- /dev/null +++ b/patch/kernel/archive/rockchip64-5.15/board-rockpis-0031-arm64-dts-rk3399-rockpro64-Add-pcie-bus-scan-delay.patch @@ -0,0 +1,12 @@ +diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi +index bfd57f6f0..5374753cd 100644 +--- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi ++++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi +@@ -579,6 +579,7 @@ &pcie0 { + pinctrl-0 = <&pcie_perst>; + vpcie12v-supply = <&vcc12v_dcin>; + vpcie3v3-supply = <&vcc3v3_pcie>; ++ bus-scan-delay-ms = <1000>; + status = "okay"; + }; + diff --git a/patch/kernel/archive/rockchip64-5.15/rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch b/patch/kernel/archive/rockchip64-5.15/rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch new file mode 100644 index 0000000000..540435944f --- /dev/null +++ b/patch/kernel/archive/rockchip64-5.15/rk3399-rp64-pcie-Reimplement-rockchip-PCIe-bus-scan-delay.patch @@ -0,0 +1,106 @@ +diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt +index 1396fd2d9..4d583446c 100644 +--- a/Documentation/admin-guide/kernel-parameters.txt ++++ b/Documentation/admin-guide/kernel-parameters.txt +@@ -4079,6 +4079,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 c52316d0b..a7974007d 100644 +--- a/drivers/pci/controller/pcie-rockchip-host.c ++++ b/drivers/pci/controller/pcie-rockchip-host.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -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; +@@ -935,6 +939,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; +@@ -984,6 +989,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 = rockchip_pcie_setup_irq(rockchip); + if (err) + goto err_remove_irq_domain; +diff --git a/drivers/pci/controller/pcie-rockchip.c b/drivers/pci/controller/pcie-rockchip.c +index 193d26562..ec6cbaadd 100644 +--- a/drivers/pci/controller/pcie-rockchip.c ++++ b/drivers/pci/controller/pcie-rockchip.c +@@ -148,6 +148,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 1650a5087..35a8cf157 100644 +--- a/drivers/pci/controller/pcie-rockchip.h ++++ b/drivers/pci/controller/pcie-rockchip.h +@@ -300,6 +300,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)