13
13
14
14
#include <linux/bitops.h>
15
15
#include <linux/clk.h>
16
+ #include <linux/clk-provider.h>
16
17
#include <linux/delay.h>
17
18
#include <linux/interrupt.h>
18
19
#include <linux/irq.h>
19
20
#include <linux/irqdomain.h>
20
21
#include <linux/kernel.h>
21
22
#include <linux/init.h>
23
+ #include <linux/iopoll.h>
22
24
#include <linux/msi.h>
23
25
#include <linux/of_address.h>
24
26
#include <linux/of_irq.h>
@@ -41,6 +43,21 @@ struct rcar_msi {
41
43
int irq2 ;
42
44
};
43
45
46
+ #ifdef CONFIG_ARM
47
+ /*
48
+ * Here we keep a static copy of the remapped PCIe controller address.
49
+ * This is only used on aarch32 systems, all of which have one single
50
+ * PCIe controller, to provide quick access to the PCIe controller in
51
+ * the L1 link state fixup function, called from the ARM fault handler.
52
+ */
53
+ static void __iomem * pcie_base ;
54
+ /*
55
+ * Static copy of bus clock pointer, so we can check whether the clock
56
+ * is enabled or not.
57
+ */
58
+ static struct clk * pcie_bus_clk ;
59
+ #endif
60
+
44
61
/* Structure representing the PCIe interface */
45
62
struct rcar_pcie_host {
46
63
struct rcar_pcie pcie ;
@@ -774,6 +791,12 @@ static int rcar_pcie_get_resources(struct rcar_pcie_host *host)
774
791
}
775
792
host -> msi .irq2 = i ;
776
793
794
+ #ifdef CONFIG_ARM
795
+ /* Cache static copy for L1 link state fixup hook on aarch32 */
796
+ pcie_base = pcie -> base ;
797
+ pcie_bus_clk = host -> bus_clk ;
798
+ #endif
799
+
777
800
return 0 ;
778
801
779
802
err_irq2 :
@@ -1029,4 +1052,67 @@ static struct platform_driver rcar_pcie_driver = {
1029
1052
},
1030
1053
.probe = rcar_pcie_probe ,
1031
1054
};
1055
+
1056
+ #ifdef CONFIG_ARM
1057
+ static DEFINE_SPINLOCK (pmsr_lock );
1058
+ static int rcar_pcie_aarch32_abort_handler (unsigned long addr ,
1059
+ unsigned int fsr , struct pt_regs * regs )
1060
+ {
1061
+ unsigned long flags ;
1062
+ u32 pmsr , val ;
1063
+ int ret = 0 ;
1064
+
1065
+ spin_lock_irqsave (& pmsr_lock , flags );
1066
+
1067
+ if (!pcie_base || !__clk_is_enabled (pcie_bus_clk )) {
1068
+ ret = 1 ;
1069
+ goto unlock_exit ;
1070
+ }
1071
+
1072
+ pmsr = readl (pcie_base + PMSR );
1073
+
1074
+ /*
1075
+ * Test if the PCIe controller received PM_ENTER_L1 DLLP and
1076
+ * the PCIe controller is not in L1 link state. If true, apply
1077
+ * fix, which will put the controller into L1 link state, from
1078
+ * which it can return to L0s/L0 on its own.
1079
+ */
1080
+ if ((pmsr & PMEL1RX ) && ((pmsr & PMSTATE ) != PMSTATE_L1 )) {
1081
+ writel (L1IATN , pcie_base + PMCTLR );
1082
+ ret = readl_poll_timeout_atomic (pcie_base + PMSR , val ,
1083
+ val & L1FAEG , 10 , 1000 );
1084
+ WARN (ret , "Timeout waiting for L1 link state, ret=%d\n" , ret );
1085
+ writel (L1FAEG | PMEL1RX , pcie_base + PMSR );
1086
+ }
1087
+
1088
+ unlock_exit :
1089
+ spin_unlock_irqrestore (& pmsr_lock , flags );
1090
+ return ret ;
1091
+ }
1092
+
1093
+ static const struct of_device_id rcar_pcie_abort_handler_of_match [] __initconst = {
1094
+ { .compatible = "renesas,pcie-r8a7779" },
1095
+ { .compatible = "renesas,pcie-r8a7790" },
1096
+ { .compatible = "renesas,pcie-r8a7791" },
1097
+ { .compatible = "renesas,pcie-rcar-gen2" },
1098
+ {},
1099
+ };
1100
+
1101
+ static int __init rcar_pcie_init (void )
1102
+ {
1103
+ if (of_find_matching_node (NULL , rcar_pcie_abort_handler_of_match )) {
1104
+ #ifdef CONFIG_ARM_LPAE
1105
+ hook_fault_code (17 , rcar_pcie_aarch32_abort_handler , SIGBUS , 0 ,
1106
+ "asynchronous external abort" );
1107
+ #else
1108
+ hook_fault_code (22 , rcar_pcie_aarch32_abort_handler , SIGBUS , 0 ,
1109
+ "imprecise external abort" );
1110
+ #endif
1111
+ }
1112
+
1113
+ return platform_driver_register (& rcar_pcie_driver );
1114
+ }
1115
+ device_initcall (rcar_pcie_init );
1116
+ #else
1032
1117
builtin_platform_driver (rcar_pcie_driver );
1118
+ #endif
0 commit comments