1010#include <linux/clk.h>
1111#include <linux/delay.h>
1212#include <linux/init.h>
13+ #include <linux/iopoll.h>
1314#include <linux/of_device.h>
1415#include <linux/pci.h>
1516#include <linux/phy/phy.h>
3132#define PCL_RSTCTRL2 0x0024
3233#define PCL_RSTCTRL_PHY_RESET BIT(0)
3334
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+
3446#define PCL_MODE 0x8000
3547#define PCL_MODE_REGEN BIT(8)
3648#define PCL_MODE_REGVAL BIT(0)
5163#define PCL_APP_INTX 0x8074
5264#define PCL_APP_INTX_SYS_INT BIT(0)
5365
66+ #define PCL_APP_PM0 0x8078
67+ #define PCL_SYS_AUX_PWR_DET BIT(8)
68+
5469/* assertion time of INTx in usec */
5570#define PCL_INTX_WIDTH_USEC 30
5671
@@ -60,7 +75,14 @@ struct uniphier_pcie_ep_priv {
6075 struct clk * clk , * clk_gio ;
6176 struct reset_control * rst , * rst_gio ;
6277 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 ;
6486};
6587
6688#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,
91113 writel (val , priv -> base + PCL_RSTCTRL2 );
92114}
93115
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 )
95117{
96118 u32 val ;
97119
@@ -116,6 +138,55 @@ static void uniphier_pcie_init_ep(struct uniphier_pcie_ep_priv *priv)
116138 msleep (100 );
117139}
118140
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+
119190static int uniphier_pcie_start_link (struct dw_pcie * pci )
120191{
121192 struct uniphier_pcie_ep_priv * priv = to_uniphier_pcie (pci );
@@ -209,7 +280,7 @@ uniphier_pcie_get_features(struct dw_pcie_ep *ep)
209280 struct dw_pcie * pci = to_dw_pcie_from_ep (ep );
210281 struct uniphier_pcie_ep_priv * priv = to_uniphier_pcie (pci );
211282
212- return priv -> features ;
283+ return & priv -> data -> features ;
213284}
214285
215286static 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)
238309 if (ret )
239310 goto out_rst_assert ;
240311
241- uniphier_pcie_init_ep (priv );
312+ if (priv -> data -> init )
313+ priv -> data -> init (priv );
242314
243315 uniphier_pcie_phy_reset (priv , true);
244316
@@ -248,8 +320,16 @@ static int uniphier_pcie_ep_enable(struct uniphier_pcie_ep_priv *priv)
248320
249321 uniphier_pcie_phy_reset (priv , false);
250322
323+ if (priv -> data -> wait ) {
324+ ret = priv -> data -> wait (priv );
325+ if (ret )
326+ goto out_phy_exit ;
327+ }
328+
251329 return 0 ;
252330
331+ out_phy_exit :
332+ phy_exit (priv -> phy );
253333out_rst_gio_assert :
254334 reset_control_assert (priv -> rst_gio );
255335out_rst_assert :
@@ -277,8 +357,8 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)
277357 if (!priv )
278358 return - ENOMEM ;
279359
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 ))
282362 return - EINVAL ;
283363
284364 priv -> pci .dev = dev ;
@@ -288,13 +368,15 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)
288368 if (IS_ERR (priv -> base ))
289369 return PTR_ERR (priv -> base );
290370
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 );
294375
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+ }
298380
299381 priv -> clk = devm_clk_get (dev , "link" );
300382 if (IS_ERR (priv -> clk ))
@@ -321,20 +403,42 @@ static int uniphier_pcie_ep_probe(struct platform_device *pdev)
321403 return dw_pcie_ep_init (& priv -> pci .ep );
322404}
323405
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+ },
331431};
332432
333433static const struct of_device_id uniphier_pcie_ep_match [] = {
334434 {
335435 .compatible = "socionext,uniphier-pro5-pcie-ep" ,
336436 .data = & uniphier_pro5_data ,
337437 },
438+ {
439+ .compatible = "socionext,uniphier-nx1-pcie-ep" ,
440+ .data = & uniphier_nx1_data ,
441+ },
338442 { /* sentinel */ },
339443};
340444
0 commit comments