blob: 67039d2a29f8197c460c5f002abbbe524185aa65 [file] [log] [blame]
Jagan Teki02262472020-05-09 22:26:21 +05301// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Rockchip AXI PCIe host controller driver
4 *
5 * Copyright (c) 2016 Rockchip, Inc.
6 * Copyright (c) 2020 Amarula Solutions(India)
7 * Copyright (c) 2020 Jagan Teki <jagan@amarulasolutions.com>
8 * Copyright (c) 2019 Patrick Wildt <patrick@blueri.se>
9 * Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org>
10 *
11 * Bits taken from Linux Rockchip PCIe host controller.
12 */
13
14#include <common.h>
15#include <clk.h>
16#include <dm.h>
Simon Glass3ba929a2020-10-30 21:38:53 -060017#include <asm/global_data.h>
Jagan Teki02262472020-05-09 22:26:21 +053018#include <dm/device_compat.h>
Jagan Teki0400f5e2020-07-09 23:41:03 +053019#include <generic-phy.h>
Jagan Teki02262472020-05-09 22:26:21 +053020#include <pci.h>
21#include <power-domain.h>
22#include <power/regulator.h>
23#include <reset.h>
24#include <syscon.h>
25#include <asm/io.h>
26#include <asm-generic/gpio.h>
27#include <asm/arch-rockchip/clock.h>
28#include <linux/iopoll.h>
29
Jagan Teki02262472020-05-09 22:26:21 +053030DECLARE_GLOBAL_DATA_PTR;
31
Jagan Teki0400f5e2020-07-09 23:41:03 +053032#define HIWORD_UPDATE(mask, val) (((mask) << 16) | (val))
33#define HIWORD_UPDATE_BIT(val) HIWORD_UPDATE(val, val)
34
35#define ENCODE_LANES(x) ((((x) >> 1) & 3) << 4)
36#define PCIE_CLIENT_BASE 0x0
37#define PCIE_CLIENT_CONFIG (PCIE_CLIENT_BASE + 0x00)
38#define PCIE_CLIENT_CONF_ENABLE HIWORD_UPDATE_BIT(0x0001)
39#define PCIE_CLIENT_LINK_TRAIN_ENABLE HIWORD_UPDATE_BIT(0x0002)
40#define PCIE_CLIENT_MODE_RC HIWORD_UPDATE_BIT(0x0040)
41#define PCIE_CLIENT_GEN_SEL_1 HIWORD_UPDATE(0x0080, 0)
42#define PCIE_CLIENT_BASIC_STATUS1 0x0048
43#define PCIE_CLIENT_LINK_STATUS_UP GENMASK(21, 20)
44#define PCIE_CLIENT_LINK_STATUS_MASK GENMASK(21, 20)
45#define PCIE_LINK_UP(x) \
46 (((x) & PCIE_CLIENT_LINK_STATUS_MASK) == PCIE_CLIENT_LINK_STATUS_UP)
47#define PCIE_RC_NORMAL_BASE 0x800000
48#define PCIE_LM_BASE 0x900000
49#define PCIE_LM_VENDOR_ID (PCIE_LM_BASE + 0x44)
50#define PCIE_LM_VENDOR_ROCKCHIP 0x1d87
51#define PCIE_LM_RCBAR (PCIE_LM_BASE + 0x300)
52#define PCIE_LM_RCBARPIE BIT(19)
53#define PCIE_LM_RCBARPIS BIT(20)
54#define PCIE_RC_BASE 0xa00000
55#define PCIE_RC_CONFIG_DCR (PCIE_RC_BASE + 0x0c4)
56#define PCIE_RC_CONFIG_DCR_CSPL_SHIFT 18
57#define PCIE_RC_CONFIG_DCR_CPLS_SHIFT 26
58#define PCIE_RC_PCIE_LCAP (PCIE_RC_BASE + 0x0cc)
59#define PCIE_RC_PCIE_LCAP_APMS_L0S BIT(10)
60#define PCIE_ATR_BASE 0xc00000
61#define PCIE_ATR_OB_ADDR0(i) (PCIE_ATR_BASE + 0x000 + (i) * 0x20)
62#define PCIE_ATR_OB_ADDR1(i) (PCIE_ATR_BASE + 0x004 + (i) * 0x20)
63#define PCIE_ATR_OB_DESC0(i) (PCIE_ATR_BASE + 0x008 + (i) * 0x20)
64#define PCIE_ATR_OB_DESC1(i) (PCIE_ATR_BASE + 0x00c + (i) * 0x20)
65#define PCIE_ATR_IB_ADDR0(i) (PCIE_ATR_BASE + 0x800 + (i) * 0x8)
66#define PCIE_ATR_IB_ADDR1(i) (PCIE_ATR_BASE + 0x804 + (i) * 0x8)
67#define PCIE_ATR_HDR_MEM 0x2
68#define PCIE_ATR_HDR_IO 0x6
69#define PCIE_ATR_HDR_CFG_TYPE0 0xa
70#define PCIE_ATR_HDR_CFG_TYPE1 0xb
71#define PCIE_ATR_HDR_RID BIT(23)
72
73#define PCIE_ATR_OB_REGION0_SIZE (32 * 1024 * 1024)
74#define PCIE_ATR_OB_REGION_SIZE (1 * 1024 * 1024)
75
76struct rockchip_pcie {
77 fdt_addr_t axi_base;
78 fdt_addr_t apb_base;
79 int first_busno;
80 struct udevice *dev;
81
82 /* resets */
83 struct reset_ctl core_rst;
84 struct reset_ctl mgmt_rst;
85 struct reset_ctl mgmt_sticky_rst;
86 struct reset_ctl pipe_rst;
87 struct reset_ctl pm_rst;
88 struct reset_ctl pclk_rst;
89 struct reset_ctl aclk_rst;
90
91 /* gpio */
92 struct gpio_desc ep_gpio;
93
94 /* vpcie regulators */
95 struct udevice *vpcie12v;
96 struct udevice *vpcie3v3;
97 struct udevice *vpcie1v8;
98 struct udevice *vpcie0v9;
99
100 /* phy */
101 struct phy pcie_phy;
102};
103
Jagan Teki02262472020-05-09 22:26:21 +0530104static int rockchip_pcie_rd_conf(const struct udevice *udev, pci_dev_t bdf,
105 uint offset, ulong *valuep,
106 enum pci_size_t size)
107{
108 struct rockchip_pcie *priv = dev_get_priv(udev);
109 unsigned int bus = PCI_BUS(bdf);
110 unsigned int dev = PCI_DEV(bdf);
Pali Rohár23769352021-11-03 01:01:05 +0100111 int where = PCIE_ECAM_OFFSET(PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), offset & ~0x3);
Jagan Teki02262472020-05-09 22:26:21 +0530112 ulong value;
113
114 if (bus == priv->first_busno && dev == 0) {
115 value = readl(priv->apb_base + PCIE_RC_NORMAL_BASE + where);
116 *valuep = pci_conv_32_to_size(value, offset, size);
117 return 0;
118 }
119
120 if ((bus == priv->first_busno + 1) && dev == 0) {
121 value = readl(priv->axi_base + where);
122 *valuep = pci_conv_32_to_size(value, offset, size);
123 return 0;
124 }
125
126 *valuep = pci_get_ff(size);
127
128 return 0;
129}
130
131static int rockchip_pcie_wr_conf(struct udevice *udev, pci_dev_t bdf,
132 uint offset, ulong value,
133 enum pci_size_t size)
134{
135 struct rockchip_pcie *priv = dev_get_priv(udev);
136 unsigned int bus = PCI_BUS(bdf);
137 unsigned int dev = PCI_DEV(bdf);
Pali Rohár23769352021-11-03 01:01:05 +0100138 int where = PCIE_ECAM_OFFSET(PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), offset & ~0x3);
Jagan Teki02262472020-05-09 22:26:21 +0530139 ulong old;
140
141 if (bus == priv->first_busno && dev == 0) {
142 old = readl(priv->apb_base + PCIE_RC_NORMAL_BASE + where);
143 value = pci_conv_size_to_32(old, value, offset, size);
144 writel(value, priv->apb_base + PCIE_RC_NORMAL_BASE + where);
145 return 0;
146 }
147
148 if ((bus == priv->first_busno + 1) && dev == 0) {
149 old = readl(priv->axi_base + where);
150 value = pci_conv_size_to_32(old, value, offset, size);
151 writel(value, priv->axi_base + where);
152 return 0;
153 }
154
155 return 0;
156}
157
158static int rockchip_pcie_atr_init(struct rockchip_pcie *priv)
159{
160 struct udevice *ctlr = pci_get_controller(priv->dev);
161 struct pci_controller *hose = dev_get_uclass_priv(ctlr);
162 u64 addr, size, offset;
163 u32 type;
164 int i, region;
165
166 /* Use region 0 to map PCI configuration space. */
167 writel(25 - 1, priv->apb_base + PCIE_ATR_OB_ADDR0(0));
168 writel(0, priv->apb_base + PCIE_ATR_OB_ADDR1(0));
169 writel(PCIE_ATR_HDR_CFG_TYPE0 | PCIE_ATR_HDR_RID,
170 priv->apb_base + PCIE_ATR_OB_DESC0(0));
171 writel(0, priv->apb_base + PCIE_ATR_OB_DESC1(0));
172
173 for (i = 0; i < hose->region_count; i++) {
174 if (hose->regions[i].flags == PCI_REGION_SYS_MEMORY)
175 continue;
176
177 if (hose->regions[i].flags == PCI_REGION_IO)
178 type = PCIE_ATR_HDR_IO;
179 else
180 type = PCIE_ATR_HDR_MEM;
181
182 /* Only support identity mappings. */
183 if (hose->regions[i].bus_start !=
184 hose->regions[i].phys_start)
185 return -EINVAL;
186
187 /* Only support mappings aligned on a region boundary. */
188 addr = hose->regions[i].bus_start;
189 if (addr & (PCIE_ATR_OB_REGION_SIZE - 1))
190 return -EINVAL;
191
192 /* Mappings should lie between AXI and APB regions. */
193 size = hose->regions[i].size;
194 if (addr < (u64)priv->axi_base + PCIE_ATR_OB_REGION0_SIZE)
195 return -EINVAL;
196 if (addr + size > (u64)priv->apb_base)
197 return -EINVAL;
198
199 offset = addr - (u64)priv->axi_base - PCIE_ATR_OB_REGION0_SIZE;
200 region = 1 + (offset / PCIE_ATR_OB_REGION_SIZE);
201 while (size > 0) {
202 writel(32 - 1,
203 priv->apb_base + PCIE_ATR_OB_ADDR0(region));
204 writel(0, priv->apb_base + PCIE_ATR_OB_ADDR1(region));
205 writel(type | PCIE_ATR_HDR_RID,
206 priv->apb_base + PCIE_ATR_OB_DESC0(region));
207 writel(0, priv->apb_base + PCIE_ATR_OB_DESC1(region));
208
209 addr += PCIE_ATR_OB_REGION_SIZE;
210 size -= PCIE_ATR_OB_REGION_SIZE;
211 region++;
212 }
213 }
214
215 /* Passthrough inbound translations unmodified. */
216 writel(32 - 1, priv->apb_base + PCIE_ATR_IB_ADDR0(2));
217 writel(0, priv->apb_base + PCIE_ATR_IB_ADDR1(2));
218
219 return 0;
220}
221
222static int rockchip_pcie_init_port(struct udevice *dev)
223{
224 struct rockchip_pcie *priv = dev_get_priv(dev);
225 u32 cr, val, status;
226 int ret;
227
228 if (dm_gpio_is_valid(&priv->ep_gpio))
229 dm_gpio_set_value(&priv->ep_gpio, 0);
230
231 ret = reset_assert(&priv->aclk_rst);
232 if (ret) {
233 dev_err(dev, "failed to assert aclk reset (ret=%d)\n", ret);
234 return ret;
235 }
236
237 ret = reset_assert(&priv->pclk_rst);
238 if (ret) {
239 dev_err(dev, "failed to assert pclk reset (ret=%d)\n", ret);
240 return ret;
241 }
242
243 ret = reset_assert(&priv->pm_rst);
244 if (ret) {
245 dev_err(dev, "failed to assert pm reset (ret=%d)\n", ret);
246 return ret;
247 }
248
Jagan Teki427603b2020-07-09 23:41:02 +0530249 ret = generic_phy_init(&priv->pcie_phy);
Jagan Teki5f142322020-05-09 22:26:22 +0530250 if (ret) {
251 dev_err(dev, "failed to init phy (ret=%d)\n", ret);
252 goto err_exit_phy;
253 }
254
Jagan Teki02262472020-05-09 22:26:21 +0530255 ret = reset_assert(&priv->core_rst);
256 if (ret) {
257 dev_err(dev, "failed to assert core reset (ret=%d)\n", ret);
Jagan Teki5f142322020-05-09 22:26:22 +0530258 goto err_exit_phy;
Jagan Teki02262472020-05-09 22:26:21 +0530259 }
260
261 ret = reset_assert(&priv->mgmt_rst);
262 if (ret) {
263 dev_err(dev, "failed to assert mgmt reset (ret=%d)\n", ret);
Jagan Teki5f142322020-05-09 22:26:22 +0530264 goto err_exit_phy;
Jagan Teki02262472020-05-09 22:26:21 +0530265 }
266
267 ret = reset_assert(&priv->mgmt_sticky_rst);
268 if (ret) {
269 dev_err(dev, "failed to assert mgmt-sticky reset (ret=%d)\n",
270 ret);
Jagan Teki5f142322020-05-09 22:26:22 +0530271 goto err_exit_phy;
Jagan Teki02262472020-05-09 22:26:21 +0530272 }
273
274 ret = reset_assert(&priv->pipe_rst);
275 if (ret) {
276 dev_err(dev, "failed to assert pipe reset (ret=%d)\n", ret);
Jagan Teki5f142322020-05-09 22:26:22 +0530277 goto err_exit_phy;
Jagan Teki02262472020-05-09 22:26:21 +0530278 }
279
280 udelay(10);
281
282 ret = reset_deassert(&priv->pm_rst);
283 if (ret) {
284 dev_err(dev, "failed to deassert pm reset (ret=%d)\n", ret);
Jagan Teki5f142322020-05-09 22:26:22 +0530285 goto err_exit_phy;
Jagan Teki02262472020-05-09 22:26:21 +0530286 }
287
288 ret = reset_deassert(&priv->aclk_rst);
289 if (ret) {
290 dev_err(dev, "failed to deassert aclk reset (ret=%d)\n", ret);
Jagan Teki5f142322020-05-09 22:26:22 +0530291 goto err_exit_phy;
Jagan Teki02262472020-05-09 22:26:21 +0530292 }
293
294 ret = reset_deassert(&priv->pclk_rst);
295 if (ret) {
296 dev_err(dev, "failed to deassert pclk reset (ret=%d)\n", ret);
Jagan Teki5f142322020-05-09 22:26:22 +0530297 goto err_exit_phy;
Jagan Teki02262472020-05-09 22:26:21 +0530298 }
299
300 /* Select GEN1 for now */
301 cr = PCIE_CLIENT_GEN_SEL_1;
302 /* Set Root complex mode */
303 cr |= PCIE_CLIENT_CONF_ENABLE | PCIE_CLIENT_MODE_RC;
304 writel(cr, priv->apb_base + PCIE_CLIENT_CONFIG);
305
Jagan Teki427603b2020-07-09 23:41:02 +0530306 ret = generic_phy_power_on(&priv->pcie_phy);
Jagan Teki5f142322020-05-09 22:26:22 +0530307 if (ret) {
308 dev_err(dev, "failed to power on phy (ret=%d)\n", ret);
309 goto err_power_off_phy;
310 }
311
Jagan Teki02262472020-05-09 22:26:21 +0530312 ret = reset_deassert(&priv->mgmt_sticky_rst);
313 if (ret) {
314 dev_err(dev, "failed to deassert mgmt-sticky reset (ret=%d)\n",
315 ret);
Jagan Teki5f142322020-05-09 22:26:22 +0530316 goto err_power_off_phy;
Jagan Teki02262472020-05-09 22:26:21 +0530317 }
318
319 ret = reset_deassert(&priv->core_rst);
320 if (ret) {
321 dev_err(dev, "failed to deassert core reset (ret=%d)\n", ret);
Jagan Teki5f142322020-05-09 22:26:22 +0530322 goto err_power_off_phy;
Jagan Teki02262472020-05-09 22:26:21 +0530323 }
324
325 ret = reset_deassert(&priv->mgmt_rst);
326 if (ret) {
327 dev_err(dev, "failed to deassert mgmt reset (ret=%d)\n", ret);
Jagan Teki5f142322020-05-09 22:26:22 +0530328 goto err_power_off_phy;
Jagan Teki02262472020-05-09 22:26:21 +0530329 }
330
331 ret = reset_deassert(&priv->pipe_rst);
332 if (ret) {
333 dev_err(dev, "failed to deassert pipe reset (ret=%d)\n", ret);
Jagan Teki5f142322020-05-09 22:26:22 +0530334 goto err_power_off_phy;
Jagan Teki02262472020-05-09 22:26:21 +0530335 }
336
337 /* Enable Gen1 training */
338 writel(PCIE_CLIENT_LINK_TRAIN_ENABLE,
339 priv->apb_base + PCIE_CLIENT_CONFIG);
340
341 if (dm_gpio_is_valid(&priv->ep_gpio))
342 dm_gpio_set_value(&priv->ep_gpio, 1);
343
344 ret = readl_poll_sleep_timeout
345 (priv->apb_base + PCIE_CLIENT_BASIC_STATUS1,
346 status, PCIE_LINK_UP(status), 20, 500 * 1000);
347 if (ret) {
348 dev_err(dev, "PCIe link training gen1 timeout!\n");
Jagan Teki5f142322020-05-09 22:26:22 +0530349 goto err_power_off_phy;
Jagan Teki02262472020-05-09 22:26:21 +0530350 }
351
352 /* Initialize Root Complex registers. */
353 writel(PCIE_LM_VENDOR_ROCKCHIP, priv->apb_base + PCIE_LM_VENDOR_ID);
354 writel(PCI_CLASS_BRIDGE_PCI << 16,
355 priv->apb_base + PCIE_RC_BASE + PCI_CLASS_REVISION);
356 writel(PCIE_LM_RCBARPIE | PCIE_LM_RCBARPIS,
357 priv->apb_base + PCIE_LM_RCBAR);
358
359 if (dev_read_bool(dev, "aspm-no-l0s")) {
360 val = readl(priv->apb_base + PCIE_RC_PCIE_LCAP);
361 val &= ~PCIE_RC_PCIE_LCAP_APMS_L0S;
362 writel(val, priv->apb_base + PCIE_RC_PCIE_LCAP);
363 }
364
365 /* Configure Address Translation. */
366 ret = rockchip_pcie_atr_init(priv);
367 if (ret) {
Simon Glass75e534b2020-12-16 21:20:07 -0700368 dev_err(dev, "PCIE-%d: ATR init failed\n", dev_seq(dev));
Jagan Teki5f142322020-05-09 22:26:22 +0530369 goto err_power_off_phy;
Jagan Teki02262472020-05-09 22:26:21 +0530370 }
371
372 return 0;
Jagan Teki5f142322020-05-09 22:26:22 +0530373
374err_power_off_phy:
Jagan Teki427603b2020-07-09 23:41:02 +0530375 generic_phy_power_off(&priv->pcie_phy);
Jagan Teki5f142322020-05-09 22:26:22 +0530376err_exit_phy:
Jagan Teki427603b2020-07-09 23:41:02 +0530377 generic_phy_exit(&priv->pcie_phy);
Jagan Teki5f142322020-05-09 22:26:22 +0530378 return ret;
Jagan Teki02262472020-05-09 22:26:21 +0530379}
380
381static int rockchip_pcie_set_vpcie(struct udevice *dev)
382{
383 struct rockchip_pcie *priv = dev_get_priv(dev);
384 int ret;
385
Mark Kettenis15b40062020-05-24 22:32:51 +0200386 if (priv->vpcie3v3) {
Jagan Teki02262472020-05-09 22:26:21 +0530387 ret = regulator_set_enable(priv->vpcie3v3, true);
388 if (ret) {
389 dev_err(dev, "failed to enable vpcie3v3 (ret=%d)\n",
390 ret);
391 return ret;
392 }
393 }
394
Mark Kettenis15b40062020-05-24 22:32:51 +0200395 if (priv->vpcie1v8) {
396 ret = regulator_set_enable(priv->vpcie1v8, true);
397 if (ret) {
398 dev_err(dev, "failed to enable vpcie1v8 (ret=%d)\n",
399 ret);
400 goto err_disable_3v3;
401 }
Jagan Teki02262472020-05-09 22:26:21 +0530402 }
403
Mark Kettenis15b40062020-05-24 22:32:51 +0200404 if (priv->vpcie0v9) {
405 ret = regulator_set_enable(priv->vpcie0v9, true);
406 if (ret) {
407 dev_err(dev, "failed to enable vpcie0v9 (ret=%d)\n",
408 ret);
409 goto err_disable_1v8;
410 }
Jagan Teki02262472020-05-09 22:26:21 +0530411 }
412
413 return 0;
414
415err_disable_1v8:
Mark Kettenis15b40062020-05-24 22:32:51 +0200416 if (priv->vpcie1v8)
417 regulator_set_enable(priv->vpcie1v8, false);
Jagan Teki02262472020-05-09 22:26:21 +0530418err_disable_3v3:
Mark Kettenis15b40062020-05-24 22:32:51 +0200419 if (priv->vpcie3v3)
Jagan Teki02262472020-05-09 22:26:21 +0530420 regulator_set_enable(priv->vpcie3v3, false);
421 return ret;
422}
423
424static int rockchip_pcie_parse_dt(struct udevice *dev)
425{
426 struct rockchip_pcie *priv = dev_get_priv(dev);
427 int ret;
428
429 priv->axi_base = dev_read_addr_name(dev, "axi-base");
430 if (!priv->axi_base)
431 return -ENODEV;
432
433 priv->apb_base = dev_read_addr_name(dev, "apb-base");
434 if (!priv->axi_base)
435 return -ENODEV;
436
437 ret = gpio_request_by_name(dev, "ep-gpios", 0,
438 &priv->ep_gpio, GPIOD_IS_OUT);
439 if (ret) {
440 dev_err(dev, "failed to find ep-gpios property\n");
441 return ret;
442 }
443
444 ret = reset_get_by_name(dev, "core", &priv->core_rst);
445 if (ret) {
446 dev_err(dev, "failed to get core reset (ret=%d)\n", ret);
447 return ret;
448 }
449
450 ret = reset_get_by_name(dev, "mgmt", &priv->mgmt_rst);
451 if (ret) {
452 dev_err(dev, "failed to get mgmt reset (ret=%d)\n", ret);
453 return ret;
454 }
455
456 ret = reset_get_by_name(dev, "mgmt-sticky", &priv->mgmt_sticky_rst);
457 if (ret) {
458 dev_err(dev, "failed to get mgmt-sticky reset (ret=%d)\n", ret);
459 return ret;
460 }
461
462 ret = reset_get_by_name(dev, "pipe", &priv->pipe_rst);
463 if (ret) {
464 dev_err(dev, "failed to get pipe reset (ret=%d)\n", ret);
465 return ret;
466 }
467
468 ret = reset_get_by_name(dev, "pm", &priv->pm_rst);
469 if (ret) {
470 dev_err(dev, "failed to get pm reset (ret=%d)\n", ret);
471 return ret;
472 }
473
474 ret = reset_get_by_name(dev, "pclk", &priv->pclk_rst);
475 if (ret) {
476 dev_err(dev, "failed to get pclk reset (ret=%d)\n", ret);
477 return ret;
478 }
479
480 ret = reset_get_by_name(dev, "aclk", &priv->aclk_rst);
481 if (ret) {
482 dev_err(dev, "failed to get aclk reset (ret=%d)\n", ret);
483 return ret;
484 }
485
486 ret = device_get_supply_regulator(dev, "vpcie3v3-supply",
487 &priv->vpcie3v3);
488 if (ret && ret != -ENOENT) {
489 dev_err(dev, "failed to get vpcie3v3 supply (ret=%d)\n", ret);
490 return ret;
491 }
492
493 ret = device_get_supply_regulator(dev, "vpcie1v8-supply",
494 &priv->vpcie1v8);
Mark Kettenis15b40062020-05-24 22:32:51 +0200495 if (ret && ret != -ENOENT) {
Jagan Teki02262472020-05-09 22:26:21 +0530496 dev_err(dev, "failed to get vpcie1v8 supply (ret=%d)\n", ret);
497 return ret;
498 }
499
500 ret = device_get_supply_regulator(dev, "vpcie0v9-supply",
501 &priv->vpcie0v9);
Mark Kettenis15b40062020-05-24 22:32:51 +0200502 if (ret && ret != -ENOENT) {
Jagan Teki02262472020-05-09 22:26:21 +0530503 dev_err(dev, "failed to get vpcie0v9 supply (ret=%d)\n", ret);
504 return ret;
505 }
506
Jagan Teki427603b2020-07-09 23:41:02 +0530507 ret = generic_phy_get_by_index(dev, 0, &priv->pcie_phy);
508 if (ret) {
509 dev_err(dev, "failed to get pcie-phy (ret=%d)\n", ret);
510 return ret;
511 }
512
Jagan Teki02262472020-05-09 22:26:21 +0530513 return 0;
514}
515
516static int rockchip_pcie_probe(struct udevice *dev)
517{
518 struct rockchip_pcie *priv = dev_get_priv(dev);
519 struct udevice *ctlr = pci_get_controller(dev);
520 struct pci_controller *hose = dev_get_uclass_priv(ctlr);
521 int ret;
522
Simon Glass75e534b2020-12-16 21:20:07 -0700523 priv->first_busno = dev_seq(dev);
Jagan Teki02262472020-05-09 22:26:21 +0530524 priv->dev = dev;
525
526 ret = rockchip_pcie_parse_dt(dev);
527 if (ret)
528 return ret;
529
Jagan Teki02262472020-05-09 22:26:21 +0530530 ret = rockchip_pcie_set_vpcie(dev);
531 if (ret)
532 return ret;
533
534 ret = rockchip_pcie_init_port(dev);
535 if (ret)
536 return ret;
537
538 dev_info(dev, "PCIE-%d: Link up (Bus%d)\n",
Simon Glass75e534b2020-12-16 21:20:07 -0700539 dev_seq(dev), hose->first_busno);
Jagan Teki02262472020-05-09 22:26:21 +0530540
541 return 0;
542}
543
544static const struct dm_pci_ops rockchip_pcie_ops = {
545 .read_config = rockchip_pcie_rd_conf,
546 .write_config = rockchip_pcie_wr_conf,
547};
548
549static const struct udevice_id rockchip_pcie_ids[] = {
550 { .compatible = "rockchip,rk3399-pcie" },
551 { }
552};
553
554U_BOOT_DRIVER(rockchip_pcie) = {
555 .name = "rockchip_pcie",
556 .id = UCLASS_PCI,
557 .of_match = rockchip_pcie_ids,
558 .ops = &rockchip_pcie_ops,
559 .probe = rockchip_pcie_probe,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700560 .priv_auto = sizeof(struct rockchip_pcie),
Jagan Teki02262472020-05-09 22:26:21 +0530561};