blob: 78f2c7d6bcdf9e0aa0d9931348088202465aeb14 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0
Marek Vasut988ee702013-12-14 05:55:28 +01002/*
3 * Freescale i.MX6 PCI Express Root-Complex driver
4 *
5 * Copyright (C) 2013 Marek Vasut <marex@denx.de>
6 *
7 * Based on upstream Linux kernel driver:
8 * pci-imx6.c: Sean Cross <xobs@kosagi.com>
9 * pcie-designware.c: Jingoo Han <jg1.han@samsung.com>
Sumit Garg3fc43942024-03-21 20:25:04 +053010 *
11 * This is a legacy PCIe iMX driver kept to support older iMX6 SoCs. It is
12 * rather tied to quite old port of pcie-designware driver from Linux which
13 * suffices only iMX6 specific needs. But now we have modern PCIe iMX driver
14 * (drivers/pci/pcie_dw_imx.c) utilizing all the common DWC specific bits from
15 * (drivers/pci/pcie_dw_common.*). So you are encouraged to add any further iMX
16 * SoC support there or even better if you posses older iMX6 SoCs then switch
17 * those too in order to have a single modern PCIe iMX driver.
Marek Vasut988ee702013-12-14 05:55:28 +010018 */
19
20#include <common.h>
Simon Glass18afe102019-11-14 12:57:47 -070021#include <init.h>
Simon Glass0f2af882020-05-10 11:40:05 -060022#include <log.h>
Simon Glass9bc15642020-02-03 07:36:16 -070023#include <malloc.h>
Marek Vasut988ee702013-12-14 05:55:28 +010024#include <pci.h>
Tim Harvey541e2732022-04-13 15:54:37 -070025#include <power/regulator.h>
Marek Vasut988ee702013-12-14 05:55:28 +010026#include <asm/arch/clock.h>
27#include <asm/arch/iomux.h>
28#include <asm/arch/crm_regs.h>
Marek Vasutd9056c22014-02-03 21:46:22 +010029#include <asm/gpio.h>
Marek Vasut988ee702013-12-14 05:55:28 +010030#include <asm/io.h>
Marek Vasut3c9f33e2019-06-09 03:50:55 +020031#include <dm.h>
Simon Glassdbd79542020-05-10 11:40:11 -060032#include <linux/delay.h>
Alexey Brodkin267d8e22014-02-26 17:47:58 +040033#include <linux/sizes.h>
Marek Vasut988ee702013-12-14 05:55:28 +010034#include <errno.h>
Fabio Estevamb5272bd2015-10-13 11:01:27 -030035#include <asm/arch/sys_proto.h>
Marek Vasut988ee702013-12-14 05:55:28 +010036
37#define PCI_ACCESS_READ 0
38#define PCI_ACCESS_WRITE 1
39
Fabio Estevam211a4902014-08-25 14:26:45 -030040#ifdef CONFIG_MX6SX
41#define MX6_DBI_ADDR 0x08ffc000
42#define MX6_IO_ADDR 0x08000000
43#define MX6_MEM_ADDR 0x08100000
44#define MX6_ROOT_ADDR 0x08f00000
45#else
Marek Vasut988ee702013-12-14 05:55:28 +010046#define MX6_DBI_ADDR 0x01ffc000
Marek Vasut988ee702013-12-14 05:55:28 +010047#define MX6_IO_ADDR 0x01000000
Marek Vasut988ee702013-12-14 05:55:28 +010048#define MX6_MEM_ADDR 0x01100000
Marek Vasut988ee702013-12-14 05:55:28 +010049#define MX6_ROOT_ADDR 0x01f00000
Fabio Estevam211a4902014-08-25 14:26:45 -030050#endif
51#define MX6_DBI_SIZE 0x4000
52#define MX6_IO_SIZE 0x100000
53#define MX6_MEM_SIZE 0xe00000
Marek Vasut988ee702013-12-14 05:55:28 +010054#define MX6_ROOT_SIZE 0xfc000
55
56/* PCIe Port Logic registers (memory-mapped) */
57#define PL_OFFSET 0x700
Tim Harveyc22f2ea2017-05-12 12:58:41 -070058#define PCIE_PL_PFLR (PL_OFFSET + 0x08)
59#define PCIE_PL_PFLR_LINK_STATE_MASK (0x3f << 16)
60#define PCIE_PL_PFLR_FORCE_LINK (1 << 15)
Marek Vasut988ee702013-12-14 05:55:28 +010061#define PCIE_PHY_DEBUG_R0 (PL_OFFSET + 0x28)
62#define PCIE_PHY_DEBUG_R1 (PL_OFFSET + 0x2c)
63#define PCIE_PHY_DEBUG_R1_LINK_UP (1 << 4)
64#define PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING (1 << 29)
65
66#define PCIE_PHY_CTRL (PL_OFFSET + 0x114)
67#define PCIE_PHY_CTRL_DATA_LOC 0
68#define PCIE_PHY_CTRL_CAP_ADR_LOC 16
69#define PCIE_PHY_CTRL_CAP_DAT_LOC 17
70#define PCIE_PHY_CTRL_WR_LOC 18
71#define PCIE_PHY_CTRL_RD_LOC 19
72
73#define PCIE_PHY_STAT (PL_OFFSET + 0x110)
74#define PCIE_PHY_STAT_DATA_LOC 0
75#define PCIE_PHY_STAT_ACK_LOC 16
76
77/* PHY registers (not memory-mapped) */
78#define PCIE_PHY_RX_ASIC_OUT 0x100D
79
80#define PHY_RX_OVRD_IN_LO 0x1005
81#define PHY_RX_OVRD_IN_LO_RX_DATA_EN (1 << 5)
82#define PHY_RX_OVRD_IN_LO_RX_PLL_EN (1 << 3)
83
Fabio Estevam211a4902014-08-25 14:26:45 -030084#define PCIE_PHY_PUP_REQ (1 << 7)
85
Marek Vasut988ee702013-12-14 05:55:28 +010086/* iATU registers */
87#define PCIE_ATU_VIEWPORT 0x900
88#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
89#define PCIE_ATU_REGION_OUTBOUND (0x0 << 31)
90#define PCIE_ATU_REGION_INDEX1 (0x1 << 0)
91#define PCIE_ATU_REGION_INDEX0 (0x0 << 0)
92#define PCIE_ATU_CR1 0x904
93#define PCIE_ATU_TYPE_MEM (0x0 << 0)
94#define PCIE_ATU_TYPE_IO (0x2 << 0)
95#define PCIE_ATU_TYPE_CFG0 (0x4 << 0)
96#define PCIE_ATU_TYPE_CFG1 (0x5 << 0)
97#define PCIE_ATU_CR2 0x908
98#define PCIE_ATU_ENABLE (0x1 << 31)
99#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30)
100#define PCIE_ATU_LOWER_BASE 0x90C
101#define PCIE_ATU_UPPER_BASE 0x910
102#define PCIE_ATU_LIMIT 0x914
103#define PCIE_ATU_LOWER_TARGET 0x918
104#define PCIE_ATU_BUS(x) (((x) & 0xff) << 24)
105#define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19)
106#define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
107#define PCIE_ATU_UPPER_TARGET 0x91C
108
Marek Vasut6ce573f2019-06-09 03:50:52 +0200109struct imx_pcie_priv {
110 void __iomem *dbi_base;
111 void __iomem *cfg_base;
Tim Harvey7367b392021-07-06 10:19:09 -0700112 struct gpio_desc reset_gpio;
113 bool reset_active_high;
Tim Harvey541e2732022-04-13 15:54:37 -0700114 struct udevice *vpcie;
Marek Vasut6ce573f2019-06-09 03:50:52 +0200115};
116
Marek Vasut988ee702013-12-14 05:55:28 +0100117/*
118 * PHY access functions
119 */
120static int pcie_phy_poll_ack(void __iomem *dbi_base, int exp_val)
121{
122 u32 val;
123 u32 max_iterations = 10;
124 u32 wait_counter = 0;
125
126 do {
127 val = readl(dbi_base + PCIE_PHY_STAT);
128 val = (val >> PCIE_PHY_STAT_ACK_LOC) & 0x1;
129 wait_counter++;
130
131 if (val == exp_val)
132 return 0;
133
134 udelay(1);
135 } while (wait_counter < max_iterations);
136
137 return -ETIMEDOUT;
138}
139
140static int pcie_phy_wait_ack(void __iomem *dbi_base, int addr)
141{
142 u32 val;
143 int ret;
144
145 val = addr << PCIE_PHY_CTRL_DATA_LOC;
146 writel(val, dbi_base + PCIE_PHY_CTRL);
147
148 val |= (0x1 << PCIE_PHY_CTRL_CAP_ADR_LOC);
149 writel(val, dbi_base + PCIE_PHY_CTRL);
150
151 ret = pcie_phy_poll_ack(dbi_base, 1);
152 if (ret)
153 return ret;
154
155 val = addr << PCIE_PHY_CTRL_DATA_LOC;
156 writel(val, dbi_base + PCIE_PHY_CTRL);
157
158 ret = pcie_phy_poll_ack(dbi_base, 0);
159 if (ret)
160 return ret;
161
162 return 0;
163}
164
165/* Read from the 16-bit PCIe PHY control registers (not memory-mapped) */
166static int pcie_phy_read(void __iomem *dbi_base, int addr , int *data)
167{
168 u32 val, phy_ctl;
169 int ret;
170
171 ret = pcie_phy_wait_ack(dbi_base, addr);
172 if (ret)
173 return ret;
174
175 /* assert Read signal */
176 phy_ctl = 0x1 << PCIE_PHY_CTRL_RD_LOC;
177 writel(phy_ctl, dbi_base + PCIE_PHY_CTRL);
178
179 ret = pcie_phy_poll_ack(dbi_base, 1);
180 if (ret)
181 return ret;
182
183 val = readl(dbi_base + PCIE_PHY_STAT);
184 *data = val & 0xffff;
185
186 /* deassert Read signal */
187 writel(0x00, dbi_base + PCIE_PHY_CTRL);
188
189 ret = pcie_phy_poll_ack(dbi_base, 0);
190 if (ret)
191 return ret;
192
193 return 0;
194}
195
196static int pcie_phy_write(void __iomem *dbi_base, int addr, int data)
197{
198 u32 var;
199 int ret;
200
201 /* write addr */
202 /* cap addr */
203 ret = pcie_phy_wait_ack(dbi_base, addr);
204 if (ret)
205 return ret;
206
207 var = data << PCIE_PHY_CTRL_DATA_LOC;
208 writel(var, dbi_base + PCIE_PHY_CTRL);
209
210 /* capture data */
211 var |= (0x1 << PCIE_PHY_CTRL_CAP_DAT_LOC);
212 writel(var, dbi_base + PCIE_PHY_CTRL);
213
214 ret = pcie_phy_poll_ack(dbi_base, 1);
215 if (ret)
216 return ret;
217
218 /* deassert cap data */
219 var = data << PCIE_PHY_CTRL_DATA_LOC;
220 writel(var, dbi_base + PCIE_PHY_CTRL);
221
222 /* wait for ack de-assertion */
223 ret = pcie_phy_poll_ack(dbi_base, 0);
224 if (ret)
225 return ret;
226
227 /* assert wr signal */
228 var = 0x1 << PCIE_PHY_CTRL_WR_LOC;
229 writel(var, dbi_base + PCIE_PHY_CTRL);
230
231 /* wait for ack */
232 ret = pcie_phy_poll_ack(dbi_base, 1);
233 if (ret)
234 return ret;
235
236 /* deassert wr signal */
237 var = data << PCIE_PHY_CTRL_DATA_LOC;
238 writel(var, dbi_base + PCIE_PHY_CTRL);
239
240 /* wait for ack de-assertion */
241 ret = pcie_phy_poll_ack(dbi_base, 0);
242 if (ret)
243 return ret;
244
245 writel(0x0, dbi_base + PCIE_PHY_CTRL);
246
247 return 0;
248}
249
Marek Vasut120efeb2019-06-09 03:50:54 +0200250static int imx6_pcie_link_up(struct imx_pcie_priv *priv)
Marek Vasut988ee702013-12-14 05:55:28 +0100251{
252 u32 rc, ltssm;
253 int rx_valid, temp;
254
255 /* link is debug bit 36, debug register 1 starts at bit 32 */
Marek Vasut6ce573f2019-06-09 03:50:52 +0200256 rc = readl(priv->dbi_base + PCIE_PHY_DEBUG_R1);
Marek Vasut988ee702013-12-14 05:55:28 +0100257 if ((rc & PCIE_PHY_DEBUG_R1_LINK_UP) &&
258 !(rc & PCIE_PHY_DEBUG_R1_LINK_IN_TRAINING))
259 return -EAGAIN;
260
261 /*
262 * From L0, initiate MAC entry to gen2 if EP/RC supports gen2.
263 * Wait 2ms (LTSSM timeout is 24ms, PHY lock is ~5us in gen2).
264 * If (MAC/LTSSM.state == Recovery.RcvrLock)
265 * && (PHY/rx_valid==0) then pulse PHY/rx_reset. Transition
266 * to gen2 is stuck
267 */
Marek Vasut6ce573f2019-06-09 03:50:52 +0200268 pcie_phy_read(priv->dbi_base, PCIE_PHY_RX_ASIC_OUT, &rx_valid);
269 ltssm = readl(priv->dbi_base + PCIE_PHY_DEBUG_R0) & 0x3F;
Marek Vasut988ee702013-12-14 05:55:28 +0100270
271 if (rx_valid & 0x01)
272 return 0;
273
274 if (ltssm != 0x0d)
275 return 0;
276
277 printf("transition to gen2 is stuck, reset PHY!\n");
278
Marek Vasut6ce573f2019-06-09 03:50:52 +0200279 pcie_phy_read(priv->dbi_base, PHY_RX_OVRD_IN_LO, &temp);
Marek Vasut988ee702013-12-14 05:55:28 +0100280 temp |= (PHY_RX_OVRD_IN_LO_RX_DATA_EN | PHY_RX_OVRD_IN_LO_RX_PLL_EN);
Marek Vasut6ce573f2019-06-09 03:50:52 +0200281 pcie_phy_write(priv->dbi_base, PHY_RX_OVRD_IN_LO, temp);
Marek Vasut988ee702013-12-14 05:55:28 +0100282
283 udelay(3000);
284
Marek Vasut6ce573f2019-06-09 03:50:52 +0200285 pcie_phy_read(priv->dbi_base, PHY_RX_OVRD_IN_LO, &temp);
Marek Vasut988ee702013-12-14 05:55:28 +0100286 temp &= ~(PHY_RX_OVRD_IN_LO_RX_DATA_EN | PHY_RX_OVRD_IN_LO_RX_PLL_EN);
Marek Vasut6ce573f2019-06-09 03:50:52 +0200287 pcie_phy_write(priv->dbi_base, PHY_RX_OVRD_IN_LO, temp);
Marek Vasut988ee702013-12-14 05:55:28 +0100288
289 return 0;
290}
291
292/*
293 * iATU region setup
294 */
Marek Vasut120efeb2019-06-09 03:50:54 +0200295static int imx_pcie_regions_setup(struct imx_pcie_priv *priv)
Marek Vasut988ee702013-12-14 05:55:28 +0100296{
297 /*
298 * i.MX6 defines 16MB in the AXI address map for PCIe.
299 *
300 * That address space excepted the pcie registers is
301 * split and defined into different regions by iATU,
302 * with sizes and offsets as follows:
303 *
304 * 0x0100_0000 --- 0x010F_FFFF 1MB IORESOURCE_IO
305 * 0x0110_0000 --- 0x01EF_FFFF 14MB IORESOURCE_MEM
306 * 0x01F0_0000 --- 0x01FF_FFFF 1MB Cfg + Registers
307 */
308
309 /* CMD reg:I/O space, MEM space, and Bus Master Enable */
Marek Vasut6ce573f2019-06-09 03:50:52 +0200310 setbits_le32(priv->dbi_base + PCI_COMMAND,
Marek Vasut988ee702013-12-14 05:55:28 +0100311 PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
312
Pali Rohár25781e22022-02-18 13:18:40 +0100313 /* Set the CLASS_REV of RC CFG header to PCI_CLASS_BRIDGE_PCI_NORMAL */
Marek Vasut6ce573f2019-06-09 03:50:52 +0200314 setbits_le32(priv->dbi_base + PCI_CLASS_REVISION,
Pali Rohár25781e22022-02-18 13:18:40 +0100315 PCI_CLASS_BRIDGE_PCI_NORMAL << 8);
Marek Vasut988ee702013-12-14 05:55:28 +0100316
317 /* Region #0 is used for Outbound CFG space access. */
Marek Vasut6ce573f2019-06-09 03:50:52 +0200318 writel(0, priv->dbi_base + PCIE_ATU_VIEWPORT);
Marek Vasut988ee702013-12-14 05:55:28 +0100319
Marek Vasut2c20b752019-06-09 03:50:53 +0200320 writel(lower_32_bits((uintptr_t)priv->cfg_base),
321 priv->dbi_base + PCIE_ATU_LOWER_BASE);
322 writel(upper_32_bits((uintptr_t)priv->cfg_base),
323 priv->dbi_base + PCIE_ATU_UPPER_BASE);
324 writel(lower_32_bits((uintptr_t)priv->cfg_base + MX6_ROOT_SIZE),
Marek Vasut6ce573f2019-06-09 03:50:52 +0200325 priv->dbi_base + PCIE_ATU_LIMIT);
Marek Vasut988ee702013-12-14 05:55:28 +0100326
Marek Vasut6ce573f2019-06-09 03:50:52 +0200327 writel(0, priv->dbi_base + PCIE_ATU_LOWER_TARGET);
328 writel(0, priv->dbi_base + PCIE_ATU_UPPER_TARGET);
329 writel(PCIE_ATU_TYPE_CFG0, priv->dbi_base + PCIE_ATU_CR1);
330 writel(PCIE_ATU_ENABLE, priv->dbi_base + PCIE_ATU_CR2);
Marek Vasut988ee702013-12-14 05:55:28 +0100331
332 return 0;
333}
334
335/*
336 * PCI Express accessors
337 */
Marek Vasut120efeb2019-06-09 03:50:54 +0200338static void __iomem *get_bus_address(struct imx_pcie_priv *priv,
339 pci_dev_t d, int where)
Marek Vasut988ee702013-12-14 05:55:28 +0100340{
Marek Vasut2c20b752019-06-09 03:50:53 +0200341 void __iomem *va_address;
Marek Vasut988ee702013-12-14 05:55:28 +0100342
343 /* Reconfigure Region #0 */
Marek Vasut6ce573f2019-06-09 03:50:52 +0200344 writel(0, priv->dbi_base + PCIE_ATU_VIEWPORT);
Marek Vasut988ee702013-12-14 05:55:28 +0100345
346 if (PCI_BUS(d) < 2)
Marek Vasut6ce573f2019-06-09 03:50:52 +0200347 writel(PCIE_ATU_TYPE_CFG0, priv->dbi_base + PCIE_ATU_CR1);
Marek Vasut988ee702013-12-14 05:55:28 +0100348 else
Marek Vasut6ce573f2019-06-09 03:50:52 +0200349 writel(PCIE_ATU_TYPE_CFG1, priv->dbi_base + PCIE_ATU_CR1);
Marek Vasut988ee702013-12-14 05:55:28 +0100350
351 if (PCI_BUS(d) == 0) {
Marek Vasut2c20b752019-06-09 03:50:53 +0200352 va_address = priv->dbi_base;
Marek Vasut988ee702013-12-14 05:55:28 +0100353 } else {
Marek Vasut6ce573f2019-06-09 03:50:52 +0200354 writel(d << 8, priv->dbi_base + PCIE_ATU_LOWER_TARGET);
Marek Vasut2c20b752019-06-09 03:50:53 +0200355 va_address = priv->cfg_base;
Marek Vasut988ee702013-12-14 05:55:28 +0100356 }
357
358 va_address += (where & ~0x3);
359
360 return va_address;
361}
362
363static int imx_pcie_addr_valid(pci_dev_t d)
364{
365 if ((PCI_BUS(d) == 0) && (PCI_DEV(d) > 1))
366 return -EINVAL;
367 if ((PCI_BUS(d) == 1) && (PCI_DEV(d) > 0))
368 return -EINVAL;
369 return 0;
370}
371
372/*
373 * Replace the original ARM DABT handler with a simple jump-back one.
374 *
375 * The problem here is that if we have a PCIe bridge attached to this PCIe
376 * controller, but no PCIe device is connected to the bridges' downstream
377 * port, the attempt to read/write from/to the config space will produce
378 * a DABT. This is a behavior of the controller and can not be disabled
379 * unfortuatelly.
380 *
381 * To work around the problem, we backup the current DABT handler address
382 * and replace it with our own DABT handler, which only bounces right back
383 * into the code.
384 */
385static void imx_pcie_fix_dabt_handler(bool set)
386{
387 extern uint32_t *_data_abort;
388 uint32_t *data_abort_addr = (uint32_t *)&_data_abort;
389
390 static const uint32_t data_abort_bounce_handler = 0xe25ef004;
391 uint32_t data_abort_bounce_addr = (uint32_t)&data_abort_bounce_handler;
392
393 static uint32_t data_abort_backup;
394
395 if (set) {
396 data_abort_backup = *data_abort_addr;
397 *data_abort_addr = data_abort_bounce_addr;
398 } else {
399 *data_abort_addr = data_abort_backup;
400 }
401}
402
Marek Vasut3c9f33e2019-06-09 03:50:55 +0200403static int imx_pcie_read_cfg(struct imx_pcie_priv *priv, pci_dev_t d,
404 int where, u32 *val)
Marek Vasut988ee702013-12-14 05:55:28 +0100405{
Marek Vasut2c20b752019-06-09 03:50:53 +0200406 void __iomem *va_address;
Marek Vasut988ee702013-12-14 05:55:28 +0100407 int ret;
408
409 ret = imx_pcie_addr_valid(d);
410 if (ret) {
411 *val = 0xffffffff;
Bin Meng122c7662016-01-08 01:03:20 -0800412 return 0;
Marek Vasut988ee702013-12-14 05:55:28 +0100413 }
414
Marek Vasut120efeb2019-06-09 03:50:54 +0200415 va_address = get_bus_address(priv, d, where);
Marek Vasut988ee702013-12-14 05:55:28 +0100416
417 /*
418 * Read the PCIe config space. We must replace the DABT handler
419 * here in case we got data abort from the PCIe controller, see
420 * imx_pcie_fix_dabt_handler() description. Note that writing the
421 * "val" with valid value is also imperative here as in case we
422 * did got DABT, the val would contain random value.
423 */
424 imx_pcie_fix_dabt_handler(true);
425 writel(0xffffffff, val);
426 *val = readl(va_address);
427 imx_pcie_fix_dabt_handler(false);
428
429 return 0;
430}
431
Marek Vasut3c9f33e2019-06-09 03:50:55 +0200432static int imx_pcie_write_cfg(struct imx_pcie_priv *priv, pci_dev_t d,
433 int where, u32 val)
Marek Vasut988ee702013-12-14 05:55:28 +0100434{
Marek Vasut2c20b752019-06-09 03:50:53 +0200435 void __iomem *va_address = NULL;
Marek Vasut988ee702013-12-14 05:55:28 +0100436 int ret;
437
438 ret = imx_pcie_addr_valid(d);
439 if (ret)
440 return ret;
441
Marek Vasut120efeb2019-06-09 03:50:54 +0200442 va_address = get_bus_address(priv, d, where);
Marek Vasut988ee702013-12-14 05:55:28 +0100443
444 /*
445 * Write the PCIe config space. We must replace the DABT handler
446 * here in case we got data abort from the PCIe controller, see
447 * imx_pcie_fix_dabt_handler() description.
448 */
449 imx_pcie_fix_dabt_handler(true);
450 writel(val, va_address);
451 imx_pcie_fix_dabt_handler(false);
452
453 return 0;
454}
455
456/*
457 * Initial bus setup
458 */
Marek Vasut120efeb2019-06-09 03:50:54 +0200459static int imx6_pcie_assert_core_reset(struct imx_pcie_priv *priv,
460 bool prepare_for_boot)
Marek Vasut988ee702013-12-14 05:55:28 +0100461{
462 struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
Fabio Estevamb5272bd2015-10-13 11:01:27 -0300463
464 if (is_mx6dqp())
465 setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_PCIE_SW_RST);
466
Fabio Estevam211a4902014-08-25 14:26:45 -0300467#if defined(CONFIG_MX6SX)
468 struct gpc *gpc_regs = (struct gpc *)GPC_BASE_ADDR;
Marek Vasut988ee702013-12-14 05:55:28 +0100469
Fabio Estevam211a4902014-08-25 14:26:45 -0300470 /* SSP_EN is not used on MX6SX anymore */
471 setbits_le32(&iomuxc_regs->gpr[12], IOMUXC_GPR12_TEST_POWERDOWN);
472 /* Force PCIe PHY reset */
473 setbits_le32(&iomuxc_regs->gpr[5], IOMUXC_GPR5_PCIE_BTNRST);
474 /* Power up PCIe PHY */
475 setbits_le32(&gpc_regs->cntr, PCIE_PHY_PUP_REQ);
476#else
Tim Harveyc22f2ea2017-05-12 12:58:41 -0700477 /*
478 * If the bootloader already enabled the link we need some special
479 * handling to get the core back into a state where it is safe to
480 * touch it for configuration. As there is no dedicated reset signal
481 * wired up for MX6QDL, we need to manually force LTSSM into "detect"
482 * state before completely disabling LTSSM, which is a prerequisite
483 * for core configuration.
484 *
485 * If both LTSSM_ENABLE and REF_SSP_ENABLE are active we have a strong
486 * indication that the bootloader activated the link.
487 */
Tim Harvey3b10a832021-04-16 13:30:41 -0700488 if ((is_mx6dq() || is_mx6sdl()) && prepare_for_boot) {
Tim Harveyc22f2ea2017-05-12 12:58:41 -0700489 u32 val, gpr1, gpr12;
490
491 gpr1 = readl(&iomuxc_regs->gpr[1]);
492 gpr12 = readl(&iomuxc_regs->gpr[12]);
493 if ((gpr1 & IOMUXC_GPR1_PCIE_REF_CLK_EN) &&
494 (gpr12 & IOMUXC_GPR12_PCIE_CTL_2)) {
Marek Vasut6ce573f2019-06-09 03:50:52 +0200495 val = readl(priv->dbi_base + PCIE_PL_PFLR);
Tim Harveyc22f2ea2017-05-12 12:58:41 -0700496 val &= ~PCIE_PL_PFLR_LINK_STATE_MASK;
497 val |= PCIE_PL_PFLR_FORCE_LINK;
498
499 imx_pcie_fix_dabt_handler(true);
Marek Vasut6ce573f2019-06-09 03:50:52 +0200500 writel(val, priv->dbi_base + PCIE_PL_PFLR);
Tim Harveyc22f2ea2017-05-12 12:58:41 -0700501 imx_pcie_fix_dabt_handler(false);
502
503 gpr12 &= ~IOMUXC_GPR12_PCIE_CTL_2;
504 writel(val, &iomuxc_regs->gpr[12]);
505 }
506 }
Marek Vasut988ee702013-12-14 05:55:28 +0100507 setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_TEST_POWERDOWN);
508 clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_REF_SSP_EN);
Fabio Estevam211a4902014-08-25 14:26:45 -0300509#endif
Marek Vasut988ee702013-12-14 05:55:28 +0100510
511 return 0;
512}
513
514static int imx6_pcie_init_phy(void)
515{
516 struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
517
518 clrbits_le32(&iomuxc_regs->gpr[12], IOMUXC_GPR12_APPS_LTSSM_ENABLE);
519
520 clrsetbits_le32(&iomuxc_regs->gpr[12],
521 IOMUXC_GPR12_DEVICE_TYPE_MASK,
522 IOMUXC_GPR12_DEVICE_TYPE_RC);
523 clrsetbits_le32(&iomuxc_regs->gpr[12],
524 IOMUXC_GPR12_LOS_LEVEL_MASK,
525 IOMUXC_GPR12_LOS_LEVEL_9);
526
Fabio Estevam211a4902014-08-25 14:26:45 -0300527#ifdef CONFIG_MX6SX
528 clrsetbits_le32(&iomuxc_regs->gpr[12],
529 IOMUXC_GPR12_RX_EQ_MASK,
530 IOMUXC_GPR12_RX_EQ_2);
531#endif
532
Marek Vasut988ee702013-12-14 05:55:28 +0100533 writel((0x0 << IOMUXC_GPR8_PCS_TX_DEEMPH_GEN1_OFFSET) |
534 (0x0 << IOMUXC_GPR8_PCS_TX_DEEMPH_GEN2_3P5DB_OFFSET) |
535 (20 << IOMUXC_GPR8_PCS_TX_DEEMPH_GEN2_6DB_OFFSET) |
536 (127 << IOMUXC_GPR8_PCS_TX_SWING_FULL_OFFSET) |
537 (127 << IOMUXC_GPR8_PCS_TX_SWING_LOW_OFFSET),
538 &iomuxc_regs->gpr[8]);
539
540 return 0;
541}
542
Tim Harveybc6b7f12022-04-13 15:57:37 -0700543int imx6_pcie_toggle_power(struct udevice *vpcie)
Marek Vasut77779a42014-03-23 22:45:40 +0100544{
Tom Rinic43e27a2022-12-04 10:13:26 -0500545#ifdef CFG_PCIE_IMX_POWER_GPIO
546 gpio_request(CFG_PCIE_IMX_POWER_GPIO, "pcie_power");
547 gpio_direction_output(CFG_PCIE_IMX_POWER_GPIO, 0);
Marek Vasut77779a42014-03-23 22:45:40 +0100548 mdelay(20);
Tom Rinic43e27a2022-12-04 10:13:26 -0500549 gpio_set_value(CFG_PCIE_IMX_POWER_GPIO, 1);
Marek Vasut77779a42014-03-23 22:45:40 +0100550 mdelay(20);
Tom Rinic43e27a2022-12-04 10:13:26 -0500551 gpio_free(CFG_PCIE_IMX_POWER_GPIO);
Marek Vasut77779a42014-03-23 22:45:40 +0100552#endif
Tim Harvey541e2732022-04-13 15:54:37 -0700553
554#if CONFIG_IS_ENABLED(DM_REGULATOR)
555 if (vpcie) {
556 regulator_set_enable(vpcie, false);
557 mdelay(20);
558 regulator_set_enable(vpcie, true);
559 mdelay(20);
560 }
561#endif
Marek Vasut77779a42014-03-23 22:45:40 +0100562 return 0;
563}
564
Tim Harveybc6b7f12022-04-13 15:57:37 -0700565int imx6_pcie_toggle_reset(struct gpio_desc *gpio, bool active_high)
Marek Vasutd9056c22014-02-03 21:46:22 +0100566{
567 /*
568 * See 'PCI EXPRESS BASE SPECIFICATION, REV 3.0, SECTION 6.6.1'
569 * for detailed understanding of the PCIe CR reset logic.
570 *
571 * The PCIe #PERST reset line _MUST_ be connected, otherwise your
572 * design does not conform to the specification. You must wait at
Fabio Estevam1d0b7e32015-09-10 20:45:25 -0300573 * least 20 ms after de-asserting the #PERST so the EP device can
Marek Vasutd9056c22014-02-03 21:46:22 +0100574 * do self-initialisation.
575 *
576 * In case your #PERST pin is connected to a plain GPIO pin of the
Tom Rini9fa71af2022-12-04 10:13:25 -0500577 * CPU, you can define CFG_PCIE_IMX_PERST_GPIO in your board's
Marek Vasutd9056c22014-02-03 21:46:22 +0100578 * configuration file and the condition below will handle the rest
579 * of the reset toggling.
580 *
Marek Vasutd9056c22014-02-03 21:46:22 +0100581 * In case your #PERST line of the PCIe EP device is not connected
582 * at all, your design is broken and you should fix your design,
583 * otherwise you will observe problems like for example the link
584 * not coming up after rebooting the system back from running Linux
585 * that uses the PCIe as well OR the PCIe link might not come up in
586 * Linux at all in the first place since it's in some non-reset
587 * state due to being previously used in U-Boot.
588 */
Tom Rini9fa71af2022-12-04 10:13:25 -0500589#ifdef CFG_PCIE_IMX_PERST_GPIO
590 gpio_request(CFG_PCIE_IMX_PERST_GPIO, "pcie_reset");
591 gpio_direction_output(CFG_PCIE_IMX_PERST_GPIO, 0);
Marek Vasutd9056c22014-02-03 21:46:22 +0100592 mdelay(20);
Tom Rini9fa71af2022-12-04 10:13:25 -0500593 gpio_set_value(CFG_PCIE_IMX_PERST_GPIO, 1);
Marek Vasutd9056c22014-02-03 21:46:22 +0100594 mdelay(20);
Tom Rini9fa71af2022-12-04 10:13:25 -0500595 gpio_free(CFG_PCIE_IMX_PERST_GPIO);
Marek Vasutd9056c22014-02-03 21:46:22 +0100596#else
Tim Harvey7367b392021-07-06 10:19:09 -0700597 if (dm_gpio_is_valid(gpio)) {
598 /* Assert PERST# for 20ms then de-assert */
599 dm_gpio_set_value(gpio, active_high ? 0 : 1);
600 mdelay(20);
601 dm_gpio_set_value(gpio, active_high ? 1 : 0);
602 mdelay(20);
603 } else {
604 puts("WARNING: Make sure the PCIe #PERST line is connected!\n");
605 }
Marek Vasutd9056c22014-02-03 21:46:22 +0100606#endif
607 return 0;
608}
609
Tim Harvey7367b392021-07-06 10:19:09 -0700610static int imx6_pcie_deassert_core_reset(struct imx_pcie_priv *priv)
Marek Vasut988ee702013-12-14 05:55:28 +0100611{
612 struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
613
Tim Harvey541e2732022-04-13 15:54:37 -0700614 imx6_pcie_toggle_power(priv->vpcie);
Marek Vasut988ee702013-12-14 05:55:28 +0100615
Marek Vasut988ee702013-12-14 05:55:28 +0100616 enable_pcie_clock();
617
Fabio Estevamb5272bd2015-10-13 11:01:27 -0300618 if (is_mx6dqp())
619 clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_PCIE_SW_RST);
620
Marek Vasut988ee702013-12-14 05:55:28 +0100621 /*
622 * Wait for the clock to settle a bit, when the clock are sourced
Fabio Estevam1d0b7e32015-09-10 20:45:25 -0300623 * from the CPU, we need about 30 ms to settle.
Marek Vasut988ee702013-12-14 05:55:28 +0100624 */
Marek Vasutd9056c22014-02-03 21:46:22 +0100625 mdelay(50);
Marek Vasut988ee702013-12-14 05:55:28 +0100626
Fabio Estevam211a4902014-08-25 14:26:45 -0300627#if defined(CONFIG_MX6SX)
628 /* SSP_EN is not used on MX6SX anymore */
629 clrbits_le32(&iomuxc_regs->gpr[12], IOMUXC_GPR12_TEST_POWERDOWN);
630 /* Clear PCIe PHY reset bit */
631 clrbits_le32(&iomuxc_regs->gpr[5], IOMUXC_GPR5_PCIE_BTNRST);
632#else
Tim Harveyd53204a2014-08-07 22:57:29 -0700633 /* Enable PCIe */
634 clrbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_TEST_POWERDOWN);
635 setbits_le32(&iomuxc_regs->gpr[1], IOMUXC_GPR1_REF_SSP_EN);
Fabio Estevam211a4902014-08-25 14:26:45 -0300636#endif
Tim Harveyd53204a2014-08-07 22:57:29 -0700637
Tim Harvey7367b392021-07-06 10:19:09 -0700638 imx6_pcie_toggle_reset(&priv->reset_gpio, priv->reset_active_high);
Marek Vasut988ee702013-12-14 05:55:28 +0100639
640 return 0;
641}
642
Marek Vasut120efeb2019-06-09 03:50:54 +0200643static int imx_pcie_link_up(struct imx_pcie_priv *priv)
Marek Vasut988ee702013-12-14 05:55:28 +0100644{
645 struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
646 uint32_t tmp;
647 int count = 0;
648
Marek Vasut120efeb2019-06-09 03:50:54 +0200649 imx6_pcie_assert_core_reset(priv, false);
Marek Vasut988ee702013-12-14 05:55:28 +0100650 imx6_pcie_init_phy();
Tim Harvey7367b392021-07-06 10:19:09 -0700651 imx6_pcie_deassert_core_reset(priv);
Marek Vasut988ee702013-12-14 05:55:28 +0100652
Marek Vasut120efeb2019-06-09 03:50:54 +0200653 imx_pcie_regions_setup(priv);
Marek Vasut988ee702013-12-14 05:55:28 +0100654
655 /*
Koen Vandeputte6be35052018-01-04 14:54:34 +0100656 * By default, the subordinate is set equally to the secondary
657 * bus (0x01) when the RC boots.
658 * This means that theoretically, only bus 1 is reachable from the RC.
659 * Force the PCIe RC subordinate to 0xff, otherwise no downstream
660 * devices will be detected if the enumeration is applied strictly.
661 */
Marek Vasut6ce573f2019-06-09 03:50:52 +0200662 tmp = readl(priv->dbi_base + 0x18);
Koen Vandeputte6be35052018-01-04 14:54:34 +0100663 tmp |= (0xff << 16);
Marek Vasut6ce573f2019-06-09 03:50:52 +0200664 writel(tmp, priv->dbi_base + 0x18);
Koen Vandeputte6be35052018-01-04 14:54:34 +0100665
666 /*
Marek Vasut988ee702013-12-14 05:55:28 +0100667 * FIXME: Force the PCIe RC to Gen1 operation
668 * The RC must be forced into Gen1 mode before bringing the link
669 * up, otherwise no downstream devices are detected. After the
670 * link is up, a managed Gen1->Gen2 transition can be initiated.
671 */
Marek Vasut6ce573f2019-06-09 03:50:52 +0200672 tmp = readl(priv->dbi_base + 0x7c);
Marek Vasut988ee702013-12-14 05:55:28 +0100673 tmp &= ~0xf;
674 tmp |= 0x1;
Marek Vasut6ce573f2019-06-09 03:50:52 +0200675 writel(tmp, priv->dbi_base + 0x7c);
Marek Vasut988ee702013-12-14 05:55:28 +0100676
677 /* LTSSM enable, starting link. */
678 setbits_le32(&iomuxc_regs->gpr[12], IOMUXC_GPR12_APPS_LTSSM_ENABLE);
679
Marek Vasut120efeb2019-06-09 03:50:54 +0200680 while (!imx6_pcie_link_up(priv)) {
Marek Vasut988ee702013-12-14 05:55:28 +0100681 udelay(10);
682 count++;
Stefano Babicd1457922016-06-06 11:14:19 +0200683 if (count >= 4000) {
Tim Harveyc3260002015-05-08 15:17:10 -0700684#ifdef CONFIG_PCI_SCAN_SHOW
685 puts("PCI: pcie phy link never came up\n");
686#endif
Marek Vasut988ee702013-12-14 05:55:28 +0100687 debug("DEBUG_R0: 0x%08x, DEBUG_R1: 0x%08x\n",
Marek Vasut6ce573f2019-06-09 03:50:52 +0200688 readl(priv->dbi_base + PCIE_PHY_DEBUG_R0),
689 readl(priv->dbi_base + PCIE_PHY_DEBUG_R1));
Marek Vasut988ee702013-12-14 05:55:28 +0100690 return -EINVAL;
691 }
692 }
693
694 return 0;
695}
696
Simon Glass2a311e82020-01-27 08:49:37 -0700697static int imx_pcie_dm_read_config(const struct udevice *dev, pci_dev_t bdf,
Marek Vasut3c9f33e2019-06-09 03:50:55 +0200698 uint offset, ulong *value,
699 enum pci_size_t size)
700{
701 struct imx_pcie_priv *priv = dev_get_priv(dev);
702 u32 tmpval;
703 int ret;
704
705 ret = imx_pcie_read_cfg(priv, bdf, offset, &tmpval);
706 if (ret)
707 return ret;
708
709 *value = pci_conv_32_to_size(tmpval, offset, size);
710 return 0;
711}
712
713static int imx_pcie_dm_write_config(struct udevice *dev, pci_dev_t bdf,
714 uint offset, ulong value,
715 enum pci_size_t size)
716{
717 struct imx_pcie_priv *priv = dev_get_priv(dev);
718 u32 tmpval, newval;
719 int ret;
720
721 ret = imx_pcie_read_cfg(priv, bdf, offset, &tmpval);
722 if (ret)
723 return ret;
724
725 newval = pci_conv_size_to_32(tmpval, value, offset, size);
726 return imx_pcie_write_cfg(priv, bdf, offset, newval);
727}
728
729static int imx_pcie_dm_probe(struct udevice *dev)
730{
731 struct imx_pcie_priv *priv = dev_get_priv(dev);
732
Tim Harvey541e2732022-04-13 15:54:37 -0700733#if CONFIG_IS_ENABLED(DM_REGULATOR)
734 device_get_supply_regulator(dev, "vpcie-supply", &priv->vpcie);
735#endif
736
Tim Harvey7367b392021-07-06 10:19:09 -0700737 /* if PERST# valid from dt then assert it */
738 gpio_request_by_name(dev, "reset-gpio", 0, &priv->reset_gpio,
739 GPIOD_IS_OUT);
740 priv->reset_active_high = dev_read_bool(dev, "reset-gpio-active-high");
741 if (dm_gpio_is_valid(&priv->reset_gpio)) {
742 dm_gpio_set_value(&priv->reset_gpio,
743 priv->reset_active_high ? 0 : 1);
744 }
745
Marek Vasut3c9f33e2019-06-09 03:50:55 +0200746 return imx_pcie_link_up(priv);
747}
748
749static int imx_pcie_dm_remove(struct udevice *dev)
750{
751 struct imx_pcie_priv *priv = dev_get_priv(dev);
752
753 imx6_pcie_assert_core_reset(priv, true);
754
755 return 0;
756}
757
Simon Glassaad29ae2020-12-03 16:55:21 -0700758static int imx_pcie_of_to_plat(struct udevice *dev)
Marek Vasut3c9f33e2019-06-09 03:50:55 +0200759{
760 struct imx_pcie_priv *priv = dev_get_priv(dev);
761
Johan Jonkerb52189e2023-03-13 01:32:31 +0100762 priv->dbi_base = devfdt_get_addr_index_ptr(dev, 0);
763 priv->cfg_base = devfdt_get_addr_index_ptr(dev, 1);
Marek Vasut3c9f33e2019-06-09 03:50:55 +0200764 if (!priv->dbi_base || !priv->cfg_base)
765 return -EINVAL;
766
767 return 0;
768}
769
770static const struct dm_pci_ops imx_pcie_ops = {
771 .read_config = imx_pcie_dm_read_config,
772 .write_config = imx_pcie_dm_write_config,
773};
774
775static const struct udevice_id imx_pcie_ids[] = {
776 { .compatible = "fsl,imx6q-pcie" },
Marek Vasutbec7be12019-11-26 09:33:29 +0100777 { .compatible = "fsl,imx6sx-pcie" },
Marek Vasut3c9f33e2019-06-09 03:50:55 +0200778 { }
779};
780
781U_BOOT_DRIVER(imx_pcie) = {
782 .name = "imx_pcie",
783 .id = UCLASS_PCI,
784 .of_match = imx_pcie_ids,
785 .ops = &imx_pcie_ops,
786 .probe = imx_pcie_dm_probe,
787 .remove = imx_pcie_dm_remove,
Simon Glassaad29ae2020-12-03 16:55:21 -0700788 .of_to_plat = imx_pcie_of_to_plat,
Simon Glass8a2b47f2020-12-03 16:55:17 -0700789 .priv_auto = sizeof(struct imx_pcie_priv),
Marek Vasut3c9f33e2019-06-09 03:50:55 +0200790 .flags = DM_FLAG_OS_PREPARE,
791};