18
18
19
19
#include "pcie-designware.h"
20
20
21
+ #define PEX_PF0_CONFIG 0xC0014
22
+ #define PEX_PF0_CFG_READY BIT(0)
23
+
24
+ /* PEX PFa PCIE PME and message interrupt registers*/
25
+ #define PEX_PF0_PME_MES_DR 0xC0020
26
+ #define PEX_PF0_PME_MES_DR_LUD BIT(7)
27
+ #define PEX_PF0_PME_MES_DR_LDD BIT(9)
28
+ #define PEX_PF0_PME_MES_DR_HRD BIT(10)
29
+
30
+ #define PEX_PF0_PME_MES_IER 0xC0028
31
+ #define PEX_PF0_PME_MES_IER_LUDIE BIT(7)
32
+ #define PEX_PF0_PME_MES_IER_LDDIE BIT(9)
33
+ #define PEX_PF0_PME_MES_IER_HRDIE BIT(10)
34
+
21
35
#define to_ls_pcie_ep (x ) dev_get_drvdata((x)->dev)
22
36
23
37
struct ls_pcie_ep_drvdata {
@@ -30,8 +44,84 @@ struct ls_pcie_ep {
30
44
struct dw_pcie * pci ;
31
45
struct pci_epc_features * ls_epc ;
32
46
const struct ls_pcie_ep_drvdata * drvdata ;
47
+ int irq ;
48
+ bool big_endian ;
33
49
};
34
50
51
+ static u32 ls_lut_readl (struct ls_pcie_ep * pcie , u32 offset )
52
+ {
53
+ struct dw_pcie * pci = pcie -> pci ;
54
+
55
+ if (pcie -> big_endian )
56
+ return ioread32be (pci -> dbi_base + offset );
57
+ else
58
+ return ioread32 (pci -> dbi_base + offset );
59
+ }
60
+
61
+ static void ls_lut_writel (struct ls_pcie_ep * pcie , u32 offset , u32 value )
62
+ {
63
+ struct dw_pcie * pci = pcie -> pci ;
64
+
65
+ if (pcie -> big_endian )
66
+ iowrite32be (value , pci -> dbi_base + offset );
67
+ else
68
+ iowrite32 (value , pci -> dbi_base + offset );
69
+ }
70
+
71
+ static irqreturn_t ls_pcie_ep_event_handler (int irq , void * dev_id )
72
+ {
73
+ struct ls_pcie_ep * pcie = dev_id ;
74
+ struct dw_pcie * pci = pcie -> pci ;
75
+ u32 val , cfg ;
76
+
77
+ val = ls_lut_readl (pcie , PEX_PF0_PME_MES_DR );
78
+ ls_lut_writel (pcie , PEX_PF0_PME_MES_DR , val );
79
+
80
+ if (!val )
81
+ return IRQ_NONE ;
82
+
83
+ if (val & PEX_PF0_PME_MES_DR_LUD ) {
84
+ cfg = ls_lut_readl (pcie , PEX_PF0_CONFIG );
85
+ cfg |= PEX_PF0_CFG_READY ;
86
+ ls_lut_writel (pcie , PEX_PF0_CONFIG , cfg );
87
+ dw_pcie_ep_linkup (& pci -> ep );
88
+
89
+ dev_dbg (pci -> dev , "Link up\n" );
90
+ } else if (val & PEX_PF0_PME_MES_DR_LDD ) {
91
+ dev_dbg (pci -> dev , "Link down\n" );
92
+ } else if (val & PEX_PF0_PME_MES_DR_HRD ) {
93
+ dev_dbg (pci -> dev , "Hot reset\n" );
94
+ }
95
+
96
+ return IRQ_HANDLED ;
97
+ }
98
+
99
+ static int ls_pcie_ep_interrupt_init (struct ls_pcie_ep * pcie ,
100
+ struct platform_device * pdev )
101
+ {
102
+ u32 val ;
103
+ int ret ;
104
+
105
+ pcie -> irq = platform_get_irq_byname (pdev , "pme" );
106
+ if (pcie -> irq < 0 )
107
+ return pcie -> irq ;
108
+
109
+ ret = devm_request_irq (& pdev -> dev , pcie -> irq , ls_pcie_ep_event_handler ,
110
+ IRQF_SHARED , pdev -> name , pcie );
111
+ if (ret ) {
112
+ dev_err (& pdev -> dev , "Can't register PCIe IRQ\n" );
113
+ return ret ;
114
+ }
115
+
116
+ /* Enable interrupts */
117
+ val = ls_lut_readl (pcie , PEX_PF0_PME_MES_IER );
118
+ val |= PEX_PF0_PME_MES_IER_LDDIE | PEX_PF0_PME_MES_IER_HRDIE |
119
+ PEX_PF0_PME_MES_IER_LUDIE ;
120
+ ls_lut_writel (pcie , PEX_PF0_PME_MES_IER , val );
121
+
122
+ return 0 ;
123
+ }
124
+
35
125
static const struct pci_epc_features *
36
126
ls_pcie_ep_get_features (struct dw_pcie_ep * ep )
37
127
{
@@ -125,6 +215,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
125
215
struct ls_pcie_ep * pcie ;
126
216
struct pci_epc_features * ls_epc ;
127
217
struct resource * dbi_base ;
218
+ int ret ;
128
219
129
220
pcie = devm_kzalloc (dev , sizeof (* pcie ), GFP_KERNEL );
130
221
if (!pcie )
@@ -144,6 +235,7 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
144
235
pci -> ops = pcie -> drvdata -> dw_pcie_ops ;
145
236
146
237
ls_epc -> bar_fixed_64bit = (1 << BAR_2 ) | (1 << BAR_4 );
238
+ ls_epc -> linkup_notifier = true;
147
239
148
240
pcie -> pci = pci ;
149
241
pcie -> ls_epc = ls_epc ;
@@ -155,9 +247,15 @@ static int __init ls_pcie_ep_probe(struct platform_device *pdev)
155
247
156
248
pci -> ep .ops = & ls_pcie_ep_ops ;
157
249
250
+ pcie -> big_endian = of_property_read_bool (dev -> of_node , "big-endian" );
251
+
158
252
platform_set_drvdata (pdev , pcie );
159
253
160
- return dw_pcie_ep_init (& pci -> ep );
254
+ ret = dw_pcie_ep_init (& pci -> ep );
255
+ if (ret )
256
+ return ret ;
257
+
258
+ return ls_pcie_ep_interrupt_init (pcie , pdev );
161
259
}
162
260
163
261
static struct platform_driver ls_pcie_ep_driver = {
0 commit comments