10
10
#include <linux/clk.h>
11
11
#include <linux/delay.h>
12
12
#include <linux/init.h>
13
+ #include <linux/iopoll.h>
13
14
#include <linux/of_device.h>
14
15
#include <linux/pci.h>
15
16
#include <linux/phy/phy.h>
31
32
#define PCL_RSTCTRL2 0x0024
32
33
#define PCL_RSTCTRL_PHY_RESET BIT(0)
33
34
35
+ #define PCL_PINCTRL0 0x002c
36
+ #define PCL_PERST_PLDN_REGEN BIT(12)
37
+ #define PCL_PERST_NOE_REGEN BIT(11)
38
+ #define PCL_PERST_OUT_REGEN BIT(8)
39
+ #define PCL_PERST_PLDN_REGVAL BIT(4)
40
+ #define PCL_PERST_NOE_REGVAL BIT(3)
41
+ #define PCL_PERST_OUT_REGVAL BIT(0)
42
+
43
+ #define PCL_PIPEMON 0x0044
44
+ #define PCL_PCLK_ALIVE BIT(15)
45
+
34
46
#define PCL_MODE 0x8000
35
47
#define PCL_MODE_REGEN BIT(8)
36
48
#define PCL_MODE_REGVAL BIT(0)
51
63
#define PCL_APP_INTX 0x8074
52
64
#define PCL_APP_INTX_SYS_INT BIT(0)
53
65
66
+ #define PCL_APP_PM0 0x8078
67
+ #define PCL_SYS_AUX_PWR_DET BIT(8)
68
+
54
69
/* assertion time of INTx in usec */
55
70
#define PCL_INTX_WIDTH_USEC 30
56
71
@@ -60,7 +75,14 @@ struct uniphier_pcie_ep_priv {
60
75
struct clk * clk , * clk_gio ;
61
76
struct reset_control * rst , * rst_gio ;
62
77
struct phy * phy ;
63
- const struct pci_epc_features * features ;
78
+ const struct uniphier_pcie_ep_soc_data * data ;
79
+ };
80
+
81
+ struct uniphier_pcie_ep_soc_data {
82
+ bool has_gio ;
83
+ void (* init )(struct uniphier_pcie_ep_priv * priv );
84
+ int (* wait )(struct uniphier_pcie_ep_priv * priv );
85
+ const struct pci_epc_features features ;
64
86
};
65
87
66
88
#define to_uniphier_pcie (x ) dev_get_drvdata((x)->dev)
@@ -91,7 +113,7 @@ static void uniphier_pcie_phy_reset(struct uniphier_pcie_ep_priv *priv,
91
113
writel (val , priv -> base + PCL_RSTCTRL2 );
92
114
}
93
115
94
- static void uniphier_pcie_init_ep (struct uniphier_pcie_ep_priv * priv )
116
+ static void uniphier_pcie_pro5_init_ep (struct uniphier_pcie_ep_priv * priv )
95
117
{
96
118
u32 val ;
97
119
@@ -116,6 +138,55 @@ static void uniphier_pcie_init_ep(struct uniphier_pcie_ep_priv *priv)
116
138
msleep (100 );
117
139
}
118
140
141
+ static void uniphier_pcie_nx1_init_ep (struct uniphier_pcie_ep_priv * priv )
142
+ {
143
+ u32 val ;
144
+
145
+ /* set EP mode */
146
+ val = readl (priv -> base + PCL_MODE );
147
+ val |= PCL_MODE_REGEN | PCL_MODE_REGVAL ;
148
+ writel (val , priv -> base + PCL_MODE );
149
+
150
+ /* use auxiliary power detection */
151
+ val = readl (priv -> base + PCL_APP_PM0 );
152
+ val |= PCL_SYS_AUX_PWR_DET ;
153
+ writel (val , priv -> base + PCL_APP_PM0 );
154
+
155
+ /* assert PERST# */
156
+ val = readl (priv -> base + PCL_PINCTRL0 );
157
+ val &= ~(PCL_PERST_NOE_REGVAL | PCL_PERST_OUT_REGVAL
158
+ | PCL_PERST_PLDN_REGVAL );
159
+ val |= PCL_PERST_NOE_REGEN | PCL_PERST_OUT_REGEN
160
+ | PCL_PERST_PLDN_REGEN ;
161
+ writel (val , priv -> base + PCL_PINCTRL0 );
162
+
163
+ uniphier_pcie_ltssm_enable (priv , false);
164
+
165
+ usleep_range (100000 , 200000 );
166
+
167
+ /* deassert PERST# */
168
+ val = readl (priv -> base + PCL_PINCTRL0 );
169
+ val |= PCL_PERST_OUT_REGVAL | PCL_PERST_OUT_REGEN ;
170
+ writel (val , priv -> base + PCL_PINCTRL0 );
171
+ }
172
+
173
+ static int uniphier_pcie_nx1_wait_ep (struct uniphier_pcie_ep_priv * priv )
174
+ {
175
+ u32 status ;
176
+ int ret ;
177
+
178
+ /* wait PIPE clock */
179
+ ret = readl_poll_timeout (priv -> base + PCL_PIPEMON , status ,
180
+ status & PCL_PCLK_ALIVE , 100000 , 1000000 );
181
+ if (ret ) {
182
+ dev_err (priv -> pci .dev ,
183
+ "Failed to initialize controller in EP mode\n" );
184
+ return ret ;
185
+ }
186
+
187
+ return 0 ;
188
+ }
189
+
119
190
static int uniphier_pcie_start_link (struct dw_pcie * pci )
120
191
{
121
192
struct uniphier_pcie_ep_priv * priv = to_uniphier_pcie (pci );
@@ -209,7 +280,7 @@ uniphier_pcie_get_features(struct dw_pcie_ep *ep)
209
280
struct dw_pcie * pci = to_dw_pcie_from_ep (ep );
210
281
struct uniphier_pcie_ep_priv * priv = to_uniphier_pcie (pci );
211
282
212
- return priv -> features ;
283
+ return & priv -> data -> features ;
213
284
}
214
285
215
286
static const struct dw_pcie_ep_ops uniphier_pcie_ep_ops = {
@@ -238,7 +309,8 @@ static int uniphier_pcie_ep_enable(struct uniphier_pcie_ep_priv *priv)
238
309
if (ret )
239
310
goto out_rst_assert ;
240
311
241
- uniphier_pcie_init_ep (priv );
312
+ if (priv -> data -> init )
313
+ priv -> data -> init (priv );
242
314
243
315
uniphier_pcie_phy_reset (priv , true);
244
316
@@ -248,8 +320,16 @@ static int uniphier_pcie_ep_enable(struct uniphier_pcie_ep_priv *priv)
248
320
249
321
uniphier_pcie_phy_reset (priv , false);
250
322
323
+ if (priv -> data -> wait ) {
324
+ ret = priv -> data -> wait (priv );
325
+ if (ret )
326
+ goto out_phy_exit ;
327
+ }
328
+
251
329
return 0 ;
252
330
331
+ out_phy_exit :
332
+ phy_exit (priv -> phy );
253
333
out_rst_gio_assert :
254
334
reset_control_assert (priv -> rst_gio );
255
335
out_rst_assert :
@@ -277,8 +357,8 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)
277
357
if (!priv )
278
358
return - ENOMEM ;
279
359
280
- priv -> features = of_device_get_match_data (dev );
281
- if (WARN_ON (!priv -> features ))
360
+ priv -> data = of_device_get_match_data (dev );
361
+ if (WARN_ON (!priv -> data ))
282
362
return - EINVAL ;
283
363
284
364
priv -> pci .dev = dev ;
@@ -288,13 +368,15 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)
288
368
if (IS_ERR (priv -> base ))
289
369
return PTR_ERR (priv -> base );
290
370
291
- priv -> clk_gio = devm_clk_get (dev , "gio" );
292
- if (IS_ERR (priv -> clk_gio ))
293
- return PTR_ERR (priv -> clk_gio );
371
+ if (priv -> data -> has_gio ) {
372
+ priv -> clk_gio = devm_clk_get (dev , "gio" );
373
+ if (IS_ERR (priv -> clk_gio ))
374
+ return PTR_ERR (priv -> clk_gio );
294
375
295
- priv -> rst_gio = devm_reset_control_get_shared (dev , "gio" );
296
- if (IS_ERR (priv -> rst_gio ))
297
- return PTR_ERR (priv -> rst_gio );
376
+ priv -> rst_gio = devm_reset_control_get_shared (dev , "gio" );
377
+ if (IS_ERR (priv -> rst_gio ))
378
+ return PTR_ERR (priv -> rst_gio );
379
+ }
298
380
299
381
priv -> clk = devm_clk_get (dev , "link" );
300
382
if (IS_ERR (priv -> clk ))
@@ -321,20 +403,42 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)
321
403
return dw_pcie_ep_init (& priv -> pci .ep );
322
404
}
323
405
324
- static const struct pci_epc_features uniphier_pro5_data = {
325
- .linkup_notifier = false,
326
- .msi_capable = true,
327
- .msix_capable = false,
328
- .align = 1 << 16 ,
329
- .bar_fixed_64bit = BIT (BAR_0 ) | BIT (BAR_2 ) | BIT (BAR_4 ),
330
- .reserved_bar = BIT (BAR_4 ),
406
+ static const struct uniphier_pcie_ep_soc_data uniphier_pro5_data = {
407
+ .has_gio = true,
408
+ .init = uniphier_pcie_pro5_init_ep ,
409
+ .wait = NULL ,
410
+ .features = {
411
+ .linkup_notifier = false,
412
+ .msi_capable = true,
413
+ .msix_capable = false,
414
+ .align = 1 << 16 ,
415
+ .bar_fixed_64bit = BIT (BAR_0 ) | BIT (BAR_2 ) | BIT (BAR_4 ),
416
+ .reserved_bar = BIT (BAR_4 ),
417
+ },
418
+ };
419
+
420
+ static const struct uniphier_pcie_ep_soc_data uniphier_nx1_data = {
421
+ .has_gio = false,
422
+ .init = uniphier_pcie_nx1_init_ep ,
423
+ .wait = uniphier_pcie_nx1_wait_ep ,
424
+ .features = {
425
+ .linkup_notifier = false,
426
+ .msi_capable = true,
427
+ .msix_capable = false,
428
+ .align = 1 << 12 ,
429
+ .bar_fixed_64bit = BIT (BAR_0 ) | BIT (BAR_2 ) | BIT (BAR_4 ),
430
+ },
331
431
};
332
432
333
433
static const struct of_device_id uniphier_pcie_ep_match [] = {
334
434
{
335
435
.compatible = "socionext,uniphier-pro5-pcie-ep" ,
336
436
.data = & uniphier_pro5_data ,
337
437
},
438
+ {
439
+ .compatible = "socionext,uniphier-nx1-pcie-ep" ,
440
+ .data = & uniphier_nx1_data ,
441
+ },
338
442
{ /* sentinel */ },
339
443
};
340
444
0 commit comments