1 // SPDX-License-Identifier: GPL-2.0
3 * pcie_uniphier.c - Socionext UniPhier PCIe driver
4 * Copyright 2019-2021 Socionext, Inc.
9 #include <dm/device_compat.h>
10 #include <generic-phy.h>
11 #include <linux/bitfield.h>
12 #include <linux/bitops.h>
13 #include <linux/compat.h>
14 #include <linux/delay.h>
19 DECLARE_GLOBAL_DATA_PTR;
22 #define PCIE_LINK_STATUS_REG 0x0080
23 #define PCIE_LINK_STATUS_WIDTH_MASK GENMASK(25, 20)
24 #define PCIE_LINK_STATUS_SPEED_MASK GENMASK(19, 16)
26 #define PCIE_MISC_CONTROL_1_OFF 0x08BC
27 #define PCIE_DBI_RO_WR_EN BIT(0)
29 /* DBI iATU registers */
30 #define PCIE_ATU_VIEWPORT 0x0900
31 #define PCIE_ATU_REGION_INBOUND BIT(31)
32 #define PCIE_ATU_REGION_OUTBOUND 0
33 #define PCIE_ATU_REGION_INDEX_MASK GENMASK(3, 0)
35 #define PCIE_ATU_CR1 0x0904
36 #define PCIE_ATU_TYPE_MEM 0
37 #define PCIE_ATU_TYPE_IO 2
38 #define PCIE_ATU_TYPE_CFG0 4
39 #define PCIE_ATU_TYPE_CFG1 5
41 #define PCIE_ATU_CR2 0x0908
42 #define PCIE_ATU_ENABLE BIT(31)
43 #define PCIE_ATU_MATCH_MODE BIT(30)
44 #define PCIE_ATU_BAR_NUM_MASK GENMASK(10, 8)
46 #define PCIE_ATU_LOWER_BASE 0x090C
47 #define PCIE_ATU_UPPER_BASE 0x0910
48 #define PCIE_ATU_LIMIT 0x0914
49 #define PCIE_ATU_LOWER_TARGET 0x0918
50 #define PCIE_ATU_BUS(x) FIELD_PREP(GENMASK(31, 24), x)
51 #define PCIE_ATU_DEV(x) FIELD_PREP(GENMASK(23, 19), x)
52 #define PCIE_ATU_FUNC(x) FIELD_PREP(GENMASK(18, 16), x)
53 #define PCIE_ATU_UPPER_TARGET 0x091C
55 /* Link Glue registers */
56 #define PCL_PINCTRL0 0x002c
57 #define PCL_PERST_PLDN_REGEN BIT(12)
58 #define PCL_PERST_NOE_REGEN BIT(11)
59 #define PCL_PERST_OUT_REGEN BIT(8)
60 #define PCL_PERST_PLDN_REGVAL BIT(4)
61 #define PCL_PERST_NOE_REGVAL BIT(3)
62 #define PCL_PERST_OUT_REGVAL BIT(0)
64 #define PCL_MODE 0x8000
65 #define PCL_MODE_REGEN BIT(8)
66 #define PCL_MODE_REGVAL BIT(0)
68 #define PCL_APP_READY_CTRL 0x8008
69 #define PCL_APP_LTSSM_ENABLE BIT(0)
71 #define PCL_APP_PM0 0x8078
72 #define PCL_SYS_AUX_PWR_DET BIT(8)
74 #define PCL_STATUS_LINK 0x8140
75 #define PCL_RDLH_LINK_UP BIT(1)
76 #define PCL_XMLH_LINK_UP BIT(0)
78 #define LINK_UP_TIMEOUT_MS 100
80 struct uniphier_pcie_priv {
85 struct fdt_resource link_res;
86 struct fdt_resource dbi_res;
87 struct fdt_resource cfg_res;
94 struct pci_region mem;
97 static int pcie_dw_get_link_speed(struct uniphier_pcie_priv *priv)
99 u32 val = readl(priv->dbi_base + PCIE_LINK_STATUS_REG);
101 return FIELD_GET(PCIE_LINK_STATUS_SPEED_MASK, val);
104 static int pcie_dw_get_link_width(struct uniphier_pcie_priv *priv)
106 u32 val = readl(priv->dbi_base + PCIE_LINK_STATUS_REG);
108 return FIELD_GET(PCIE_LINK_STATUS_WIDTH_MASK, val);
111 static void pcie_dw_prog_outbound_atu(struct uniphier_pcie_priv *priv,
112 int index, int type, u64 cpu_addr,
113 u64 pci_addr, u32 size)
115 writel(PCIE_ATU_REGION_OUTBOUND
116 | FIELD_PREP(PCIE_ATU_REGION_INDEX_MASK, index),
117 priv->dbi_base + PCIE_ATU_VIEWPORT);
118 writel(lower_32_bits(cpu_addr),
119 priv->dbi_base + PCIE_ATU_LOWER_BASE);
120 writel(upper_32_bits(cpu_addr),
121 priv->dbi_base + PCIE_ATU_UPPER_BASE);
122 writel(lower_32_bits(cpu_addr + size - 1),
123 priv->dbi_base + PCIE_ATU_LIMIT);
124 writel(lower_32_bits(pci_addr),
125 priv->dbi_base + PCIE_ATU_LOWER_TARGET);
126 writel(upper_32_bits(pci_addr),
127 priv->dbi_base + PCIE_ATU_UPPER_TARGET);
129 writel(type, priv->dbi_base + PCIE_ATU_CR1);
130 writel(PCIE_ATU_ENABLE, priv->dbi_base + PCIE_ATU_CR2);
133 static int uniphier_pcie_addr_valid(pci_dev_t bdf, int first_busno)
135 /* accept only device {0,1} on first bus */
136 if ((PCI_BUS(bdf) != first_busno) || (PCI_DEV(bdf) > 1))
142 static int uniphier_pcie_conf_address(const struct udevice *dev, pci_dev_t bdf,
143 uint offset, void **paddr)
145 struct uniphier_pcie_priv *priv = dev_get_priv(dev);
147 int seq = dev_seq(dev);
150 ret = uniphier_pcie_addr_valid(bdf, seq);
154 if ((PCI_BUS(bdf) == seq) && !PCI_DEV(bdf)) {
155 *paddr = (void *)(priv->dbi_base + offset);
159 busdev = PCIE_ATU_BUS(PCI_BUS(bdf) - seq)
160 | PCIE_ATU_DEV(PCI_DEV(bdf))
161 | PCIE_ATU_FUNC(PCI_FUNC(bdf));
163 pcie_dw_prog_outbound_atu(priv, 0,
164 PCIE_ATU_TYPE_CFG0, (u64)priv->cfg_base,
165 busdev, priv->cfg_size);
166 *paddr = (void *)(priv->cfg_base + offset);
171 static int uniphier_pcie_read_config(const struct udevice *dev, pci_dev_t bdf,
172 uint offset, ulong *valp,
173 enum pci_size_t size)
175 return pci_generic_mmap_read_config(dev, uniphier_pcie_conf_address,
176 bdf, offset, valp, size);
179 static int uniphier_pcie_write_config(struct udevice *dev, pci_dev_t bdf,
180 uint offset, ulong val,
181 enum pci_size_t size)
183 return pci_generic_mmap_write_config(dev, uniphier_pcie_conf_address,
184 bdf, offset, val, size);
187 static void uniphier_pcie_ltssm_enable(struct uniphier_pcie_priv *priv,
192 val = readl(priv->base + PCL_APP_READY_CTRL);
194 val |= PCL_APP_LTSSM_ENABLE;
196 val &= ~PCL_APP_LTSSM_ENABLE;
197 writel(val, priv->base + PCL_APP_READY_CTRL);
200 static int uniphier_pcie_link_up(struct uniphier_pcie_priv *priv)
204 val = readl(priv->base + PCL_STATUS_LINK);
205 mask = PCL_RDLH_LINK_UP | PCL_XMLH_LINK_UP;
207 return (val & mask) == mask;
210 static int uniphier_pcie_wait_link(struct uniphier_pcie_priv *priv)
212 unsigned long timeout;
214 timeout = get_timer(0) + LINK_UP_TIMEOUT_MS;
216 while (get_timer(0) < timeout) {
217 if (uniphier_pcie_link_up(priv))
224 static int uniphier_pcie_establish_link(struct uniphier_pcie_priv *priv)
226 if (uniphier_pcie_link_up(priv))
229 uniphier_pcie_ltssm_enable(priv, true);
231 return uniphier_pcie_wait_link(priv);
234 static void uniphier_pcie_init_rc(struct uniphier_pcie_priv *priv)
239 val = readl(priv->base + PCL_MODE);
240 val |= PCL_MODE_REGEN;
241 val &= ~PCL_MODE_REGVAL;
242 writel(val, priv->base + PCL_MODE);
244 /* use auxiliary power detection */
245 val = readl(priv->base + PCL_APP_PM0);
246 val |= PCL_SYS_AUX_PWR_DET;
247 writel(val, priv->base + PCL_APP_PM0);
250 val = readl(priv->base + PCL_PINCTRL0);
251 val &= ~(PCL_PERST_NOE_REGVAL | PCL_PERST_OUT_REGVAL
252 | PCL_PERST_PLDN_REGVAL);
253 val |= PCL_PERST_NOE_REGEN | PCL_PERST_OUT_REGEN
254 | PCL_PERST_PLDN_REGEN;
255 writel(val, priv->base + PCL_PINCTRL0);
257 uniphier_pcie_ltssm_enable(priv, false);
261 /* deassert PERST# */
262 val = readl(priv->base + PCL_PINCTRL0);
263 val |= PCL_PERST_OUT_REGVAL | PCL_PERST_OUT_REGEN;
264 writel(val, priv->base + PCL_PINCTRL0);
267 static void uniphier_pcie_setup_rc(struct uniphier_pcie_priv *priv,
268 struct pci_controller *hose)
270 /* Store the IO and MEM windows settings for future use by the ATU */
271 priv->io.phys_start = hose->regions[0].phys_start; /* IO base */
272 priv->io.bus_start = hose->regions[0].bus_start; /* IO_bus_addr */
273 priv->io.size = hose->regions[0].size; /* IO size */
274 priv->mem.phys_start = hose->regions[1].phys_start; /* MEM base */
275 priv->mem.bus_start = hose->regions[1].bus_start; /* MEM_bus_addr */
276 priv->mem.size = hose->regions[1].size; /* MEM size */
279 pcie_dw_prog_outbound_atu(priv, 0,
280 PCIE_ATU_TYPE_IO, priv->io.phys_start,
281 priv->io.bus_start, priv->io.size);
284 pcie_dw_prog_outbound_atu(priv, 1,
285 PCIE_ATU_TYPE_MEM, priv->mem.phys_start,
286 priv->mem.bus_start, priv->mem.size);
289 static int uniphier_pcie_probe(struct udevice *dev)
291 struct uniphier_pcie_priv *priv = dev_get_priv(dev);
292 struct udevice *ctlr = pci_get_controller(dev);
293 struct pci_controller *hose = dev_get_uclass_priv(ctlr);
296 priv->base = map_physmem(priv->link_res.start,
297 fdt_resource_size(&priv->link_res),
299 priv->dbi_base = map_physmem(priv->dbi_res.start,
300 fdt_resource_size(&priv->dbi_res),
302 priv->cfg_size = fdt_resource_size(&priv->cfg_res);
303 priv->cfg_base = map_physmem(priv->cfg_res.start,
304 priv->cfg_size, MAP_NOCACHE);
306 ret = clk_enable(&priv->clk);
308 dev_err(dev, "Failed to enable clk: %d\n", ret);
311 ret = reset_deassert(&priv->rst);
313 dev_err(dev, "Failed to deassert reset: %d\n", ret);
314 goto out_clk_release;
317 ret = generic_phy_init(&priv->phy);
319 dev_err(dev, "Failed to initialize phy: %d\n", ret);
320 goto out_reset_release;
323 ret = generic_phy_power_on(&priv->phy);
325 dev_err(dev, "Failed to power on phy: %d\n", ret);
329 uniphier_pcie_init_rc(priv);
331 /* set DBI to read only */
332 writel(0, priv->dbi_base + PCIE_MISC_CONTROL_1_OFF);
334 uniphier_pcie_setup_rc(priv, hose);
336 if (uniphier_pcie_establish_link(priv)) {
337 printf("PCIE-%d: Link down\n", dev_seq(dev));
339 printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n",
340 dev_seq(dev), pcie_dw_get_link_speed(priv),
341 pcie_dw_get_link_width(priv), hose->first_busno);
347 generic_phy_exit(&priv->phy);
349 reset_release_all(&priv->rst, 1);
351 clk_release_all(&priv->clk, 1);
356 static int uniphier_pcie_of_to_plat(struct udevice *dev)
358 struct uniphier_pcie_priv *priv = dev_get_priv(dev);
359 const void *fdt = gd->fdt_blob;
360 int node = dev_of_offset(dev);
363 ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
364 "link", &priv->link_res);
366 dev_err(dev, "Failed to get link regs: %d\n", ret);
370 ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
371 "dbi", &priv->dbi_res);
373 dev_err(dev, "Failed to get dbi regs: %d\n", ret);
377 ret = fdt_get_named_resource(fdt, node, "reg", "reg-names",
378 "config", &priv->cfg_res);
380 dev_err(dev, "Failed to get config regs: %d\n", ret);
384 ret = clk_get_by_index(dev, 0, &priv->clk);
386 dev_err(dev, "Failed to get clocks property: %d\n", ret);
390 ret = reset_get_by_index(dev, 0, &priv->rst);
392 dev_err(dev, "Failed to get resets property: %d\n", ret);
396 ret = generic_phy_get_by_index(dev, 0, &priv->phy);
398 dev_err(dev, "Failed to get phy property: %d\n", ret);
405 static const struct dm_pci_ops uniphier_pcie_ops = {
406 .read_config = uniphier_pcie_read_config,
407 .write_config = uniphier_pcie_write_config,
410 static const struct udevice_id uniphier_pcie_ids[] = {
411 { .compatible = "socionext,uniphier-pcie", },
415 U_BOOT_DRIVER(pcie_uniphier) = {
416 .name = "uniphier-pcie",
418 .of_match = uniphier_pcie_ids,
419 .probe = uniphier_pcie_probe,
420 .ops = &uniphier_pcie_ops,
421 .of_to_plat = uniphier_pcie_of_to_plat,
422 .priv_auto = sizeof(struct uniphier_pcie_priv),