|
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 |
|
@@ -123,6 +138,55 @@ static void uniphier_pcie_pro5_init_ep(struct uniphier_pcie_ep_priv *priv) |
123 | 138 | msleep(100); |
124 | 139 | } |
125 | 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 | + |
126 | 190 | static int uniphier_pcie_start_link(struct dw_pcie *pci) |
127 | 191 | { |
128 | 192 | struct uniphier_pcie_ep_priv *priv = to_uniphier_pcie(pci); |
@@ -353,11 +417,28 @@ static const struct uniphier_pcie_ep_soc_data uniphier_pro5_data = { |
353 | 417 | }, |
354 | 418 | }; |
355 | 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 | + }, |
| 431 | +}; |
| 432 | + |
356 | 433 | static const struct of_device_id uniphier_pcie_ep_match[] = { |
357 | 434 | { |
358 | 435 | .compatible = "socionext,uniphier-pro5-pcie-ep", |
359 | 436 | .data = &uniphier_pro5_data, |
360 | 437 | }, |
| 438 | + { |
| 439 | + .compatible = "socionext,uniphier-nx1-pcie-ep", |
| 440 | + .data = &uniphier_nx1_data, |
| 441 | + }, |
361 | 442 | { /* sentinel */ }, |
362 | 443 | }; |
363 | 444 |
|
|
0 commit comments