lantiq: add v3.9 support
[openwrt/svn-archive/archive.git] / target / linux / lantiq / patches-3.9 / 0011-MIPS-lantiq-add-pcie-driver.patch
1 From 7bd0d6e0f0aaa06267989b0d0d51f9d2aff25814 Mon Sep 17 00:00:00 2001
2 From: John Crispin <blogic@openwrt.org>
3 Date: Wed, 13 Mar 2013 09:39:02 +0100
4 Subject: [PATCH 11/22] MIPS: lantiq: add pcie driver
5
6 ---
7 arch/mips/lantiq/Kconfig | 10 +
8 arch/mips/lantiq/xway/sysctrl.c | 2 +
9 arch/mips/pci/Makefile | 2 +
10 arch/mips/pci/fixup-lantiq-pcie.c | 82 ++
11 arch/mips/pci/fixup-lantiq.c | 3 +
12 arch/mips/pci/ifxmips_pci_common.h | 57 ++
13 arch/mips/pci/ifxmips_pcie.c | 1607 ++++++++++++++++++++++++++++++++++++
14 arch/mips/pci/ifxmips_pcie.h | 135 +++
15 arch/mips/pci/ifxmips_pcie_ar10.h | 290 +++++++
16 arch/mips/pci/ifxmips_pcie_msi.c | 392 +++++++++
17 arch/mips/pci/ifxmips_pcie_phy.c | 478 +++++++++++
18 arch/mips/pci/ifxmips_pcie_pm.c | 176 ++++
19 arch/mips/pci/ifxmips_pcie_pm.h | 36 +
20 arch/mips/pci/ifxmips_pcie_reg.h | 1001 ++++++++++++++++++++++
21 arch/mips/pci/ifxmips_pcie_vr9.h | 271 ++++++
22 arch/mips/pci/pci.c | 25 +
23 drivers/pci/pcie/aer/Kconfig | 2 +-
24 include/linux/pci.h | 2 +
25 include/linux/pci_ids.h | 6 +
26 19 files changed, 4576 insertions(+), 1 deletion(-)
27 create mode 100644 arch/mips/pci/fixup-lantiq-pcie.c
28 create mode 100644 arch/mips/pci/ifxmips_pci_common.h
29 create mode 100644 arch/mips/pci/ifxmips_pcie.c
30 create mode 100644 arch/mips/pci/ifxmips_pcie.h
31 create mode 100644 arch/mips/pci/ifxmips_pcie_ar10.h
32 create mode 100644 arch/mips/pci/ifxmips_pcie_msi.c
33 create mode 100644 arch/mips/pci/ifxmips_pcie_phy.c
34 create mode 100644 arch/mips/pci/ifxmips_pcie_pm.c
35 create mode 100644 arch/mips/pci/ifxmips_pcie_pm.h
36 create mode 100644 arch/mips/pci/ifxmips_pcie_reg.h
37 create mode 100644 arch/mips/pci/ifxmips_pcie_vr9.h
38
39 diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig
40 index 675310a..4c9a241 100644
41 --- a/arch/mips/lantiq/Kconfig
42 +++ b/arch/mips/lantiq/Kconfig
43 @@ -18,6 +18,7 @@ config SOC_XWAY
44 bool "XWAY"
45 select SOC_TYPE_XWAY
46 select HW_HAS_PCI
47 + select ARCH_SUPPORTS_MSI
48
49 config SOC_FALCON
50 bool "FALCON"
51 @@ -37,6 +38,15 @@ config PCI_LANTIQ
52 bool "PCI Support"
53 depends on SOC_XWAY && PCI
54
55 +config PCIE_LANTIQ
56 + bool "PCIE Support"
57 + depends on SOC_XWAY && PCI
58 +
59 +config PCIE_LANTIQ_MSI
60 + bool
61 + depends on PCIE_LANTIQ && PCI_MSI
62 + default y
63 +
64 config XRX200_PHY_FW
65 bool "XRX200 PHY firmware loader"
66 depends on SOC_XWAY
67 diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
68 index c24924f..e30dde8 100644
69 --- a/arch/mips/lantiq/xway/sysctrl.c
70 +++ b/arch/mips/lantiq/xway/sysctrl.c
71 @@ -377,6 +377,8 @@ void __init ltq_soc_init(void)
72 PMU_PPE_EMA | PMU_PPE_TC | PMU_PPE_SLL01 |
73 PMU_PPE_QSB | PMU_PPE_TOP);
74 clkdev_add_pmu("1f203000.rcu", "gphy", 0, PMU_GPHY);
75 + pmu_w32(~0, PMU_PWDSR1);
76 + pmu_w32(pmu_r32(PMU_PWDSR) & ~PMU_PCIE_CLK, PMU_PWDSR);
77 } else if (of_machine_is_compatible("lantiq,ar9")) {
78 clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(),
79 ltq_ar9_fpi_hz(), CLOCK_250M);
80 diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
81 index 2cb1d31..8ba7fff 100644
82 --- a/arch/mips/pci/Makefile
83 +++ b/arch/mips/pci/Makefile
84 @@ -41,6 +41,8 @@ obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o
85 obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o
86 obj-$(CONFIG_LANTIQ) += fixup-lantiq.o
87 obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o
88 +obj-$(CONFIG_PCIE_LANTIQ) += ifxmips_pcie_phy.o ifxmips_pcie.o fixup-lantiq-pcie.o
89 +obj-$(CONFIG_PCIE_LANTIQ_MSI) += pcie-lantiq-msi.o
90 obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o
91 obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o
92 obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o
93 diff --git a/arch/mips/pci/fixup-lantiq-pcie.c b/arch/mips/pci/fixup-lantiq-pcie.c
94 new file mode 100644
95 index 0000000..50a1c3b
96 --- /dev/null
97 +++ b/arch/mips/pci/fixup-lantiq-pcie.c
98 @@ -0,0 +1,82 @@
99 +/******************************************************************************
100 +**
101 +** FILE NAME : ifxmips_fixup_pcie.c
102 +** PROJECT : IFX UEIP for VRX200
103 +** MODULES : PCIe
104 +**
105 +** DATE : 02 Mar 2009
106 +** AUTHOR : Lei Chuanhua
107 +** DESCRIPTION : PCIe Root Complex Driver
108 +** COPYRIGHT : Copyright (c) 2009
109 +** Infineon Technologies AG
110 +** Am Campeon 1-12, 85579 Neubiberg, Germany
111 +**
112 +** This program is free software; you can redistribute it and/or modify
113 +** it under the terms of the GNU General Public License as published by
114 +** the Free Software Foundation; either version 2 of the License, or
115 +** (at your option) any later version.
116 +** HISTORY
117 +** $Version $Date $Author $Comment
118 +** 0.0.1 17 Mar,2009 Lei Chuanhua Initial version
119 +*******************************************************************************/
120 +/*!
121 + \file ifxmips_fixup_pcie.c
122 + \ingroup IFX_PCIE
123 + \brief PCIe Fixup functions source file
124 +*/
125 +#include <linux/pci.h>
126 +#include <linux/pci_regs.h>
127 +#include <linux/pci_ids.h>
128 +
129 +#include <lantiq_soc.h>
130 +
131 +#include "pcie-lantiq.h"
132 +
133 +#define PCI_VENDOR_ID_INFINEON 0x15D1
134 +#define PCI_DEVICE_ID_INFINEON_DANUBE 0x000F
135 +#define PCI_DEVICE_ID_INFINEON_PCIE 0x0011
136 +#define PCI_VENDOR_ID_LANTIQ 0x1BEF
137 +#define PCI_DEVICE_ID_LANTIQ_PCIE 0x0011
138 +
139 +
140 +
141 +static void __devinit
142 +ifx_pcie_fixup_resource(struct pci_dev *dev)
143 +{
144 + u32 reg;
145 +
146 + IFX_PCIE_PRINT(PCIE_MSG_FIXUP, "%s dev %s: enter\n", __func__, pci_name(dev));
147 +
148 + printk("%s: fixup host controller %s (%04x:%04x)\n",
149 + __func__, pci_name(dev), dev->vendor, dev->device);
150 +
151 + /* Setup COMMAND register */
152 + reg = PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER /* |
153 + PCI_COMMAND_INTX_DISABLE */| PCI_COMMAND_SERR;
154 + pci_write_config_word(dev, PCI_COMMAND, reg);
155 + IFX_PCIE_PRINT(PCIE_MSG_FIXUP, "%s dev %s: exit\n", __func__, pci_name(dev));
156 +}
157 +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INFINEON, PCI_DEVICE_ID_INFINEON_PCIE, ifx_pcie_fixup_resource);
158 +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LANTIQ, PCI_VENDOR_ID_LANTIQ, ifx_pcie_fixup_resource);
159 +
160 +static void __devinit
161 +ifx_pcie_rc_class_early_fixup(struct pci_dev *dev)
162 +{
163 + IFX_PCIE_PRINT(PCIE_MSG_FIXUP, "%s dev %s: enter\n", __func__, pci_name(dev));
164 +
165 + if (dev->devfn == PCI_DEVFN(0, 0) &&
166 + (dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) {
167 +
168 + dev->class = (PCI_CLASS_BRIDGE_PCI << 8) | (dev->class & 0xff);
169 +
170 + printk(KERN_INFO "%s: fixed pcie host bridge to pci-pci bridge\n", __func__);
171 + }
172 + IFX_PCIE_PRINT(PCIE_MSG_FIXUP, "%s dev %s: exit\n", __func__, pci_name(dev));
173 + mdelay(10);
174 +}
175 +
176 +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INFINEON, PCI_DEVICE_ID_INFINEON_PCIE,
177 + ifx_pcie_rc_class_early_fixup);
178 +
179 +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LANTIQ, PCI_DEVICE_ID_LANTIQ_PCIE,
180 + ifx_pcie_rc_class_early_fixup);
181 diff --git a/arch/mips/pci/fixup-lantiq.c b/arch/mips/pci/fixup-lantiq.c
182 index 6c829df..cf5c4e0 100644
183 --- a/arch/mips/pci/fixup-lantiq.c
184 +++ b/arch/mips/pci/fixup-lantiq.c
185 @@ -11,6 +11,7 @@
186
187 int (*ltq_pci_plat_arch_init)(struct pci_dev *dev) = NULL;
188 int (*ltq_pci_plat_dev_init)(struct pci_dev *dev) = NULL;
189 +int (*ltq_pci_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin);
190
191 int pcibios_plat_dev_init(struct pci_dev *dev)
192 {
193 @@ -28,6 +29,8 @@ int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
194 struct of_irq dev_irq;
195 int irq;
196
197 + if (ltq_pci_map_irq)
198 + return ltq_pci_map_irq(dev, slot, pin);
199 if (of_irq_map_pci(dev, &dev_irq)) {
200 dev_err(&dev->dev, "trying to map irq for unknown slot:%d pin:%d\n",
201 slot, pin);
202 diff --git a/arch/mips/pci/ifxmips_pci_common.h b/arch/mips/pci/ifxmips_pci_common.h
203 new file mode 100644
204 index 0000000..46f4cb2
205 --- /dev/null
206 +++ b/arch/mips/pci/ifxmips_pci_common.h
207 @@ -0,0 +1,57 @@
208 +/******************************************************************************
209 +**
210 +** FILE NAME : ifxmips_pci_common.h
211 +** PROJECT : IFX UEIP
212 +** MODULES : PCI subsystem
213 +**
214 +** DATE : 30 June 2009
215 +** AUTHOR : Lei Chuanhua
216 +** DESCRIPTION : PCIe Root Complex Driver
217 +** COPYRIGHT : Copyright (c) 2009
218 +** Infineon Technologies AG
219 +** Am Campeon 1-12, 85579 Neubiberg, Germany
220 +**
221 +** This program is free software; you can redistribute it and/or modify
222 +** it under the terms of the GNU General Public License as published by
223 +** the Free Software Foundation; either version 2 of the License, or
224 +** (at your option) any later version.
225 +** HISTORY
226 +** $Version $Date $Author $Comment
227 +** 0.0.1 30 June,2009 Lei Chuanhua Initial version
228 +*******************************************************************************/
229 +
230 +#ifndef IFXMIPS_PCI_COMMON_H
231 +#define IFXMIPS_PCI_COMMON_H
232 +#include <linux/version.h>
233 +/*!
234 + \defgroup IFX_PCI_COM IFX PCI/PCIe common parts for OS integration
235 + \brief PCI/PCIe common parts
236 +*/
237 +
238 +/*!
239 + \defgroup IFX_PCI_COM_OS OS APIs
240 + \ingroup IFX_PCI_COM
241 + \brief PCI/PCIe bus driver OS interface functions
242 +*/
243 +/*!
244 + \file ifxmips_pci_common.h
245 + \ingroup IFX_PCI_COM
246 + \brief PCI/PCIe bus driver common OS header file
247 +*/
248 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24)
249 +#define IFX_PCI_CONST
250 +#else
251 +#define IFX_PCI_CONST const
252 +#endif
253 +#ifdef CONFIG_IFX_PCI
254 +extern int ifx_pci_bios_map_irq(IFX_PCI_CONST struct pci_dev *dev, u8 slot, u8 pin);
255 +extern int ifx_pci_bios_plat_dev_init(struct pci_dev *dev);
256 +#endif /* COFNIG_IFX_PCI */
257 +
258 +#ifdef CONFIG_IFX_PCIE
259 +extern int ifx_pcie_bios_map_irq(IFX_PCI_CONST struct pci_dev *dev, u8 slot, u8 pin);
260 +extern int ifx_pcie_bios_plat_dev_init(struct pci_dev *dev);
261 +#endif
262 +
263 +#endif /* IFXMIPS_PCI_COMMON_H */
264 +
265 diff --git a/arch/mips/pci/ifxmips_pcie.c b/arch/mips/pci/ifxmips_pcie.c
266 new file mode 100644
267 index 0000000..5cebfe6
268 --- /dev/null
269 +++ b/arch/mips/pci/ifxmips_pcie.c
270 @@ -0,0 +1,1607 @@
271 +/******************************************************************************
272 +**
273 +** FILE NAME : ifxmips_pcie.c
274 +** PROJECT : IFX UEIP for VRX200
275 +** MODULES : PCI MSI sub module
276 +**
277 +** DATE : 02 Mar 2009
278 +** AUTHOR : Lei Chuanhua
279 +** DESCRIPTION : PCIe Root Complex Driver
280 +** COPYRIGHT : Copyright (c) 2009
281 +** Infineon Technologies AG
282 +** Am Campeon 1-12, 85579 Neubiberg, Germany
283 +**
284 +** This program is free software; you can redistribute it and/or modify
285 +** it under the terms of the GNU General Public License as published by
286 +** the Free Software Foundation; either version 2 of the License, or
287 +** (at your option) any later version.
288 +** HISTORY
289 +** $Version $Date $Author $Comment
290 +** 0.0.1 02 Mar,2009 Lei Chuanhua Initial version
291 +*******************************************************************************/
292 + /*!
293 + \file ifxmips_pcie.c
294 + \ingroup IFX_PCIE
295 + \brief PCI express bus driver source file
296 +*/
297 +#include <linux/types.h>
298 +#include <linux/pci.h>
299 +#include <linux/kernel.h>
300 +#include <linux/init.h>
301 +#include <linux/delay.h>
302 +#include <linux/mm.h>
303 +#include <asm/paccess.h>
304 +#include <linux/pci.h>
305 +#include <linux/pci_regs.h>
306 +#include <linux/module.h>
307 +
308 +#include "ifxmips_pcie.h"
309 +#include "ifxmips_pcie_reg.h"
310 +
311 +#define IFX_PCIE_VER_MAJOR 1
312 +#define IFX_PCIE_VER_MID 5
313 +#define IFX_PCIE_VER_MINOR 3
314 +
315 +/* Enable 32bit io due to its mem mapped io nature */
316 +#define IFX_PCIE_ERROR_INT
317 +#define CONFIG_IFX_PCIE_1ST_CORE
318 +#define IFX_PCIE_IO_32BIT
319 +
320 +#define IFX_PCIE_IR (INT_NUM_IM4_IRL0 + 25)
321 +#define IFX_PCIE_INTA (INT_NUM_IM4_IRL0 + 8)
322 +#define IFX_PCIE_INTB (INT_NUM_IM4_IRL0 + 9)
323 +#define IFX_PCIE_INTC (INT_NUM_IM4_IRL0 + 10)
324 +#define IFX_PCIE_INTD (INT_NUM_IM4_IRL0 + 11)
325 +#define MS(_v, _f) (((_v) & (_f)) >> _f##_S)
326 +#define SM(_v, _f) (((_v) << _f##_S) & (_f))
327 +#define IFX_REG_SET_BIT(_f, _r) \
328 + IFX_REG_W32((IFX_REG_R32((_r)) &~ (_f)) | (_f), (_r))
329 +
330 +static DEFINE_SPINLOCK(ifx_pcie_lock);
331 +
332 +u32 g_pcie_debug_flag = PCIE_MSG_ANY & (~PCIE_MSG_CFG);
333 +
334 +static ifx_pcie_irq_t pcie_irqs[IFX_PCIE_CORE_NR] = {
335 + {
336 + .ir_irq = {
337 + .irq = IFX_PCIE_IR,
338 + .name = "ifx_pcie_rc0",
339 + },
340 +
341 + .legacy_irq = {
342 + {
343 + .irq_bit = PCIE_IRN_INTA,
344 + .irq = IFX_PCIE_INTA,
345 + },
346 + {
347 + .irq_bit = PCIE_IRN_INTB,
348 + .irq = IFX_PCIE_INTB,
349 + },
350 + {
351 + .irq_bit = PCIE_IRN_INTC,
352 + .irq = IFX_PCIE_INTC,
353 + },
354 + {
355 + .irq_bit = PCIE_IRN_INTD,
356 + .irq = IFX_PCIE_INTD,
357 + },
358 + },
359 + },
360 +
361 +#ifdef CONFIG_IFX_PCIE_2ND_CORE
362 + {
363 + .ir_irq = {
364 + .irq = IFX_PCIE1_IR,
365 + .name = "ifx_pcie_rc1",
366 + },
367 +
368 + .legacy_irq = {
369 + {
370 + .irq_bit = PCIE_IRN_INTA,
371 + .irq = IFX_PCIE1_INTA,
372 + },
373 + {
374 + .irq_bit = PCIE_IRN_INTB,
375 + .irq = IFX_PCIE1_INTB,
376 + },
377 + {
378 + .irq_bit = PCIE_IRN_INTC,
379 + .irq = IFX_PCIE1_INTC,
380 + },
381 + {
382 + .irq_bit = PCIE_IRN_INTD,
383 + .irq = IFX_PCIE1_INTD,
384 + },
385 + },
386 +
387 + },
388 +#endif /* CONFIG_IFX_PCIE_2ND_CORE */
389 +};
390 +
391 +void
392 +ifx_pcie_debug(const char *fmt, ...)
393 +{
394 + static char buf[256] = {0}; /* XXX */
395 + va_list ap;
396 +
397 + va_start(ap, fmt);
398 + vsnprintf(buf, sizeof(buf), fmt, ap);
399 + va_end(ap);
400 +
401 + printk("%s", buf);
402 +}
403 +
404 +#ifdef IFX_PCI_PHY_DBG
405 +/* Generate hot reset, XXX must catpure to verify */
406 +static INLINE void
407 +pcie_secondary_bus_reset(int pcie_port)
408 +{
409 + int i;
410 + u32 reg;
411 +#define IFX_PCIE_RESET_TIME 20
412 +
413 + /* Assert Secondary Bus Reset */
414 + reg = IFX_REG_R32(PCIE_INTRBCTRL(pcie_port));
415 + reg |= PCIE_INTRBCTRL_RST_SECONDARY_BUS;
416 + IFX_REG_W32(reg, PCIE_INTRBCTRL(pcie_port));
417 +
418 + /* De-assert Secondary Bus Reset */
419 + reg &= ~PCIE_INTRBCTRL_RST_SECONDARY_BUS;
420 + IFX_REG_W32(reg, PCIE_INTRBCTRL(pcie_port));
421 +
422 + /* XXX, wait at least 100 ms, then restore again */
423 + for (i = 0; i < IFX_PCIE_RESET_TIME; i++) {
424 + mdelay(10);
425 + }
426 +#undef IFX_PCIE_RESET_TIME
427 +}
428 +
429 +/* Error or L0s to L0 */
430 +static INLINE int
431 +pcie_retrain_link(int pcie_port)
432 +{
433 + int i;
434 + u32 reg;
435 +#define IFX_PCIE_RETRAIN_TIME 1000
436 +
437 + reg = IFX_REG_R32(PCIE_LCTLSTS(pcie_port));
438 + reg |= PCIE_LCTLSTS_RETRIAN_LINK;
439 + IFX_REG_W32(reg, PCIE_LCTLSTS(pcie_port));
440 +
441 + /* Wait for the link to come up */
442 + for (i = 0; i < IFX_PCIE_RETRAIN_TIME; i++) {
443 + if (!(IFX_REG_R32(PCIE_LCTLSTS(pcie_port)) & PCIE_LCTLSTS_RETRAIN_PENDING)) {
444 + break;
445 + }
446 + udelay(100);
447 + }
448 + if (i >= IFX_PCIE_RETRAIN_TIME) {
449 + IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s retrain timeout\n", __func__);
450 + return -1;
451 + }
452 + return 0;
453 +#undef IFX_PCIE_RETRAIN_TIME
454 +}
455 +
456 +static INLINE void
457 +pcie_disable_scrambling(int pcie_port)
458 +{
459 + u32 reg;
460 +
461 + reg = IFX_REG_R32(PCIE_PLCR(pcie_port));
462 + reg |= PCIE_PLCR_SCRAMBLE_DISABLE;
463 + IFX_REG_W32(reg, PCIE_PLCR(pcie_port));
464 +}
465 +#endif /* IFX_PCI_PHY_DBG */
466 +
467 +static INLINE int
468 +pcie_ltssm_enable(int pcie_port)
469 +{
470 + int i;
471 +#define IFX_PCIE_LTSSM_ENABLE_TIMEOUT 10
472 +
473 + IFX_REG_W32(PCIE_RC_CCR_LTSSM_ENABLE, PCIE_RC_CCR(pcie_port)); /* Enable LTSSM */
474 +
475 + /* Wait for the link to come up */
476 + for (i = 0; i < IFX_PCIE_LTSSM_ENABLE_TIMEOUT; i++) {
477 + if (!(IFX_REG_R32(PCIE_LCTLSTS(pcie_port)) & PCIE_LCTLSTS_RETRAIN_PENDING)) {
478 + break;
479 + }
480 + udelay(10);
481 + }
482 + if (i >= IFX_PCIE_LTSSM_ENABLE_TIMEOUT) {
483 + IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s link timeout!!!!!\n", __func__);
484 + return -1;
485 + }
486 + return 0;
487 +#undef IFX_PCIE_LTSSM_ENABLE_TIMEOUT
488 +}
489 +
490 +static INLINE void
491 +pcie_ltssm_disable(int pcie_port)
492 +{
493 + IFX_REG_W32(0, PCIE_RC_CCR(pcie_port)); /* Disable LTSSM */
494 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_RC_CCR 0x%08x\n",
495 + __func__, IFX_REG_R32(PCIE_RC_CCR(pcie_port)));
496 +}
497 +
498 +static INLINE void
499 +pcie_ahb_bus_error_suppress(int pcie_port)
500 +{
501 + IFX_REG_W32(PCIE_AHB_CTRL_BUS_ERROR_SUPPRESS, PCIE_AHB_CTRL(pcie_port));
502 +}
503 +
504 +static INLINE void
505 +pcie_status_register_clear(int pcie_port)
506 +{
507 + /* Clear the status register, XXX, seperate function */
508 + IFX_REG_W32(0, PCIE_RC_DR(pcie_port));
509 + IFX_REG_W32(0, PCIE_PCICMDSTS(pcie_port));
510 + IFX_REG_W32(0, PCIE_DCTLSTS(pcie_port));
511 + IFX_REG_W32(0, PCIE_LCTLSTS(pcie_port));
512 + IFX_REG_W32(0, PCIE_SLCTLSTS(pcie_port));
513 + IFX_REG_W32(0, PCIE_RSTS(pcie_port));
514 + IFX_REG_W32(0, PCIE_UES_R(pcie_port));
515 + IFX_REG_W32(0, PCIE_UEMR(pcie_port));
516 + IFX_REG_W32(0, PCIE_UESR(pcie_port));
517 + IFX_REG_W32(0, PCIE_CESR(pcie_port));
518 + IFX_REG_W32(0, PCIE_CEMR(pcie_port));
519 + IFX_REG_W32(0, PCIE_RESR(pcie_port));
520 + IFX_REG_W32(0, PCIE_PVCCRSR(pcie_port));
521 + IFX_REG_W32(0, PCIE_VC0_RSR0(pcie_port));
522 + IFX_REG_W32(0, PCIE_TPFCS(pcie_port));
523 + IFX_REG_W32(0, PCIE_TNPFCS(pcie_port));
524 + IFX_REG_W32(0, PCIE_TCFCS(pcie_port));
525 + IFX_REG_W32(0, PCIE_QSR(pcie_port));
526 + IFX_REG_W32(0, PCIE_IOBLSECS(pcie_port));
527 +}
528 +
529 +static inline int
530 +ifx_pcie_link_up(int pcie_port)
531 +{
532 + return (IFX_REG_R32(PCIE_PHY_SR(pcie_port)) & PCIE_PHY_SR_PHY_LINK_UP) ? 1 : 0;
533 +}
534 +
535 +#ifdef IFX_PCIE_DBG
536 +static void
537 +pcie_status_registers_dump(int pcie_port)
538 +{
539 + printk(KERN_INFO "PCIe_PCICMDSTS: 0x%08x\n", IFX_REG_R32(PCIE_PCICMDSTS(pcie_port)));
540 + printk(KERN_INFO "PCIe_RC_DR: 0x%08x\n", IFX_REG_R32(PCIE_RC_DR(pcie_port)));
541 + printk(KERN_INFO "PCIe_DCTLSTS: 0x%08x\n", IFX_REG_R32(PCIE_DCTLSTS(pcie_port)));
542 + printk(KERN_INFO "PCIe_LCTLSTS: 0x%08x\n", IFX_REG_R32(PCIE_LCTLSTS(pcie_port)));
543 + printk(KERN_INFO "PCIe_SLCTLSTS: 0x%08x\n", IFX_REG_R32(PCIE_SLCTLSTS(pcie_port)));
544 + printk(KERN_INFO "PCIe_RSTS: 0x%08x\n", IFX_REG_R32(PCIE_RSTS(pcie_port)));
545 + printk(KERN_INFO "PCIe_UES_R: 0x%08x\n", IFX_REG_R32(PCIE_UES_R(pcie_port)));
546 + printk(KERN_INFO "PCIe_UEMR: 0x%08x\n", IFX_REG_R32(PCIE_UEMR(pcie_port)));
547 + printk(KERN_INFO "PCIe_UESR: 0x%08x\n", IFX_REG_R32(PCIE_UESR(pcie_port)));
548 + printk(KERN_INFO "PCIe_CESR: 0x%08x\n", IFX_REG_R32(PCIE_CESR(pcie_port)));
549 + printk(KERN_INFO "PCIe_CEMR: 0x%08x\n", IFX_REG_R32(PCIE_CEMR(pcie_port)));
550 + printk(KERN_INFO "PCIe_RESR: 0x%08x\n", IFX_REG_R32(PCIE_RESR(pcie_port)));
551 + printk(KERN_INFO "PCIe_ESIR: 0x%08x\n", IFX_REG_R32(PCIE_ESIR(pcie_port)));
552 + printk(KERN_INFO "PCIe_PVCCRSR: 0x%08x\n", IFX_REG_R32(PCIE_PVCCRSR(pcie_port)));
553 + printk(KERN_INFO "PCIe_VC0_RSR0: 0x%08x\n", IFX_REG_R32(PCIE_VC0_RSR0(pcie_port)));
554 + printk(KERN_INFO "PCIe_TPFCS: 0x%08x\n", IFX_REG_R32(PCIE_TPFCS(pcie_port)));
555 + printk(KERN_INFO "PCIe_TNPFCS: 0x%08x\n", IFX_REG_R32(PCIE_TNPFCS(pcie_port)));
556 + printk(KERN_INFO "PCIe_TCFCS: 0x%08x\n", IFX_REG_R32(PCIE_TCFCS(pcie_port)));
557 + printk(KERN_INFO "PCIe_QSR: 0x%08x\n", IFX_REG_R32(PCIE_QSR(pcie_port)));
558 + printk(KERN_INFO "PCIe_VCTAR1: 0x%08x\n", IFX_REG_R32(PCIE_VCTAR1(pcie_port)));
559 + printk(KERN_INFO "PCIe_VCTAR2: 0x%08x\n", IFX_REG_R32(PCIE_VCTAR2(pcie_port)));
560 + printk(KERN_INFO "PCIe_IOBLSECS: 0x%08x\n", IFX_REG_R32(PCIE_IOBLSECS(pcie_port)));
561 + printk(KERN_INFO "PCIe_ALTRT: 0x%08x\n", IFX_REG_R32(PCIE_ALTRT(pcie_port)));
562 + printk(KERN_INFO "PCIe_SNR: 0x%08x\n", IFX_REG_R32(PCIE_SNR(pcie_port)));
563 + printk(KERN_INFO "PCIe_DBR0: 0x%08x\n", IFX_REG_R32(PCIE_DBR0(pcie_port)));
564 + printk(KERN_INFO "PCIe_DBR1: 0x%08x\n", IFX_REG_R32(PCIE_DBR1(pcie_port)));
565 +}
566 +
567 +static void
568 +pcie_post_dump(int pcie_port)
569 +{
570 + printk(KERN_INFO "PCIe_PCICMDSTS: 0x%08x\n", IFX_REG_R32(PCIE_PCICMDSTS(pcie_port)));
571 + printk(KERN_INFO "PCIe_MBML: 0x%08x\n", IFX_REG_R32(PCIE_MBML(pcie_port)));
572 + printk(KERN_INFO "PCIe_PBML: 0x%08x\n", IFX_REG_R32(PCIE_PMBL(pcie_port)));
573 + printk(KERN_INFO "PCIe_IOBLSECS: 0x%08x\n", IFX_REG_R32(PCIE_IOBLSECS(pcie_port)));
574 + printk(KERN_INFO "PCIe_IO_BANDL: 0x%08x\n", IFX_REG_R32(PCIE_IO_BANDL(pcie_port)));
575 + printk(KERN_INFO "PCIe_INTRBCTRL: 0x%08x\n", IFX_REG_R32(PCIE_INTRBCTRL(pcie_port)));
576 + printk(KERN_INFO "Power State: D%1d\n", IFX_REG_R32(PCIE_PM_CSR(pcie_port)) & PCIE_PM_CSR_POWER_STATE);
577 + printk(KERN_INFO "Negotiated Link Width: %d\n", MS(IFX_REG_R32(PCIE_LCTLSTS(pcie_port)), PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH));
578 + printk(KERN_INFO "Number of VCs: %d\n", IFX_REG_R32(PCIE_PVC1(pcie_port)) & PCIE_PVC1_EXT_VC_CNT);
579 + printk(KERN_INFO "Low-priority VCs: %d\n", MS(IFX_REG_R32(PCIE_PVC1(pcie_port)), PCIE_PVC1_LOW_PRI_EXT_VC_CNT));
580 + printk(KERN_INFO "VC Arbitration: 0x%08x\n", IFX_REG_R32(PCIE_PVC2(pcie_port)) & PCIE_PVC2_VC_ARB_WRR);
581 + printk(KERN_INFO "Port Arbitration: 0x%08x\n", IFX_REG_R32(PCIE_VC0_RC(pcie_port)) & PCIE_VC0_RC_PORT_ARB);
582 +
583 + if (ifx_pcie_link_up(pcie_port)) {
584 + printk(KERN_INFO "PCIe PHY Link is UP\n");
585 + }
586 + else {
587 + printk(KERN_INFO "PCIe PHY Link is DOWN!\n");
588 + }
589 + if ((IFX_REG_R32(PCIE_RC_DR(pcie_port)) & PCIE_RC_DR_DLL_UP)) {
590 + printk(KERN_INFO "PCIe DLL is UP\n");
591 + }
592 + else {
593 + printk(KERN_INFO "PCIe DLL is DOWN!\n");
594 + }
595 +
596 + if ((IFX_REG_R32(PCIE_LCTLSTS(pcie_port)) & PCIE_LCTLSTS_DLL_ACTIVE)) {
597 + printk(KERN_INFO "PCIE_LCTLSTS in DL_Active state!\n");
598 + }
599 + else {
600 + printk(KERN_INFO "PCIE_LCTLSTS NOT in DL_Active state!\n");
601 + }
602 + }
603 +#endif /* IFX_PCIE_DBG */
604 +
605 +/* XXX, this function is not needed in fact */
606 +static INLINE void
607 +pcie_mem_io_setup(int pcie_port)
608 +{
609 + u32 reg;
610 + /*
611 + * BAR[0:1] readonly register
612 + * RC contains only minimal BARs for packets mapped to this device
613 + * Mem/IO filters defines a range of memory occupied by memory mapped IO devices that
614 + * reside on the downstream side fo the bridge.
615 + */
616 + reg = SM((PCIE_MEM_PHY_PORT_TO_END(pcie_port) >> 20), PCIE_MBML_MEM_LIMIT_ADDR)
617 + | SM((PCIE_MEM_PHY_PORT_TO_BASE(pcie_port) >> 20), PCIE_MBML_MEM_BASE_ADDR);
618 +
619 + IFX_REG_W32(reg, PCIE_MBML(pcie_port));
620 +
621 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_MBML: 0x%08x\n",
622 + __func__, IFX_REG_R32(PCIE_MBML(pcie_port)));
623 +
624 +#ifdef IFX_PCIE_PREFETCH_MEM_64BIT
625 + reg = SM((PCIE_MEM_PHY_PORT_TO_END(pcie_port) >> 20), PCIE_PMBL_END_ADDR)
626 + | SM((PCIE_MEM_PHY_PORT_TO_BASE(pcie_port) >> 20), PCIE_PMBL_UPPER_12BIT)
627 + | PCIE_PMBL_64BIT_ADDR;
628 + IFX_REG_W32(reg, PCIE_PMBL(pcie_port));
629 +
630 + /* Must configure upper 32bit */
631 + IFX_REG_W32(0, PCIE_PMBU32(pcie_port));
632 + IFX_REG_W32(0, PCIE_PMLU32(pcie_port));
633 +#else
634 + /* PCIe_PBML, same as MBML */
635 + IFX_REG_W32(IFX_REG_R32(PCIE_MBML(pcie_port)), PCIE_PMBL(pcie_port));
636 +#endif
637 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_PMBL: 0x%08x\n",
638 + __func__, IFX_REG_R32(PCIE_PMBL(pcie_port)));
639 +
640 + /* IO Address Range */
641 + reg = SM((PCIE_IO_PHY_PORT_TO_END(pcie_port) >> 12), PCIE_IOBLSECS_IO_LIMIT_ADDR)
642 + | SM((PCIE_IO_PHY_PORT_TO_BASE(pcie_port) >> 12), PCIE_IOBLSECS_IO_BASE_ADDR);
643 +#ifdef IFX_PCIE_IO_32BIT
644 + reg |= PCIE_IOBLSECS_32BIT_IO_ADDR;
645 +#endif /* IFX_PCIE_IO_32BIT */
646 + IFX_REG_W32(reg, PCIE_IOBLSECS(pcie_port));
647 +
648 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_IOBLSECS: 0x%08x\n",
649 + __func__, IFX_REG_R32(PCIE_IOBLSECS(pcie_port)));
650 +#ifdef IFX_PCIE_IO_32BIT
651 + reg = SM((PCIE_IO_PHY_PORT_TO_END(pcie_port) >> 16), PCIE_IO_BANDL_UPPER_16BIT_IO_LIMIT)
652 + | SM((PCIE_IO_PHY_PORT_TO_BASE(pcie_port) >> 16), PCIE_IO_BANDL_UPPER_16BIT_IO_BASE);
653 + IFX_REG_W32(reg, PCIE_IO_BANDL(pcie_port));
654 +
655 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_IO_BANDL: 0x%08x\n",
656 + __func__, IFX_REG_R32(PCIE_IO_BANDL(pcie_port)));
657 +#endif /* IFX_PCIE_IO_32BIT */
658 +}
659 +
660 +static INLINE void
661 +pcie_msi_setup(int pcie_port)
662 +{
663 + u32 reg;
664 +
665 + /* XXX, MSI stuff should only apply to EP */
666 + /* MSI Capability: Only enable 32-bit addresses */
667 + reg = IFX_REG_R32(PCIE_MCAPR(pcie_port));
668 + reg &= ~PCIE_MCAPR_ADDR64_CAP;
669 +
670 + reg |= PCIE_MCAPR_MSI_ENABLE;
671 +
672 + /* Disable multiple message */
673 + reg &= ~(PCIE_MCAPR_MULTI_MSG_CAP | PCIE_MCAPR_MULTI_MSG_ENABLE);
674 + IFX_REG_W32(reg, PCIE_MCAPR(pcie_port));
675 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_MCAPR: 0x%08x\n",
676 + __func__, IFX_REG_R32(PCIE_MCAPR(pcie_port)));
677 +}
678 +
679 +static INLINE void
680 +pcie_pm_setup(int pcie_port)
681 +{
682 + u32 reg;
683 +
684 + /* Enable PME, Soft reset enabled */
685 + reg = IFX_REG_R32(PCIE_PM_CSR(pcie_port));
686 + reg |= PCIE_PM_CSR_PME_ENABLE | PCIE_PM_CSR_SW_RST;
687 + IFX_REG_W32(reg, PCIE_PM_CSR(pcie_port));
688 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_PM_CSR: 0x%08x\n",
689 + __func__, IFX_REG_R32(PCIE_PM_CSR(pcie_port)));
690 +}
691 +
692 +static INLINE void
693 +pcie_bus_setup(int pcie_port)
694 +{
695 + u32 reg;
696 +
697 + reg = SM(0, PCIE_BNR_PRIMARY_BUS_NUM) | SM(1, PCIE_PNR_SECONDARY_BUS_NUM) | SM(0xFF, PCIE_PNR_SUB_BUS_NUM);
698 + IFX_REG_W32(reg, PCIE_BNR(pcie_port));
699 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_BNR: 0x%08x\n",
700 + __func__, IFX_REG_R32(PCIE_BNR(pcie_port)));
701 +}
702 +
703 +static INLINE void
704 +pcie_device_setup(int pcie_port)
705 +{
706 + u32 reg;
707 +
708 + /* Device capability register, set up Maximum payload size */
709 + reg = IFX_REG_R32(PCIE_DCAP(pcie_port));
710 + reg |= PCIE_DCAP_ROLE_BASE_ERR_REPORT;
711 + reg |= SM(PCIE_MAX_PAYLOAD_128, PCIE_DCAP_MAX_PAYLOAD_SIZE);
712 +
713 + /* Only available for EP */
714 + reg &= ~(PCIE_DCAP_EP_L0S_LATENCY | PCIE_DCAP_EP_L1_LATENCY);
715 + IFX_REG_W32(reg, PCIE_DCAP(pcie_port));
716 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_DCAP: 0x%08x\n",
717 + __func__, IFX_REG_R32(PCIE_DCAP(pcie_port)));
718 +
719 + /* Device control and status register */
720 + /* Set Maximum Read Request size for the device as a Requestor */
721 + reg = IFX_REG_R32(PCIE_DCTLSTS(pcie_port));
722 +
723 + /*
724 + * Request size can be larger than the MPS used, but the completions returned
725 + * for the read will be bounded by the MPS size.
726 + * In our system, Max request size depends on AHB burst size. It is 64 bytes.
727 + * but we set it as 128 as minimum one.
728 + */
729 + reg |= SM(PCIE_MAX_PAYLOAD_128, PCIE_DCTLSTS_MAX_READ_SIZE)
730 + | SM(PCIE_MAX_PAYLOAD_128, PCIE_DCTLSTS_MAX_PAYLOAD_SIZE);
731 +
732 + /* Enable relaxed ordering, no snoop, and all kinds of errors */
733 + reg |= PCIE_DCTLSTS_RELAXED_ORDERING_EN | PCIE_DCTLSTS_ERR_EN | PCIE_DCTLSTS_NO_SNOOP_EN;
734 +
735 + IFX_REG_W32(reg, PCIE_DCTLSTS(pcie_port));
736 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_DCTLSTS: 0x%08x\n",
737 + __func__, IFX_REG_R32(PCIE_DCTLSTS(pcie_port)));
738 +}
739 +
740 +static INLINE void
741 +pcie_link_setup(int pcie_port)
742 +{
743 + u32 reg;
744 +
745 + /*
746 + * XXX, Link capability register, bit 18 for EP CLKREQ# dynamic clock management for L1, L2/3 CPM
747 + * L0s is reported during link training via TS1 order set by N_FTS
748 + */
749 + reg = IFX_REG_R32(PCIE_LCAP(pcie_port));
750 + reg &= ~PCIE_LCAP_L0S_EIXT_LATENCY;
751 + reg |= SM(3, PCIE_LCAP_L0S_EIXT_LATENCY);
752 + IFX_REG_W32(reg, PCIE_LCAP(pcie_port));
753 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_LCAP: 0x%08x\n",
754 + __func__, IFX_REG_R32(PCIE_LCAP(pcie_port)));
755 +
756 + /* Link control and status register */
757 + reg = IFX_REG_R32(PCIE_LCTLSTS(pcie_port));
758 +
759 + /* Link Enable, ASPM enabled */
760 + reg &= ~PCIE_LCTLSTS_LINK_DISABLE;
761 +
762 +#ifdef CONFIG_PCIEASPM
763 + /*
764 + * We use the same physical reference clock that the platform provides on the connector
765 + * It paved the way for ASPM to calculate the new exit Latency
766 + */
767 + reg |= PCIE_LCTLSTS_SLOT_CLK_CFG;
768 + reg |= PCIE_LCTLSTS_COM_CLK_CFG;
769 + /*
770 + * We should disable ASPM by default except that we have dedicated power management support
771 + * Enable ASPM will cause the system hangup/instability, performance degration
772 + */
773 + reg |= PCIE_LCTLSTS_ASPM_ENABLE;
774 +#else
775 + reg &= ~PCIE_LCTLSTS_ASPM_ENABLE;
776 +#endif /* CONFIG_PCIEASPM */
777 +
778 + /*
779 + * The maximum size of any completion with data packet is bounded by the MPS setting
780 + * in device control register
781 + */
782 +
783 + /* RCB may cause multiple split transactions, two options available, we use 64 byte RCB */
784 + reg &= ~ PCIE_LCTLSTS_RCB128;
785 +
786 + IFX_REG_W32(reg, PCIE_LCTLSTS(pcie_port));
787 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_LCTLSTS: 0x%08x\n",
788 + __func__, IFX_REG_R32(PCIE_LCTLSTS(pcie_port)));
789 +}
790 +
791 +static INLINE void
792 +pcie_error_setup(int pcie_port)
793 +{
794 + u32 reg;
795 +
796 + /*
797 + * Forward ERR_COR, ERR_NONFATAL, ERR_FATAL to the backbone
798 + * Poisoned write TLPs and completions indicating poisoned TLPs will set the PCIe_PCICMDSTS.MDPE
799 + */
800 + reg = IFX_REG_R32(PCIE_INTRBCTRL(pcie_port));
801 + reg |= PCIE_INTRBCTRL_SERR_ENABLE | PCIE_INTRBCTRL_PARITY_ERR_RESP_ENABLE;
802 +
803 + IFX_REG_W32(reg, PCIE_INTRBCTRL(pcie_port));
804 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_INTRBCTRL: 0x%08x\n",
805 + __func__, IFX_REG_R32(PCIE_INTRBCTRL(pcie_port)));
806 +
807 + /* Uncorrectable Error Mask Register, Unmask <enable> all bits in PCIE_UESR */
808 + reg = IFX_REG_R32(PCIE_UEMR(pcie_port));
809 + reg &= ~PCIE_ALL_UNCORRECTABLE_ERR;
810 + IFX_REG_W32(reg, PCIE_UEMR(pcie_port));
811 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_UEMR: 0x%08x\n",
812 + __func__, IFX_REG_R32(PCIE_UEMR(pcie_port)));
813 +
814 + /* Uncorrectable Error Severity Register, ALL errors are FATAL */
815 + IFX_REG_W32(PCIE_ALL_UNCORRECTABLE_ERR, PCIE_UESR(pcie_port));
816 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_UESR: 0x%08x\n",
817 + __func__, IFX_REG_R32(PCIE_UESR(pcie_port)));
818 +
819 + /* Correctable Error Mask Register, unmask <enable> all bits */
820 + reg = IFX_REG_R32(PCIE_CEMR(pcie_port));
821 + reg &= ~PCIE_CORRECTABLE_ERR;
822 + IFX_REG_W32(reg, PCIE_CEMR(pcie_port));
823 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_CEMR: 0x%08x\n",
824 + __func__, IFX_REG_R32(PCIE_CEMR(pcie_port)));
825 +
826 + /* Advanced Error Capabilities and Control Registr */
827 + reg = IFX_REG_R32(PCIE_AECCR(pcie_port));
828 + reg |= PCIE_AECCR_ECRC_CHECK_EN | PCIE_AECCR_ECRC_GEN_EN;
829 + IFX_REG_W32(reg, PCIE_AECCR(pcie_port));
830 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_AECCR: 0x%08x\n",
831 + __func__, IFX_REG_R32(PCIE_AECCR(pcie_port)));
832 +
833 + /* Root Error Command Register, Report all types of errors */
834 + reg = IFX_REG_R32(PCIE_RECR(pcie_port));
835 + reg |= PCIE_RECR_ERR_REPORT_EN;
836 + IFX_REG_W32(reg, PCIE_RECR(pcie_port));
837 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_RECR: 0x%08x\n",
838 + __func__, IFX_REG_R32(PCIE_RECR(pcie_port)));
839 +
840 + /* Clear the Root status register */
841 + reg = IFX_REG_R32(PCIE_RESR(pcie_port));
842 + IFX_REG_W32(reg, PCIE_RESR(pcie_port));
843 +}
844 +
845 +static INLINE void
846 +pcie_root_setup(int pcie_port)
847 +{
848 + u32 reg;
849 +
850 + /* Root control and capabilities register */
851 + reg = IFX_REG_R32(PCIE_RCTLCAP(pcie_port));
852 + reg |= PCIE_RCTLCAP_SERR_ENABLE | PCIE_RCTLCAP_PME_INT_EN;
853 + IFX_REG_W32(reg, PCIE_RCTLCAP(pcie_port));
854 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_RCTLCAP: 0x%08x\n",
855 + __func__, IFX_REG_R32(PCIE_RCTLCAP(pcie_port)));
856 +}
857 +
858 +static INLINE void
859 +pcie_vc_setup(int pcie_port)
860 +{
861 + u32 reg;
862 +
863 + /* Port VC Capability Register 2 */
864 + reg = IFX_REG_R32(PCIE_PVC2(pcie_port));
865 + reg &= ~PCIE_PVC2_VC_ARB_WRR;
866 + reg |= PCIE_PVC2_VC_ARB_16P_FIXED_WRR;
867 + IFX_REG_W32(reg, PCIE_PVC2(pcie_port));
868 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_PVC2: 0x%08x\n",
869 + __func__, IFX_REG_R32(PCIE_PVC2(pcie_port)));
870 +
871 + /* VC0 Resource Capability Register */
872 + reg = IFX_REG_R32(PCIE_VC0_RC(pcie_port));
873 + reg &= ~PCIE_VC0_RC_REJECT_SNOOP;
874 + IFX_REG_W32(reg, PCIE_VC0_RC(pcie_port));
875 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_VC0_RC: 0x%08x\n",
876 + __func__, IFX_REG_R32(PCIE_VC0_RC(pcie_port)));
877 +}
878 +
879 +static INLINE void
880 +pcie_port_logic_setup(int pcie_port)
881 +{
882 + u32 reg;
883 +
884 + /* FTS number, default 12, increase to 63, may increase time from/to L0s to L0 */
885 + reg = IFX_REG_R32(PCIE_AFR(pcie_port));
886 + reg &= ~(PCIE_AFR_FTS_NUM | PCIE_AFR_COM_FTS_NUM);
887 + reg |= SM(PCIE_AFR_FTS_NUM_DEFAULT, PCIE_AFR_FTS_NUM)
888 + | SM(PCIE_AFR_FTS_NUM_DEFAULT, PCIE_AFR_COM_FTS_NUM);
889 + /* L0s and L1 entry latency */
890 + reg &= ~(PCIE_AFR_L0S_ENTRY_LATENCY | PCIE_AFR_L1_ENTRY_LATENCY);
891 + reg |= SM(PCIE_AFR_L0S_ENTRY_LATENCY_DEFAULT, PCIE_AFR_L0S_ENTRY_LATENCY)
892 + | SM(PCIE_AFR_L1_ENTRY_LATENCY_DEFAULT, PCIE_AFR_L1_ENTRY_LATENCY);
893 + IFX_REG_W32(reg, PCIE_AFR(pcie_port));
894 +
895 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_AFR: 0x%08x\n",
896 + __func__, IFX_REG_R32(PCIE_AFR(pcie_port)));
897 +
898 + /* Port Link Control Register */
899 + reg = IFX_REG_R32(PCIE_PLCR(pcie_port));
900 + reg |= PCIE_PLCR_DLL_LINK_EN; /* Enable the DLL link */
901 + IFX_REG_W32(reg, PCIE_PLCR(pcie_port));
902 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_PLCR: 0x%08x\n",
903 + __func__, IFX_REG_R32(PCIE_PLCR(pcie_port)));
904 +
905 + /* Lane Skew Register */
906 + reg = IFX_REG_R32(PCIE_LSR(pcie_port));
907 + /* Enable ACK/NACK and FC */
908 + reg &= ~(PCIE_LSR_ACKNAK_DISABLE | PCIE_LSR_FC_DISABLE);
909 + IFX_REG_W32(reg, PCIE_LSR(pcie_port));
910 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_LSR: 0x%08x\n",
911 + __func__, IFX_REG_R32(PCIE_LSR(pcie_port)));
912 +
913 + /* Symbol Timer Register and Filter Mask Register 1 */
914 + reg = IFX_REG_R32(PCIE_STRFMR(pcie_port));
915 +
916 + /* Default SKP interval is very accurate already, 5us */
917 + /* Enable IO/CFG transaction */
918 + reg |= PCIE_STRFMR_RX_CFG_TRANS_ENABLE | PCIE_STRFMR_RX_IO_TRANS_ENABLE;
919 + /* Disable FC WDT */
920 + reg &= ~PCIE_STRFMR_FC_WDT_DISABLE;
921 + IFX_REG_W32(reg, PCIE_STRFMR(pcie_port));
922 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_STRFMR: 0x%08x\n",
923 + __func__, IFX_REG_R32(PCIE_STRFMR(pcie_port)));
924 +
925 + /* Filter Masker Register 2 */
926 + reg = IFX_REG_R32(PCIE_FMR2(pcie_port));
927 + reg |= PCIE_FMR2_VENDOR_MSG1_PASSED_TO_TRGT1 | PCIE_FMR2_VENDOR_MSG0_PASSED_TO_TRGT1;
928 + IFX_REG_W32(reg, PCIE_FMR2(pcie_port));
929 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_FMR2: 0x%08x\n",
930 + __func__, IFX_REG_R32(PCIE_FMR2(pcie_port)));
931 +
932 + /* VC0 Completion Receive Queue Control Register */
933 + reg = IFX_REG_R32(PCIE_VC0_CRQCR(pcie_port));
934 + reg &= ~PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE;
935 + reg |= SM(PCIE_VC0_TLP_QUEUE_MODE_BYPASS, PCIE_VC0_CRQCR_CPL_TLP_QUEUE_MODE);
936 + IFX_REG_W32(reg, PCIE_VC0_CRQCR(pcie_port));
937 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_VC0_CRQCR: 0x%08x\n",
938 + __func__, IFX_REG_R32(PCIE_VC0_CRQCR(pcie_port)));
939 +}
940 +
941 +static INLINE void
942 +pcie_rc_cfg_reg_setup(int pcie_port)
943 +{
944 + pcie_ltssm_disable(pcie_port);
945 + pcie_mem_io_setup(pcie_port);
946 + pcie_msi_setup(pcie_port);
947 + pcie_pm_setup(pcie_port);
948 + pcie_bus_setup(pcie_port);
949 + pcie_device_setup(pcie_port);
950 + pcie_link_setup(pcie_port);
951 + pcie_error_setup(pcie_port);
952 + pcie_root_setup(pcie_port);
953 + pcie_vc_setup(pcie_port);
954 + pcie_port_logic_setup(pcie_port);
955 +}
956 +
957 +static int
958 +ifx_pcie_wait_phy_link_up(int pcie_port)
959 +{
960 +#define IFX_PCIE_PHY_LINK_UP_TIMEOUT 1000 /* XXX, tunable */
961 + int i;
962 +
963 + /* Wait for PHY link is up */
964 + for (i = 0; i < IFX_PCIE_PHY_LINK_UP_TIMEOUT; i++) {
965 + if (ifx_pcie_link_up(pcie_port)) {
966 + break;
967 + }
968 + udelay(100);
969 + }
970 + if (i >= IFX_PCIE_PHY_LINK_UP_TIMEOUT) {
971 + printk(KERN_ERR "%s timeout\n", __func__);
972 + return -1;
973 + }
974 +
975 + /* Check data link up or not */
976 + if (!(IFX_REG_R32(PCIE_RC_DR(pcie_port)) & PCIE_RC_DR_DLL_UP)) {
977 + printk(KERN_ERR "%s DLL link is still down\n", __func__);
978 + return -1;
979 + }
980 +
981 + /* Check Data link active or not */
982 + if (!(IFX_REG_R32(PCIE_LCTLSTS(pcie_port)) & PCIE_LCTLSTS_DLL_ACTIVE)) {
983 + printk(KERN_ERR "%s DLL is not active\n", __func__);
984 + return -1;
985 + }
986 + return 0;
987 +#undef IFX_PCIE_PHY_LINK_UP_TIMEOUT
988 +}
989 +
990 +static INLINE int
991 +pcie_app_loigc_setup(int pcie_port)
992 +{
993 +#ifdef IFX_PCIE_PHY_DBG
994 + pcie_disable_scrambling(pcie_port);
995 +#endif /* IFX_PCIE_PHY_DBG */
996 + pcie_ahb_bus_error_suppress(pcie_port);
997 +
998 + /* Pull PCIe EP out of reset */
999 + pcie_device_rst_deassert(pcie_port);
1000 +
1001 + /* Start LTSSM training between RC and EP */
1002 + pcie_ltssm_enable(pcie_port);
1003 +
1004 + /* Check PHY status after enabling LTSSM */
1005 + if (ifx_pcie_wait_phy_link_up(pcie_port) != 0) {
1006 + return -1;
1007 + }
1008 + return 0;
1009 +}
1010 +
1011 +/*
1012 + * Must be done after ltssm due to based on negotiated link
1013 + * width and payload size
1014 + * Update the Replay Time Limit. Empirically, some PCIe
1015 + * devices take a little longer to respond than expected under
1016 + * load. As a workaround for this we configure the Replay Time
1017 + * Limit to the value expected for a 512 byte MPS instead of
1018 + * our actual 128 byte MPS. The numbers below are directly
1019 + * from the PCIe spec table 3-4/5.
1020 + */
1021 +static INLINE void
1022 +pcie_replay_time_update(int pcie_port)
1023 +{
1024 + u32 reg;
1025 + int nlw;
1026 + int rtl;
1027 +
1028 + reg = IFX_REG_R32(PCIE_LCTLSTS(pcie_port));
1029 +
1030 + nlw = MS(reg, PCIE_LCTLSTS_NEGOTIATED_LINK_WIDTH);
1031 + switch (nlw) {
1032 + case PCIE_MAX_LENGTH_WIDTH_X1:
1033 + rtl = 1677;
1034 + break;
1035 + case PCIE_MAX_LENGTH_WIDTH_X2:
1036 + rtl = 867;
1037 + break;
1038 + case PCIE_MAX_LENGTH_WIDTH_X4:
1039 + rtl = 462;
1040 + break;
1041 + case PCIE_MAX_LENGTH_WIDTH_X8:
1042 + rtl = 258;
1043 + break;
1044 + default:
1045 + rtl = 1677;
1046 + break;
1047 + }
1048 + reg = IFX_REG_R32(PCIE_ALTRT(pcie_port));
1049 + reg &= ~PCIE_ALTRT_REPLAY_TIME_LIMIT;
1050 + reg |= SM(rtl, PCIE_ALTRT_REPLAY_TIME_LIMIT);
1051 + IFX_REG_W32(reg, PCIE_ALTRT(pcie_port));
1052 +
1053 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_ALTRT 0x%08x\n",
1054 + __func__, IFX_REG_R32(PCIE_ALTRT(pcie_port)));
1055 +}
1056 +
1057 +/*
1058 + * Table 359 Enhanced Configuration Address Mapping1)
1059 + * 1) This table is defined in Table 7-1, page 341, PCI Express Base Specification v1.1
1060 + * Memory Address PCI Express Configuration Space
1061 + * A[(20+n-1):20] Bus Number 1 < n < 8
1062 + * A[19:15] Device Number
1063 + * A[14:12] Function Number
1064 + * A[11:8] Extended Register Number
1065 + * A[7:2] Register Number
1066 + * A[1:0] Along with size of the access, used to generate Byte Enables
1067 + * For VR9, only the address bits [22:0] are mapped to the configuration space:
1068 + * . Address bits [22:20] select the target bus (1-of-8)1)
1069 + * . Address bits [19:15] select the target device (1-of-32) on the bus
1070 + * . Address bits [14:12] select the target function (1-of-8) within the device.
1071 + * . Address bits [11:2] selects the target dword (1-of-1024) within the selected function.s configuration space
1072 + * . Address bits [1:0] define the start byte location within the selected dword.
1073 + */
1074 +static inline u32
1075 +pcie_bus_addr(u8 bus_num, u16 devfn, int where)
1076 +{
1077 + u32 addr;
1078 + u8 bus;
1079 +
1080 + if (!bus_num) {
1081 + /* type 0 */
1082 + addr = ((PCI_SLOT(devfn) & 0x1F) << 15) | ((PCI_FUNC(devfn) & 0x7) << 12) | ((where & 0xFFF)& ~3);
1083 + }
1084 + else {
1085 + bus = bus_num;
1086 + /* type 1, only support 8 buses */
1087 + addr = ((bus & 0x7) << 20) | ((PCI_SLOT(devfn) & 0x1F) << 15) |
1088 + ((PCI_FUNC(devfn) & 0x7) << 12) | ((where & 0xFFF) & ~3);
1089 + }
1090 + IFX_PCIE_PRINT(PCIE_MSG_CFG, "%s: bus addr : %02x:%02x.%01x/%02x, addr=%08x\n",
1091 + __func__, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn), where, addr);
1092 + return addr;
1093 +}
1094 +
1095 +static int
1096 +pcie_valid_config(int pcie_port, int bus, int dev)
1097 +{
1098 + /* RC itself */
1099 + if ((bus == 0) && (dev == 0)) {
1100 + return 1;
1101 + }
1102 +
1103 + /* No physical link */
1104 + if (!ifx_pcie_link_up(pcie_port)) {
1105 + return 0;
1106 + }
1107 +
1108 + /* Bus zero only has RC itself
1109 + * XXX, check if EP will be integrated
1110 + */
1111 + if ((bus == 0) && (dev != 0)) {
1112 + return 0;
1113 + }
1114 +
1115 + /* Maximum 8 buses supported for VRX */
1116 + if (bus > 9) {
1117 + return 0;
1118 + }
1119 +
1120 + /*
1121 + * PCIe is PtP link, one bus only supports only one device
1122 + * except bus zero and PCIe switch which is virtual bus device
1123 + * The following two conditions really depends on the system design
1124 + * and attached the device.
1125 + * XXX, how about more new switch
1126 + */
1127 + if ((bus == 1) && (dev != 0)) {
1128 + return 0;
1129 + }
1130 +
1131 + if ((bus >= 3) && (dev != 0)) {
1132 + return 0;
1133 + }
1134 + return 1;
1135 +}
1136 +
1137 +static INLINE u32
1138 +ifx_pcie_cfg_rd(int pcie_port, u32 reg)
1139 +{
1140 + return IFX_REG_R32((volatile u32 *)(PCIE_CFG_PORT_TO_BASE(pcie_port) + reg));
1141 +}
1142 +
1143 +static INLINE void
1144 +ifx_pcie_cfg_wr(int pcie_port, unsigned int reg, u32 val)
1145 +{
1146 + IFX_REG_W32( val, (volatile u32 *)(PCIE_CFG_PORT_TO_BASE(pcie_port) + reg));
1147 +}
1148 +
1149 +static INLINE u32
1150 +ifx_pcie_rc_cfg_rd(int pcie_port, u32 reg)
1151 +{
1152 + return IFX_REG_R32((volatile u32 *)(PCIE_RC_PORT_TO_BASE(pcie_port) + reg));
1153 +}
1154 +
1155 +static INLINE void
1156 +ifx_pcie_rc_cfg_wr(int pcie_port, unsigned int reg, u32 val)
1157 +{
1158 + IFX_REG_W32(val, (volatile u32 *)(PCIE_RC_PORT_TO_BASE(pcie_port) + reg));
1159 +}
1160 +
1161 +u32
1162 +ifx_pcie_bus_enum_read_hack(int where, u32 value)
1163 +{
1164 + u32 tvalue = value;
1165 +
1166 + if (where == PCI_PRIMARY_BUS) {
1167 + u8 primary, secondary, subordinate;
1168 +
1169 + primary = tvalue & 0xFF;
1170 + secondary = (tvalue >> 8) & 0xFF;
1171 + subordinate = (tvalue >> 16) & 0xFF;
1172 + primary += pcibios_1st_host_bus_nr();
1173 + secondary += pcibios_1st_host_bus_nr();
1174 + subordinate += pcibios_1st_host_bus_nr();
1175 + tvalue = (tvalue & 0xFF000000) | (u32)primary | (u32)(secondary << 8) | (u32)(subordinate << 16);
1176 + }
1177 + return tvalue;
1178 +}
1179 +
1180 +u32
1181 +ifx_pcie_bus_enum_write_hack(int where, u32 value)
1182 +{
1183 + u32 tvalue = value;
1184 +
1185 + if (where == PCI_PRIMARY_BUS) {
1186 + u8 primary, secondary, subordinate;
1187 +
1188 + primary = tvalue & 0xFF;
1189 + secondary = (tvalue >> 8) & 0xFF;
1190 + subordinate = (tvalue >> 16) & 0xFF;
1191 + if (primary > 0 && primary != 0xFF) {
1192 + primary -= pcibios_1st_host_bus_nr();
1193 + }
1194 +
1195 + if (secondary > 0 && secondary != 0xFF) {
1196 + secondary -= pcibios_1st_host_bus_nr();
1197 + }
1198 + if (subordinate > 0 && subordinate != 0xFF) {
1199 + subordinate -= pcibios_1st_host_bus_nr();
1200 + }
1201 + tvalue = (tvalue & 0xFF000000) | (u32)primary | (u32)(secondary << 8) | (u32)(subordinate << 16);
1202 + }
1203 + else if (where == PCI_SUBORDINATE_BUS) {
1204 + u8 subordinate = tvalue & 0xFF;
1205 +
1206 + subordinate = subordinate > 0 ? subordinate - pcibios_1st_host_bus_nr() : 0;
1207 + tvalue = subordinate;
1208 + }
1209 + return tvalue;
1210 +}
1211 +
1212 +/**
1213 + * \fn static int ifx_pcie_read_config(struct pci_bus *bus, u32 devfn,
1214 + * int where, int size, u32 *value)
1215 + * \brief Read a value from configuration space
1216 + *
1217 + * \param[in] bus Pointer to pci bus
1218 + * \param[in] devfn PCI device function number
1219 + * \param[in] where PCI register number
1220 + * \param[in] size Register read size
1221 + * \param[out] value Pointer to return value
1222 + * \return PCIBIOS_BAD_REGISTER_NUMBER Invalid register number
1223 + * \return PCIBIOS_FUNC_NOT_SUPPORTED PCI function not supported
1224 + * \return PCIBIOS_DEVICE_NOT_FOUND PCI device not found
1225 + * \return PCIBIOS_SUCCESSFUL OK
1226 + * \ingroup IFX_PCIE_OS
1227 + */
1228 +static int
1229 +ifx_pcie_read_config(struct pci_bus *bus, u32 devfn,
1230 + int where, int size, u32 *value)
1231 +{
1232 + u32 data = 0;
1233 + int bus_number = bus->number;
1234 + static const u32 mask[8] = {0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0};
1235 + int ret = PCIBIOS_SUCCESSFUL;
1236 + struct ifx_pci_controller *ctrl = bus->sysdata;
1237 + int pcie_port = ctrl->port;
1238 +
1239 + if (unlikely(size != 1 && size != 2 && size != 4)){
1240 + ret = PCIBIOS_BAD_REGISTER_NUMBER;
1241 + goto out;
1242 + }
1243 +
1244 + /* Make sure the address is aligned to natural boundary */
1245 + if (unlikely(((size - 1) & where))) {
1246 + ret = PCIBIOS_BAD_REGISTER_NUMBER;
1247 + goto out;
1248 + }
1249 +
1250 + /*
1251 + * If we are second controller, we have to cheat OS so that it assume
1252 + * its bus number starts from 0 in host controller
1253 + */
1254 + bus_number = ifx_pcie_bus_nr_deduct(bus_number, pcie_port);
1255 +
1256 + /*
1257 + * We need to force the bus number to be zero on the root
1258 + * bus. Linux numbers the 2nd root bus to start after all
1259 + * busses on root 0.
1260 + */
1261 + if (bus->parent == NULL) {
1262 + bus_number = 0;
1263 + }
1264 +
1265 + /*
1266 + * PCIe only has a single device connected to it. It is
1267 + * always device ID 0. Don't bother doing reads for other
1268 + * device IDs on the first segment.
1269 + */
1270 + if ((bus_number == 0) && (PCI_SLOT(devfn) != 0)) {
1271 + ret = PCIBIOS_FUNC_NOT_SUPPORTED;
1272 + goto out;
1273 + }
1274 +
1275 + if (pcie_valid_config(pcie_port, bus_number, PCI_SLOT(devfn)) == 0) {
1276 + *value = 0xffffffff;
1277 + ret = PCIBIOS_DEVICE_NOT_FOUND;
1278 + goto out;
1279 + }
1280 +
1281 + IFX_PCIE_PRINT(PCIE_MSG_READ_CFG, "%s: %02x:%02x.%01x/%02x:%01d\n", __func__, bus_number,
1282 + PCI_SLOT(devfn), PCI_FUNC(devfn), where, size);
1283 +
1284 + PCIE_IRQ_LOCK(ifx_pcie_lock);
1285 + if (bus_number == 0) { /* RC itself */
1286 + u32 t;
1287 +
1288 + t = (where & ~3);
1289 + data = ifx_pcie_rc_cfg_rd(pcie_port, t);
1290 + IFX_PCIE_PRINT(PCIE_MSG_READ_CFG, "%s: rd local cfg, offset:%08x, data:%08x\n",
1291 + __func__, t, data);
1292 + }
1293 + else {
1294 + u32 addr = pcie_bus_addr(bus_number, devfn, where);
1295 +
1296 + data = ifx_pcie_cfg_rd(pcie_port, addr);
1297 + if (pcie_port == IFX_PCIE_PORT0) {
1298 + #ifdef CONFIG_IFX_PCIE_HW_SWAP
1299 + data = le32_to_cpu(data);
1300 + #endif /* CONFIG_IFX_PCIE_HW_SWAP */
1301 + }
1302 + else {
1303 + #ifdef CONFIG_IFX_PCIE1_HW_SWAP
1304 + data = le32_to_cpu(data);
1305 + #endif /* CONFIG_IFX_PCIE_HW_SWAP */
1306 + }
1307 + }
1308 + /* To get a correct PCI topology, we have to restore the bus number to OS */
1309 + data = ifx_pcie_bus_enum_hack(bus, devfn, where, data, pcie_port, 1);
1310 +
1311 + PCIE_IRQ_UNLOCK(ifx_pcie_lock);
1312 + IFX_PCIE_PRINT(PCIE_MSG_READ_CFG, "%s: read config: data=%08x raw=%08x\n",
1313 + __func__, (data >> (8 * (where & 3))) & mask[size & 7], data);
1314 +
1315 + *value = (data >> (8 * (where & 3))) & mask[size & 7];
1316 +out:
1317 + return ret;
1318 +}
1319 +
1320 +static u32
1321 +ifx_pcie_size_to_value(int where, int size, u32 data, u32 value)
1322 +{
1323 + u32 shift;
1324 + u32 tdata = data;
1325 +
1326 + switch (size) {
1327 + case 1:
1328 + shift = (where & 0x3) << 3;
1329 + tdata &= ~(0xffU << shift);
1330 + tdata |= ((value & 0xffU) << shift);
1331 + break;
1332 + case 2:
1333 + shift = (where & 3) << 3;
1334 + tdata &= ~(0xffffU << shift);
1335 + tdata |= ((value & 0xffffU) << shift);
1336 + break;
1337 + case 4:
1338 + tdata = value;
1339 + break;
1340 + }
1341 + return tdata;
1342 +}
1343 +
1344 +/**
1345 + * \fn static static int ifx_pcie_write_config(struct pci_bus *bus, u32 devfn,
1346 + * int where, int size, u32 value)
1347 + * \brief Write a value to PCI configuration space
1348 + *
1349 + * \param[in] bus Pointer to pci bus
1350 + * \param[in] devfn PCI device function number
1351 + * \param[in] where PCI register number
1352 + * \param[in] size The register size to be written
1353 + * \param[in] value The valule to be written
1354 + * \return PCIBIOS_BAD_REGISTER_NUMBER Invalid register number
1355 + * \return PCIBIOS_DEVICE_NOT_FOUND PCI device not found
1356 + * \return PCIBIOS_SUCCESSFUL OK
1357 + * \ingroup IFX_PCIE_OS
1358 + */
1359 +static int
1360 +ifx_pcie_write_config(struct pci_bus *bus, u32 devfn,
1361 + int where, int size, u32 value)
1362 +{
1363 + int bus_number = bus->number;
1364 + int ret = PCIBIOS_SUCCESSFUL;
1365 + struct ifx_pci_controller *ctrl = bus->sysdata;
1366 + int pcie_port = ctrl->port;
1367 + u32 tvalue = value;
1368 + u32 data;
1369 +
1370 + /* Make sure the address is aligned to natural boundary */
1371 + if (unlikely(((size - 1) & where))) {
1372 + ret = PCIBIOS_BAD_REGISTER_NUMBER;
1373 + goto out;
1374 + }
1375 + /*
1376 + * If we are second controller, we have to cheat OS so that it assume
1377 + * its bus number starts from 0 in host controller
1378 + */
1379 + bus_number = ifx_pcie_bus_nr_deduct(bus_number, pcie_port);
1380 +
1381 + /*
1382 + * We need to force the bus number to be zero on the root
1383 + * bus. Linux numbers the 2nd root bus to start after all
1384 + * busses on root 0.
1385 + */
1386 + if (bus->parent == NULL) {
1387 + bus_number = 0;
1388 + }
1389 +
1390 + if (pcie_valid_config(pcie_port, bus_number, PCI_SLOT(devfn)) == 0) {
1391 + ret = PCIBIOS_DEVICE_NOT_FOUND;
1392 + goto out;
1393 + }
1394 +
1395 + IFX_PCIE_PRINT(PCIE_MSG_WRITE_CFG, "%s: %02x:%02x.%01x/%02x:%01d value=%08x\n", __func__,
1396 + bus_number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, value);
1397 +
1398 + /* XXX, some PCIe device may need some delay */
1399 + PCIE_IRQ_LOCK(ifx_pcie_lock);
1400 +
1401 + /*
1402 + * To configure the correct bus topology using native way, we have to cheat Os so that
1403 + * it can configure the PCIe hardware correctly.
1404 + */
1405 + tvalue = ifx_pcie_bus_enum_hack(bus, devfn, where, value, pcie_port, 0);
1406 +
1407 + if (bus_number == 0) { /* RC itself */
1408 + u32 t;
1409 +
1410 + t = (where & ~3);
1411 + IFX_PCIE_PRINT(PCIE_MSG_WRITE_CFG,"%s: wr local cfg, offset:%08x, fill:%08x\n", __func__, t, value);
1412 + data = ifx_pcie_rc_cfg_rd(pcie_port, t);
1413 + IFX_PCIE_PRINT(PCIE_MSG_WRITE_CFG,"%s: rd local cfg, offset:%08x, data:%08x\n", __func__, t, data);
1414 +
1415 + data = ifx_pcie_size_to_value(where, size, data, tvalue);
1416 +
1417 + IFX_PCIE_PRINT(PCIE_MSG_WRITE_CFG,"%s: wr local cfg, offset:%08x, value:%08x\n", __func__, t, data);
1418 + ifx_pcie_rc_cfg_wr(pcie_port, t, data);
1419 + IFX_PCIE_PRINT(PCIE_MSG_WRITE_CFG,"%s: rd local cfg, offset:%08x, value:%08x\n",
1420 + __func__, t, ifx_pcie_rc_cfg_rd(pcie_port, t));
1421 + }
1422 + else {
1423 + u32 addr = pcie_bus_addr(bus_number, devfn, where);
1424 +
1425 + IFX_PCIE_PRINT(PCIE_MSG_WRITE_CFG,"%s: wr cfg, offset:%08x, fill:%08x\n", __func__, addr, value);
1426 + data = ifx_pcie_cfg_rd(pcie_port, addr);
1427 + if (pcie_port == IFX_PCIE_PORT0) {
1428 + #ifdef CONFIG_IFX_PCIE_HW_SWAP
1429 + data = le32_to_cpu(data);
1430 + #endif /* CONFIG_IFX_PCIE_HW_SWAP */
1431 + }
1432 + else {
1433 + #ifdef CONFIG_IFX_PCIE1_HW_SWAP
1434 + data = le32_to_cpu(data);
1435 + #endif /* CONFIG_IFX_PCIE_HW_SWAP */
1436 + }
1437 + IFX_PCIE_PRINT(PCIE_MSG_WRITE_CFG,"%s: rd cfg, offset:%08x, data:%08x\n", __func__, addr, data);
1438 +
1439 + data = ifx_pcie_size_to_value(where, size, data, tvalue);
1440 + if (pcie_port == IFX_PCIE_PORT0) {
1441 + #ifdef CONFIG_IFX_PCIE_HW_SWAP
1442 + data = cpu_to_le32(data);
1443 + #endif /* CONFIG_IFX_PCIE_HW_SWAP */
1444 + }
1445 + else {
1446 + #ifdef CONFIG_IFX_PCIE1_HW_SWAP
1447 + data = cpu_to_le32(data);
1448 + #endif /* CONFIG_IFX_PCIE_HW_SWAP */
1449 + }
1450 + IFX_PCIE_PRINT(PCIE_MSG_WRITE_CFG, "%s: wr cfg, offset:%08x, value:%08x\n", __func__, addr, data);
1451 + ifx_pcie_cfg_wr(pcie_port, addr, data);
1452 + IFX_PCIE_PRINT(PCIE_MSG_WRITE_CFG, "%s: rd cfg, offset:%08x, value:%08x\n",
1453 + __func__, addr, ifx_pcie_cfg_rd(pcie_port, addr));
1454 + }
1455 + PCIE_IRQ_UNLOCK(ifx_pcie_lock);
1456 +out:
1457 + return ret;
1458 +}
1459 +
1460 +static struct resource ifx_pcie_io_resource = {
1461 + .name = "PCIe0 I/O space",
1462 + .start = PCIE_IO_PHY_BASE,
1463 + .end = PCIE_IO_PHY_END,
1464 + .flags = IORESOURCE_IO,
1465 +};
1466 +
1467 +static struct resource ifx_pcie_mem_resource = {
1468 + .name = "PCIe0 Memory space",
1469 + .start = PCIE_MEM_PHY_BASE,
1470 + .end = PCIE_MEM_PHY_END,
1471 + .flags = IORESOURCE_MEM,
1472 +};
1473 +
1474 +static struct pci_ops ifx_pcie_ops = {
1475 + .read = ifx_pcie_read_config,
1476 + .write = ifx_pcie_write_config,
1477 +};
1478 +
1479 +#ifdef CONFIG_IFX_PCIE_2ND_CORE
1480 +static struct resource ifx_pcie1_io_resource = {
1481 + .name = "PCIe1 I/O space",
1482 + .start = PCIE1_IO_PHY_BASE,
1483 + .end = PCIE1_IO_PHY_END,
1484 + .flags = IORESOURCE_IO,
1485 +};
1486 +
1487 +static struct resource ifx_pcie1_mem_resource = {
1488 + .name = "PCIe1 Memory space",
1489 + .start = PCIE1_MEM_PHY_BASE,
1490 + .end = PCIE1_MEM_PHY_END,
1491 + .flags = IORESOURCE_MEM,
1492 +};
1493 +#endif /* CONFIG_IFX_PCIE_2ND_CORE */
1494 +
1495 +static struct ifx_pci_controller ifx_pcie_controller[IFX_PCIE_CORE_NR] = {
1496 + {
1497 + .pcic = {
1498 + .pci_ops = &ifx_pcie_ops,
1499 + .mem_resource = &ifx_pcie_mem_resource,
1500 + .io_resource = &ifx_pcie_io_resource,
1501 + },
1502 + .port = IFX_PCIE_PORT0,
1503 + },
1504 +#ifdef CONFIG_IFX_PCIE_2ND_CORE
1505 + {
1506 + .pcic = {
1507 + .pci_ops = &ifx_pcie_ops,
1508 + .mem_resource = &ifx_pcie1_mem_resource,
1509 + .io_resource = &ifx_pcie1_io_resource,
1510 + },
1511 + .port = IFX_PCIE_PORT1,
1512 + },
1513 +#endif /* CONFIG_IFX_PCIE_2ND_CORE */
1514 +};
1515 +
1516 +#ifdef IFX_PCIE_ERROR_INT
1517 +static INLINE void
1518 +pcie_core_int_clear_all(int pcie_port)
1519 +{
1520 + u32 reg;
1521 +
1522 + reg = IFX_REG_R32(PCIE_IRNCR(pcie_port));
1523 + IFX_PCIE_PRINT(PCIE_MSG_ISR, "%s PCIE_IRNCR: 0x%08x\n",
1524 + __func__, IFX_REG_R32(PCIE_IRNCR(pcie_port)));
1525 + reg &= PCIE_RC_CORE_COMBINED_INT;
1526 + IFX_REG_W32(reg, PCIE_IRNCR(pcie_port));
1527 +}
1528 +
1529 +static irqreturn_t
1530 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,19)
1531 +pcie_rc_core_isr(int irq, void *dev_id)
1532 +#else
1533 +pcie_rc_core_isr(int irq, void *dev_id, struct pt_regs *regs)
1534 +#endif
1535 +{
1536 + struct ifx_pci_controller *ctrl = (struct ifx_pci_controller *)dev_id;
1537 + int pcie_port = ctrl->port;
1538 +
1539 + IFX_PCIE_PRINT(PCIE_MSG_ISR, "PCIe RC error intr %d\n", irq);
1540 + pcie_core_int_clear_all(pcie_port);
1541 + return IRQ_HANDLED;
1542 +}
1543 +
1544 +static int
1545 +pcie_rc_core_int_init(int pcie_port)
1546 +{
1547 + int ret;
1548 +
1549 + IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s enter \n", __func__);
1550 +
1551 + /* Enable core interrupt */
1552 + IFX_REG_SET_BIT(PCIE_RC_CORE_COMBINED_INT, PCIE_IRNEN(pcie_port));
1553 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_IRNEN: 0x%08x\n",
1554 + __func__, IFX_REG_R32(PCIE_IRNEN(pcie_port)));
1555 +
1556 + /* Clear it first */
1557 + IFX_REG_SET_BIT(PCIE_RC_CORE_COMBINED_INT, PCIE_IRNCR(pcie_port));
1558 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s PCIE_IRNCR: 0x%08x\n",
1559 + __func__, IFX_REG_R32(PCIE_IRNCR(pcie_port)));
1560 + ret = request_irq(pcie_irqs[pcie_port].ir_irq.irq, pcie_rc_core_isr, IRQF_DISABLED,
1561 + pcie_irqs[pcie_port].ir_irq.name, &ifx_pcie_controller[pcie_port]);
1562 + if (ret) {
1563 + printk(KERN_ERR "%s request irq %d failed\n", __func__, IFX_PCIE_IR);
1564 + }
1565 + IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s exit \n", __func__);
1566 +
1567 + return ret;
1568 +}
1569 +#endif /* IFX_PCIE_ERROR_INT */
1570 +
1571 +/**
1572 + * \fn int ifx_pcie_bios_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
1573 + * \brief Map a PCI device to the appropriate interrupt line
1574 + *
1575 + * \param[in] dev The Linux PCI device structure for the device to map
1576 + * \param[in] slot The slot number for this device on __BUS 0__. Linux
1577 + * enumerates through all the bridges and figures out the
1578 + * slot on Bus 0 where this device eventually hooks to.
1579 + * \param[in] pin The PCI interrupt pin read from the device, then swizzled
1580 + * as it goes through each bridge.
1581 + * \return Interrupt number for the device
1582 + * \ingroup IFX_PCIE_OS
1583 + */
1584 +int
1585 +ifx_pcie_bios_map_irq(IFX_PCI_CONST struct pci_dev *dev, u8 slot, u8 pin)
1586 +{
1587 + u32 irq_bit = 0;
1588 + int irq = 0;
1589 + struct ifx_pci_controller *ctrl = dev->bus->sysdata;
1590 + int pcie_port = ctrl->port;
1591 +
1592 + printk("%s port %d dev %s slot %d pin %d \n", __func__, pcie_port, pci_name(dev), slot, pin);
1593 +
1594 + if ((pin == PCIE_LEGACY_DISABLE) || (pin > PCIE_LEGACY_INT_MAX)) {
1595 + printk(KERN_WARNING "WARNING: dev %s: invalid interrupt pin %d\n", pci_name(dev), pin);
1596 + return -1;
1597 + }
1598 + /* Pin index so minus one */
1599 + irq_bit = pcie_irqs[pcie_port].legacy_irq[pin - 1].irq_bit;
1600 + irq = pcie_irqs[pcie_port].legacy_irq[pin - 1].irq;
1601 + IFX_REG_SET_BIT(irq_bit, PCIE_IRNEN(pcie_port));
1602 +// printk("%s PCIE_IRNEN: 0x%08x\n", __func__, IFX_REG_R32(PCIE_IRNEN(pcie_port)));
1603 + IFX_REG_SET_BIT(irq_bit, PCIE_IRNCR(pcie_port));
1604 + // printk("%s PCIE_IRNCR: 0x%08x\n", __func__, IFX_REG_R32(PCIE_IRNCR(pcie_port)));
1605 + printk("%s dev %s irq %d assigned\n", __func__, pci_name(dev), irq);
1606 +// printk("%s dev %s: exit\n", __func__, pci_name(dev));
1607 + return irq;
1608 +}
1609 +
1610 +/**
1611 + * \fn int ifx_pcie_bios_plat_dev_init(struct pci_dev *dev)
1612 + * \brief Called to perform platform specific PCI setup
1613 + *
1614 + * \param[in] dev The Linux PCI device structure for the device to map
1615 + * \return OK
1616 + * \ingroup IFX_PCIE_OS
1617 + */
1618 +int
1619 +ifx_pcie_bios_plat_dev_init(struct pci_dev *dev)
1620 +{
1621 + u16 config;
1622 +#ifdef IFX_PCIE_ERROR_INT
1623 + u32 dconfig;
1624 + int pos;
1625 +#endif /* IFX_PCIE_ERROR_INT */
1626 +
1627 + IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s enter \n", __func__);
1628 + /* Enable reporting System errors and parity errors on all devices */
1629 + /* Enable parity checking and error reporting */
1630 + pci_read_config_word(dev, PCI_COMMAND, &config);
1631 + config |= PCI_COMMAND_PARITY | PCI_COMMAND_SERR /*| PCI_COMMAND_INVALIDATE |
1632 + PCI_COMMAND_FAST_BACK*/;
1633 + pci_write_config_word(dev, PCI_COMMAND, config);
1634 +
1635 + if (dev->subordinate) {
1636 + /* Set latency timers on sub bridges */
1637 + pci_write_config_byte(dev, PCI_SEC_LATENCY_TIMER, 0x40); /* XXX, */
1638 + /* More bridge error detection */
1639 + pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &config);
1640 + config |= PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_SERR;
1641 + pci_write_config_word(dev, PCI_BRIDGE_CONTROL, config);
1642 + }
1643 +#ifdef IFX_PCIE_ERROR_INT
1644 + /* Enable the PCIe normal error reporting */
1645 + pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
1646 + if (pos) {
1647 +
1648 + /* Disable system error generation in response to error messages */
1649 + pci_read_config_word(dev, pos + PCI_EXP_RTCTL, &config);
1650 + config &= ~(PCI_EXP_RTCTL_SECEE | PCI_EXP_RTCTL_SENFEE | PCI_EXP_RTCTL_SEFEE);
1651 + pci_write_config_word(dev, pos + PCI_EXP_RTCTL, config);
1652 +
1653 + /* Clear PCIE Capability's Device Status */
1654 + pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &config);
1655 + pci_write_config_word(dev, pos + PCI_EXP_DEVSTA, config);
1656 +
1657 + /* Update Device Control */
1658 + pci_read_config_word(dev, pos + PCI_EXP_DEVCTL, &config);
1659 + /* Correctable Error Reporting */
1660 + config |= PCI_EXP_DEVCTL_CERE;
1661 + /* Non-Fatal Error Reporting */
1662 + config |= PCI_EXP_DEVCTL_NFERE;
1663 + /* Fatal Error Reporting */
1664 + config |= PCI_EXP_DEVCTL_FERE;
1665 + /* Unsupported Request */
1666 + config |= PCI_EXP_DEVCTL_URRE;
1667 + pci_write_config_word(dev, pos + PCI_EXP_DEVCTL, config);
1668 + }
1669 +
1670 + /* Find the Advanced Error Reporting capability */
1671 + pos = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
1672 + if (pos) {
1673 + /* Clear Uncorrectable Error Status */
1674 + pci_read_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, &dconfig);
1675 + pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_STATUS, dconfig);
1676 + /* Enable reporting of all uncorrectable errors */
1677 + /* Uncorrectable Error Mask - turned on bits disable errors */
1678 + pci_write_config_dword(dev, pos + PCI_ERR_UNCOR_MASK, 0);
1679 + /*
1680 + * Leave severity at HW default. This only controls if
1681 + * errors are reported as uncorrectable or
1682 + * correctable, not if the error is reported.
1683 + */
1684 + /* PCI_ERR_UNCOR_SEVER - Uncorrectable Error Severity */
1685 + /* Clear Correctable Error Status */
1686 + pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &dconfig);
1687 + pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, dconfig);
1688 + /* Enable reporting of all correctable errors */
1689 + /* Correctable Error Mask - turned on bits disable errors */
1690 + pci_write_config_dword(dev, pos + PCI_ERR_COR_MASK, 0);
1691 + /* Advanced Error Capabilities */
1692 + pci_read_config_dword(dev, pos + PCI_ERR_CAP, &dconfig);
1693 + /* ECRC Generation Enable */
1694 + if (dconfig & PCI_ERR_CAP_ECRC_GENC) {
1695 + dconfig |= PCI_ERR_CAP_ECRC_GENE;
1696 + }
1697 + /* ECRC Check Enable */
1698 + if (dconfig & PCI_ERR_CAP_ECRC_CHKC) {
1699 + dconfig |= PCI_ERR_CAP_ECRC_CHKE;
1700 + }
1701 + pci_write_config_dword(dev, pos + PCI_ERR_CAP, dconfig);
1702 +
1703 + /* PCI_ERR_HEADER_LOG - Header Log Register (16 bytes) */
1704 + /* Enable Root Port's interrupt in response to error messages */
1705 + pci_write_config_dword(dev, pos + PCI_ERR_ROOT_COMMAND,
1706 + PCI_ERR_ROOT_CMD_COR_EN |
1707 + PCI_ERR_ROOT_CMD_NONFATAL_EN |
1708 + PCI_ERR_ROOT_CMD_FATAL_EN);
1709 + /* Clear the Root status register */
1710 + pci_read_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, &dconfig);
1711 + pci_write_config_dword(dev, pos + PCI_ERR_ROOT_STATUS, dconfig);
1712 + }
1713 +#endif /* IFX_PCIE_ERROR_INT */
1714 + /* WAR, only 128 MRRS is supported, force all EPs to support this value */
1715 + pcie_set_readrq(dev, 128);
1716 + IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s exit \n", __func__);
1717 + return 0;
1718 +}
1719 +
1720 +static void
1721 +pcie_phy_rst(int pcie_port)
1722 +{
1723 + pcie_phy_rst_assert(pcie_port);
1724 + pcie_phy_rst_deassert(pcie_port);
1725 +
1726 + /* Make sure PHY PLL is stable */
1727 + udelay(20);
1728 +}
1729 +
1730 +static int
1731 +pcie_rc_initialize(int pcie_port)
1732 +{
1733 + int i;
1734 +#define IFX_PCIE_PHY_LOOP_CNT 5
1735 +
1736 + pcie_rcu_endian_setup(pcie_port);
1737 +
1738 + pcie_ep_gpio_rst_init(pcie_port);
1739 +
1740 + /*
1741 + * XXX, PCIe elastic buffer bug will cause not to be detected. One more
1742 + * reset PCIe PHY will solve this issue
1743 + */
1744 + for (i = 0; i < IFX_PCIE_PHY_LOOP_CNT; i++) {
1745 + /* Disable PCIe PHY Analog part for sanity check */
1746 + pcie_phy_pmu_disable(pcie_port);
1747 +
1748 + pcie_phy_rst(pcie_port);
1749 +
1750 + /* PCIe Core reset enabled, low active, sw programmed */
1751 + pcie_core_rst_assert(pcie_port);
1752 +
1753 + /* Put PCIe EP in reset status */
1754 + pcie_device_rst_assert(pcie_port);
1755 +
1756 + /* PCI PHY & Core reset disabled, high active, sw programmed */
1757 + pcie_core_rst_deassert(pcie_port);
1758 +
1759 + /* Already in a quiet state, program PLL, enable PHY, check ready bit */
1760 + pcie_phy_clock_mode_setup(pcie_port);
1761 +
1762 + /* Enable PCIe PHY and Clock */
1763 + pcie_core_pmu_setup(pcie_port);
1764 +
1765 + /* Clear status registers */
1766 + pcie_status_register_clear(pcie_port);
1767 +
1768 + #ifdef CONFIG_PCI_MSI
1769 + pcie_msi_init(pcie_port);
1770 + #endif /* CONFIG_PCI_MSI */
1771 + pcie_rc_cfg_reg_setup(pcie_port);
1772 +
1773 + /* Once link is up, break out */
1774 + if (pcie_app_loigc_setup(pcie_port) == 0) {
1775 + break;
1776 + }
1777 + }
1778 + if (i >= IFX_PCIE_PHY_LOOP_CNT) {
1779 + printk(KERN_ERR "%s link up failed!!!!!\n", __func__);
1780 + return -EIO;
1781 + }
1782 + /* NB, don't increase ACK/NACK timer timeout value, which will cause a lot of COR errors */
1783 + pcie_replay_time_update(pcie_port);
1784 +#ifdef IFX_PCIE_DBG
1785 + pcie_post_dump(pcie_port);
1786 + pcie_status_registers_dump(pcie_port);
1787 +#endif /* IFX_PCIE_DBG */
1788 + return 0;
1789 +}
1790 +
1791 +static int inline
1792 +ifx_pcie_startup_port_nr(void)
1793 +{
1794 + int pcie_port = IFX_PCIE_PORT0;
1795 +
1796 +#if defined (CONFIG_IFX_PCIE_1ST_CORE) && defined (CONFIG_IFX_PCIE_2ND_CORE)
1797 + pcie_port = IFX_PCIE_PORT0;
1798 +#elif defined (CONFIG_IFX_PCIE_1ST_CORE)
1799 + pcie_port = IFX_PCIE_PORT0;
1800 +#elif defined (CONFIG_IFX_PCIE_2ND_CORE)
1801 + pcie_port = IFX_PCIE_PORT1;
1802 +#else
1803 + #error "Please choose valid PCIe Core"
1804 +#endif
1805 + return pcie_port;
1806 +}
1807 +
1808 +/**
1809 + * \fn static int __init ifx_pcie_bios_init(void)
1810 + * \brief Initialize the IFX PCIe controllers
1811 + *
1812 + * \return -EIO PCIe PHY link is not up
1813 + * \return -ENOMEM Configuration/IO space failed to map
1814 + * \return 0 OK
1815 + * \ingroup IFX_PCIE_OS
1816 + */
1817 +extern int (*ltq_pci_plat_arch_init)(struct pci_dev *dev);
1818 +extern int (*ltq_pci_map_irq)(const struct pci_dev *dev, u8 slot, u8 pin);
1819 +
1820 +static int __init
1821 +ifx_pcie_bios_init(void)
1822 +{
1823 + char ver_str[128] = {0};
1824 + void __iomem *io_map_base;
1825 + int pcie_port;
1826 + int startup_port;
1827 +
1828 + IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s enter \n", __func__);
1829 +
1830 + ltq_pci_map_irq = ifx_pcie_bios_map_irq;
1831 + ltq_pci_plat_arch_init = ifx_pcie_bios_plat_dev_init;
1832 +
1833 + /* Enable AHB Master/ Slave */
1834 + pcie_ahb_pmu_setup();
1835 +
1836 + startup_port = ifx_pcie_startup_port_nr();
1837 +
1838 + for (pcie_port = startup_port; pcie_port < IFX_PCIE_CORE_NR; pcie_port++){
1839 + if (pcie_rc_initialize(pcie_port) == 0) {
1840 + IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s: ifx_pcie_cfg_base 0x%p\n",
1841 + __func__, PCIE_CFG_PORT_TO_BASE(pcie_port));
1842 + /* Otherwise, warning will pop up */
1843 + io_map_base = ioremap(PCIE_IO_PHY_PORT_TO_BASE(pcie_port), PCIE_IO_SIZE);
1844 + if (io_map_base == NULL) {
1845 + IFX_PCIE_PRINT(PCIE_MSG_ERR, "%s io space ioremap failed\n", __func__);
1846 + return -ENOMEM;
1847 + }
1848 + ifx_pcie_controller[pcie_port].pcic.io_map_base = (unsigned long)io_map_base;
1849 +
1850 + register_pci_controller(&ifx_pcie_controller[pcie_port].pcic);
1851 + /* XXX, clear error status */
1852 +
1853 + IFX_PCIE_PRINT(PCIE_MSG_INIT, "%s: mem_resource 0x%p, io_resource 0x%p\n",
1854 + __func__, &ifx_pcie_controller[pcie_port].pcic.mem_resource,
1855 + &ifx_pcie_controller[pcie_port].pcic.io_resource);
1856 +
1857 + #ifdef IFX_PCIE_ERROR_INT
1858 + pcie_rc_core_int_init(pcie_port);
1859 + #endif /* IFX_PCIE_ERROR_INT */
1860 + }
1861 + }
1862 +#ifdef CONFIG_IFX_PMCU
1863 + ifx_pcie_pmcu_init();
1864 +#endif /* CONFIG_IFX_PMCU */
1865 +
1866 + sprintf(ver_str, "PCIe Root Complex %d.%d.%d", IFX_PCIE_VER_MAJOR, IFX_PCIE_VER_MID, IFX_PCIE_VER_MINOR);
1867 + printk(KERN_INFO "%s", ver_str);
1868 + return 0;
1869 +#undef IFX_PCIE_PHY_LOOP_CNT
1870 +}
1871 +arch_initcall(ifx_pcie_bios_init);
1872 +
1873 +MODULE_LICENSE("GPL");
1874 +MODULE_AUTHOR("Chuanhua.Lei@infineon.com");
1875 +MODULE_SUPPORTED_DEVICE("Infineon builtin PCIe RC module");
1876 +MODULE_DESCRIPTION("Infineon builtin PCIe RC driver");
1877 +
1878 diff --git a/arch/mips/pci/ifxmips_pcie.h b/arch/mips/pci/ifxmips_pcie.h
1879 new file mode 100644
1880 index 0000000..c6f92f5
1881 --- /dev/null
1882 +++ b/arch/mips/pci/ifxmips_pcie.h
1883 @@ -0,0 +1,135 @@
1884 +/******************************************************************************
1885 +**
1886 +** FILE NAME : ifxmips_pcie.h
1887 +** PROJECT : IFX UEIP for VRX200
1888 +** MODULES : PCIe module
1889 +**
1890 +** DATE : 02 Mar 2009
1891 +** AUTHOR : Lei Chuanhua
1892 +** DESCRIPTION : PCIe Root Complex Driver
1893 +** COPYRIGHT : Copyright (c) 2009
1894 +** Infineon Technologies AG
1895 +** Am Campeon 1-12, 85579 Neubiberg, Germany
1896 +**
1897 +** This program is free software; you can redistribute it and/or modify
1898 +** it under the terms of the GNU General Public License as published by
1899 +** the Free Software Foundation; either version 2 of the License, or
1900 +** (at your option) any later version.
1901 +** HISTORY
1902 +** $Version $Date $Author $Comment
1903 +** 0.0.1 17 Mar,2009 Lei Chuanhua Initial version
1904 +*******************************************************************************/
1905 +#ifndef IFXMIPS_PCIE_H
1906 +#define IFXMIPS_PCIE_H
1907 +#include <linux/version.h>
1908 +#include <linux/types.h>
1909 +#include <linux/pci.h>
1910 +#include <linux/interrupt.h>
1911 +#include "ifxmips_pci_common.h"
1912 +#include "ifxmips_pcie_reg.h"
1913 +
1914 +/*!
1915 + \defgroup IFX_PCIE PCI Express bus driver module
1916 + \brief PCI Express IP module support VRX200
1917 +*/
1918 +
1919 +/*!
1920 + \defgroup IFX_PCIE_OS OS APIs
1921 + \ingroup IFX_PCIE
1922 + \brief PCIe bus driver OS interface functions
1923 +*/
1924 +
1925 +/*!
1926 + \file ifxmips_pcie.h
1927 + \ingroup IFX_PCIE
1928 + \brief header file for PCIe module common header file
1929 +*/
1930 +#define PCIE_IRQ_LOCK(lock) do { \
1931 + unsigned long flags; \
1932 + spin_lock_irqsave(&(lock), flags);
1933 +#define PCIE_IRQ_UNLOCK(lock) \
1934 + spin_unlock_irqrestore(&(lock), flags); \
1935 +} while (0)
1936 +
1937 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)
1938 +#define IRQF_SHARED SA_SHIRQ
1939 +#endif
1940 +
1941 +#define PCIE_MSG_MSI 0x00000001
1942 +#define PCIE_MSG_ISR 0x00000002
1943 +#define PCIE_MSG_FIXUP 0x00000004
1944 +#define PCIE_MSG_READ_CFG 0x00000008
1945 +#define PCIE_MSG_WRITE_CFG 0x00000010
1946 +#define PCIE_MSG_CFG (PCIE_MSG_READ_CFG | PCIE_MSG_WRITE_CFG)
1947 +#define PCIE_MSG_REG 0x00000020
1948 +#define PCIE_MSG_INIT 0x00000040
1949 +#define PCIE_MSG_ERR 0x00000080
1950 +#define PCIE_MSG_PHY 0x00000100
1951 +#define PCIE_MSG_ANY 0x000001ff
1952 +
1953 +#define IFX_PCIE_PORT0 0
1954 +#define IFX_PCIE_PORT1 1
1955 +
1956 +#ifdef CONFIG_IFX_PCIE_2ND_CORE
1957 +#define IFX_PCIE_CORE_NR 2
1958 +#else
1959 +#define IFX_PCIE_CORE_NR 1
1960 +#endif
1961 +
1962 +#define IFX_PCIE_ERROR_INT
1963 +
1964 +//#define IFX_PCIE_DBG
1965 +
1966 +#if defined(IFX_PCIE_DBG)
1967 +#define IFX_PCIE_PRINT(_m, _fmt, args...) do { \
1968 + ifx_pcie_debug((_fmt), ##args); \
1969 +} while (0)
1970 +
1971 +#define INLINE
1972 +#else
1973 +#define IFX_PCIE_PRINT(_m, _fmt, args...) \
1974 + do {} while(0)
1975 +#define INLINE inline
1976 +#endif
1977 +
1978 +struct ifx_pci_controller {
1979 + struct pci_controller pcic;
1980 +
1981 + /* RC specific, per host bus information */
1982 + u32 port; /* Port index, 0 -- 1st core, 1 -- 2nd core */
1983 +};
1984 +
1985 +typedef struct ifx_pcie_ir_irq {
1986 + const unsigned int irq;
1987 + const char name[16];
1988 +}ifx_pcie_ir_irq_t;
1989 +
1990 +typedef struct ifx_pcie_legacy_irq{
1991 + const u32 irq_bit;
1992 + const int irq;
1993 +}ifx_pcie_legacy_irq_t;
1994 +
1995 +typedef struct ifx_pcie_irq {
1996 + ifx_pcie_ir_irq_t ir_irq;
1997 + ifx_pcie_legacy_irq_t legacy_irq[PCIE_LEGACY_INT_MAX];
1998 +}ifx_pcie_irq_t;
1999 +
2000 +extern u32 g_pcie_debug_flag;
2001 +extern void ifx_pcie_debug(const char *fmt, ...);
2002 +extern void pcie_phy_clock_mode_setup(int pcie_port);
2003 +extern void pcie_msi_pic_init(int pcie_port);
2004 +extern u32 ifx_pcie_bus_enum_read_hack(int where, u32 value);
2005 +extern u32 ifx_pcie_bus_enum_write_hack(int where, u32 value);
2006 +
2007 +#define CONFIG_VR9
2008 +
2009 +#ifdef CONFIG_VR9
2010 +#include "ifxmips_pcie_vr9.h"
2011 +#elif defined (CONFIG_AR10)
2012 +#include "ifxmips_pcie_ar10.h"
2013 +#else
2014 +#error "PCIE: platform not defined"
2015 +#endif /* CONFIG_VR9 */
2016 +
2017 +#endif /* IFXMIPS_PCIE_H */
2018 +
2019 diff --git a/arch/mips/pci/ifxmips_pcie_ar10.h b/arch/mips/pci/ifxmips_pcie_ar10.h
2020 new file mode 100644
2021 index 0000000..99ff463
2022 --- /dev/null
2023 +++ b/arch/mips/pci/ifxmips_pcie_ar10.h
2024 @@ -0,0 +1,290 @@
2025 +/****************************************************************************
2026 + Copyright (c) 2010
2027 + Lantiq Deutschland GmbH
2028 + Am Campeon 3; 85579 Neubiberg, Germany
2029 +
2030 + For licensing information, see the file 'LICENSE' in the root folder of
2031 + this software module.
2032 +
2033 + *****************************************************************************/
2034 +/*!
2035 + \file ifxmips_pcie_ar10.h
2036 + \ingroup IFX_PCIE
2037 + \brief PCIe RC driver ar10 specific file
2038 +*/
2039 +
2040 +#ifndef IFXMIPS_PCIE_AR10_H
2041 +#define IFXMIPS_PCIE_AR10_H
2042 +#ifndef AUTOCONF_INCLUDED
2043 +#include <linux/config.h>
2044 +#endif /* AUTOCONF_INCLUDED */
2045 +#include <linux/types.h>
2046 +#include <linux/delay.h>
2047 +
2048 +/* Project header file */
2049 +#include <asm/ifx/ifx_types.h>
2050 +#include <asm/ifx/ifx_pmu.h>
2051 +#include <asm/ifx/ifx_gpio.h>
2052 +#include <asm/ifx/ifx_ebu_led.h>
2053 +
2054 +static inline void pcie_ep_gpio_rst_init(int pcie_port)
2055 +{
2056 + ifx_ebu_led_enable();
2057 + if (pcie_port == 0) {
2058 + ifx_ebu_led_set_data(11, 1);
2059 + }
2060 + else {
2061 + ifx_ebu_led_set_data(12, 1);
2062 + }
2063 +}
2064 +
2065 +static inline void pcie_ahb_pmu_setup(void)
2066 +{
2067 + /* XXX, moved to CGU to control AHBM */
2068 +}
2069 +
2070 +static inline void pcie_rcu_endian_setup(int pcie_port)
2071 +{
2072 + u32 reg;
2073 +
2074 + reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
2075 + /* Inbound, big endian */
2076 + reg |= IFX_RCU_BE_AHB4S;
2077 + if (pcie_port == 0) {
2078 + reg |= IFX_RCU_BE_PCIE0M;
2079 +
2080 + #ifdef CONFIG_IFX_PCIE_HW_SWAP
2081 + /* Outbound, software swap needed */
2082 + reg |= IFX_RCU_BE_AHB3M;
2083 + reg &= ~IFX_RCU_BE_PCIE0S;
2084 + #else
2085 + /* Outbound little endian */
2086 + reg &= ~IFX_RCU_BE_AHB3M;
2087 + reg &= ~IFX_RCU_BE_PCIE0S;
2088 + #endif
2089 + }
2090 + else {
2091 + reg |= IFX_RCU_BE_PCIE1M;
2092 + #ifdef CONFIG_IFX_PCIE1_HW_SWAP
2093 + /* Outbound, software swap needed */
2094 + reg |= IFX_RCU_BE_AHB3M;
2095 + reg &= ~IFX_RCU_BE_PCIE1S;
2096 + #else
2097 + /* Outbound little endian */
2098 + reg &= ~IFX_RCU_BE_AHB3M;
2099 + reg &= ~IFX_RCU_BE_PCIE1S;
2100 + #endif
2101 + }
2102 +
2103 + IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
2104 + IFX_PCIE_PRINT(PCIE_MSG_REG, "%s IFX_RCU_AHB_ENDIAN: 0x%08x\n", __func__, IFX_REG_R32(IFX_RCU_AHB_ENDIAN));
2105 +}
2106 +
2107 +static inline void pcie_phy_pmu_enable(int pcie_port)
2108 +{
2109 + if (pcie_port == 0) { /* XXX, should use macro*/
2110 + PCIE0_PHY_PMU_SETUP(IFX_PMU_ENABLE);
2111 + }
2112 + else {
2113 + PCIE1_PHY_PMU_SETUP(IFX_PMU_ENABLE);
2114 + }
2115 +}
2116 +
2117 +static inline void pcie_phy_pmu_disable(int pcie_port)
2118 +{
2119 + if (pcie_port == 0) { /* XXX, should use macro*/
2120 + PCIE0_PHY_PMU_SETUP(IFX_PMU_DISABLE);
2121 + }
2122 + else {
2123 + PCIE1_PHY_PMU_SETUP(IFX_PMU_DISABLE);
2124 + }
2125 +}
2126 +
2127 +static inline void pcie_pdi_big_endian(int pcie_port)
2128 +{
2129 + u32 reg;
2130 +
2131 + reg = IFX_REG_R32(IFX_RCU_AHB_ENDIAN);
2132 + if (pcie_port == 0) {
2133 + /* Config AHB->PCIe and PDI endianness */
2134 + reg |= IFX_RCU_BE_PCIE0_PDI;
2135 + }
2136 + else {
2137 + /* Config AHB->PCIe and PDI endianness */
2138 + reg |= IFX_RCU_BE_PCIE1_PDI;
2139 + }
2140 + IFX_REG_W32(reg, IFX_RCU_AHB_ENDIAN);
2141 +}
2142 +
2143 +static inline void pcie_pdi_pmu_enable(int pcie_port)
2144 +{
2145 + if (pcie_port == 0) {
2146 + /* Enable PDI to access PCIe PHY register */
2147 + PDI0_PMU_SETUP(IFX_PMU_ENABLE);
2148 + }
2149 + else {
2150 + PDI1_PMU_SETUP(IFX_PMU_ENABLE);
2151 + }
2152 +}
2153 +
2154 +static inline void pcie_core_rst_assert(int pcie_port)
2155 +{
2156 + u32 reg;
2157 +
2158 + reg = IFX_REG_R32(IFX_RCU_RST_REQ);
2159 +
2160 + /* Reset Core, bit 22 */
2161 + if (pcie_port == 0) {
2162 + reg |= 0x00400000;
2163 + }
2164 + else {
2165 + reg |= 0x08000000; /* Bit 27 */
2166 + }
2167 + IFX_REG_W32(reg, IFX_RCU_RST_REQ);
2168 +}
2169 +
2170 +static inline void pcie_core_rst_deassert(int pcie_port)
2171 +{
2172 + u32 reg;
2173 +
2174 + /* Make sure one micro-second delay */
2175 + udelay(1);
2176 +
2177 + reg = IFX_REG_R32(IFX_RCU_RST_REQ);
2178 + if (pcie_port == 0) {
2179 + reg &= ~0x00400000; /* bit 22 */
2180 + }
2181 + else {
2182 + reg &= ~0x08000000; /* Bit 27 */
2183 + }
2184 + IFX_REG_W32(reg, IFX_RCU_RST_REQ);
2185 +}
2186 +
2187 +static inline void pcie_phy_rst_assert(int pcie_port)
2188 +{
2189 + u32 reg;
2190 +
2191 + reg = IFX_REG_R32(IFX_RCU_RST_REQ);
2192 + if (pcie_port == 0) {
2193 + reg |= 0x00001000; /* Bit 12 */
2194 + }
2195 + else {
2196 + reg |= 0x00002000; /* Bit 13 */
2197 + }
2198 + IFX_REG_W32(reg, IFX_RCU_RST_REQ);
2199 +}
2200 +
2201 +static inline void pcie_phy_rst_deassert(int pcie_port)
2202 +{
2203 + u32 reg;
2204 +
2205 + /* Make sure one micro-second delay */
2206 + udelay(1);
2207 +
2208 + reg = IFX_REG_R32(IFX_RCU_RST_REQ);
2209 + if (pcie_port == 0) {
2210 + reg &= ~0x00001000; /* Bit 12 */
2211 + }
2212 + else {
2213 + reg &= ~0x00002000; /* Bit 13 */
2214 + }
2215 + IFX_REG_W32(reg, IFX_RCU_RST_REQ);
2216 +}
2217 +
2218 +static inline void pcie_device_rst_assert(int pcie_port)
2219 +{
2220 + if (pcie_port == 0) {
2221 + ifx_ebu_led_set_data(11, 0);
2222 + }
2223 + else {
2224 + ifx_ebu_led_set_data(12, 0);
2225 + }
2226 +}
2227 +
2228 +static inline void pcie_device_rst_deassert(int pcie_port)
2229 +{
2230 + mdelay(100);
2231 + if (pcie_port == 0) {
2232 + ifx_ebu_led_set_data(11, 1);
2233 + }
2234 + else {
2235 + ifx_ebu_led_set_data(12, 1);
2236 + }
2237 + ifx_ebu_led_disable();
2238 +}
2239 +
2240 +static inline void pcie_core_pmu_setup(int pcie_port)
2241 +{
2242 + if (pcie_port == 0) {
2243 + PCIE0_CTRL_PMU_SETUP(IFX_PMU_ENABLE);
2244 + }
2245 + else {
2246 + PCIE1_CTRL_PMU_SETUP(IFX_PMU_ENABLE);
2247 + }
2248 +}
2249 +
2250 +static inline void pcie_msi_init(int pcie_port)
2251 +{
2252 + pcie_msi_pic_init(pcie_port);
2253 + if (pcie_port == 0) {
2254 + MSI0_PMU_SETUP(IFX_PMU_ENABLE);
2255 + }
2256 + else {
2257 + MSI1_PMU_SETUP(IFX_PMU_ENABLE);
2258 + }
2259 +}
2260 +
2261 +static inline u32
2262 +ifx_pcie_bus_nr_deduct(u32 bus_number, int pcie_port)
2263 +{
2264 + u32 tbus_number = bus_number;
2265 +
2266 +#ifdef CONFIG_IFX_PCIE_2ND_CORE
2267 + if (pcie_port == IFX_PCIE_PORT1) { /* Port 1 must check if there are two cores enabled */
2268 + if (pcibios_host_nr() > 1) {
2269 + tbus_number -= pcibios_1st_host_bus_nr();
2270 + }
2271 + }
2272 +#endif /* CONFIG_IFX_PCI */
2273 + return tbus_number;
2274 +}
2275 +
2276 +static inline u32
2277 +ifx_pcie_bus_enum_hack(struct pci_bus *bus, u32 devfn, int where, u32 value, int pcie_port, int read)
2278 +{
2279 + struct pci_dev *pdev;
2280 + u32 tvalue = value;
2281 +
2282 + /* Sanity check */
2283 + pdev = pci_get_slot(bus, devfn);
2284 + if (pdev == NULL) {
2285 + return tvalue;
2286 + }
2287 +
2288 + /* Only care about PCI bridge */
2289 + if (pdev->hdr_type != PCI_HEADER_TYPE_BRIDGE) {
2290 + return tvalue;
2291 + }
2292 +
2293 + if (read) { /* Read hack */
2294 + #ifdef CONFIG_IFX_PCIE_2ND_CORE
2295 + if (pcie_port == IFX_PCIE_PORT1) { /* Port 1 must check if there are two cores enabled */
2296 + if (pcibios_host_nr() > 1) {
2297 + tvalue = ifx_pcie_bus_enum_read_hack(where, tvalue);
2298 + }
2299 + }
2300 + #endif /* CONFIG_IFX_PCIE_2ND_CORE */
2301 + }
2302 + else { /* Write hack */
2303 + #ifdef CONFIG_IFX_PCIE_2ND_CORE
2304 + if (pcie_port == IFX_PCIE_PORT1) { /* Port 1 must check if there are two cores enabled */
2305 + if (pcibios_host_nr() > 1) {
2306 + tvalue = ifx_pcie_bus_enum_write_hack(where, tvalue);
2307 + }
2308 + }
2309 + #endif
2310 + }
2311 + return tvalue;
2312 +}
2313 +
2314 +#endif /* IFXMIPS_PCIE_AR10_H */
2315 diff --git a/arch/mips/pci/ifxmips_pcie_msi.c b/arch/mips/pci/ifxmips_pcie_msi.c
2316 new file mode 100644
2317 index 0000000..bffd6fa
2318 --- /dev/null
2319 +++ b/arch/mips/pci/ifxmips_pcie_msi.c
2320 @@ -0,0 +1,392 @@
2321 +/******************************************************************************
2322 +**
2323 +** FILE NAME : ifxmips_pcie_msi.c
2324 +** PROJECT : IFX UEIP for VRX200
2325 +** MODULES : PCI MSI sub module
2326 +**
2327 +** DATE : 02 Mar 2009
2328 +** AUTHOR : Lei Chuanhua
2329 +** DESCRIPTION : PCIe MSI Driver
2330 +** COPYRIGHT : Copyright (c) 2009
2331 +** Infineon Technologies AG
2332 +** Am Campeon 1-12, 85579 Neubiberg, Germany
2333 +**
2334 +** This program is free software; you can redistribute it and/or modify
2335 +** it under the terms of the GNU General Public License as published by
2336 +** the Free Software Foundation; either version 2 of the License, or
2337 +** (at your option) any later version.
2338 +** HISTORY
2339 +** $Date $Author $Comment
2340 +** 02 Mar,2009 Lei Chuanhua Initial version
2341 +*******************************************************************************/
2342 +/*!
2343 + \defgroup IFX_PCIE_MSI MSI OS APIs
2344 + \ingroup IFX_PCIE
2345 + \brief PCIe bus driver OS interface functions
2346 +*/
2347 +
2348 +/*!
2349 + \file ifxmips_pcie_msi.c
2350 + \ingroup IFX_PCIE
2351 + \brief PCIe MSI OS interface file
2352 +*/
2353 +
2354 +#ifndef AUTOCONF_INCLUDED
2355 +#include <linux/config.h>
2356 +#endif /* AUTOCONF_INCLUDED */
2357 +#include <linux/init.h>
2358 +#include <linux/sched.h>
2359 +#include <linux/slab.h>
2360 +#include <linux/interrupt.h>
2361 +#include <linux/kernel_stat.h>
2362 +#include <linux/pci.h>
2363 +#include <linux/msi.h>
2364 +#include <linux/module.h>
2365 +#include <asm/bootinfo.h>
2366 +#include <asm/irq.h>
2367 +#include <asm/traps.h>
2368 +
2369 +#include <asm/ifx/ifx_types.h>
2370 +#include <asm/ifx/ifx_regs.h>
2371 +#include <asm/ifx/common_routines.h>
2372 +#include <asm/ifx/irq.h>
2373 +
2374 +#include "ifxmips_pcie_reg.h"
2375 +#include "ifxmips_pcie.h"
2376 +
2377 +#define IFX_MSI_IRQ_NUM 16
2378 +
2379 +enum {
2380 + IFX_PCIE_MSI_IDX0 = 0,
2381 + IFX_PCIE_MSI_IDX1,
2382 + IFX_PCIE_MSI_IDX2,
2383 + IFX_PCIE_MSI_IDX3,
2384 +};
2385 +
2386 +typedef struct ifx_msi_irq_idx {
2387 + const int irq;
2388 + const int idx;
2389 +}ifx_msi_irq_idx_t;
2390 +
2391 +struct ifx_msi_pic {
2392 + volatile u32 pic_table[IFX_MSI_IRQ_NUM];
2393 + volatile u32 pic_endian; /* 0x40 */
2394 +};
2395 +typedef struct ifx_msi_pic *ifx_msi_pic_t;
2396 +
2397 +typedef struct ifx_msi_irq {
2398 + const volatile ifx_msi_pic_t msi_pic_p;
2399 + const u32 msi_phy_base;
2400 + const ifx_msi_irq_idx_t msi_irq_idx[IFX_MSI_IRQ_NUM];
2401 + /*
2402 + * Each bit in msi_free_irq_bitmask represents a MSI interrupt that is
2403 + * in use.
2404 + */
2405 + u16 msi_free_irq_bitmask;
2406 +
2407 + /*
2408 + * Each bit in msi_multiple_irq_bitmask tells that the device using
2409 + * this bit in msi_free_irq_bitmask is also using the next bit. This
2410 + * is used so we can disable all of the MSI interrupts when a device
2411 + * uses multiple.
2412 + */
2413 + u16 msi_multiple_irq_bitmask;
2414 +}ifx_msi_irq_t;
2415 +
2416 +static ifx_msi_irq_t msi_irqs[IFX_PCIE_CORE_NR] = {
2417 + {
2418 + .msi_pic_p = (const volatile ifx_msi_pic_t)IFX_MSI_PIC_REG_BASE,
2419 + .msi_phy_base = PCIE_MSI_PHY_BASE,
2420 + .msi_irq_idx = {
2421 + {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
2422 + {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
2423 + {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
2424 + {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
2425 + {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
2426 + {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
2427 + {IFX_PCIE_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE_MSI_IR1, IFX_PCIE_MSI_IDX1},
2428 + {IFX_PCIE_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE_MSI_IR3, IFX_PCIE_MSI_IDX3},
2429 + },
2430 + .msi_free_irq_bitmask = 0,
2431 + .msi_multiple_irq_bitmask= 0,
2432 + },
2433 +#ifdef CONFIG_IFX_PCIE_2ND_CORE
2434 + {
2435 + .msi_pic_p = (const volatile ifx_msi_pic_t)IFX_MSI1_PIC_REG_BASE,
2436 + .msi_phy_base = PCIE1_MSI_PHY_BASE,
2437 + .msi_irq_idx = {
2438 + {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
2439 + {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
2440 + {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
2441 + {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
2442 + {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
2443 + {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
2444 + {IFX_PCIE1_MSI_IR0, IFX_PCIE_MSI_IDX0}, {IFX_PCIE1_MSI_IR1, IFX_PCIE_MSI_IDX1},
2445 + {IFX_PCIE1_MSI_IR2, IFX_PCIE_MSI_IDX2}, {IFX_PCIE1_MSI_IR3, IFX_PCIE_MSI_IDX3},
2446 + },
2447 + .msi_free_irq_bitmask = 0,
2448 + .msi_multiple_irq_bitmask= 0,
2449 +
2450 + },
2451 +#endif /* CONFIG_IFX_PCIE_2ND_CORE */
2452 +};
2453 +
2454 +/*
2455 + * This lock controls updates to msi_free_irq_bitmask,
2456 + * msi_multiple_irq_bitmask and pic register settting
2457 + */
2458 +static DEFINE_SPINLOCK(ifx_pcie_msi_lock);
2459 +
2460 +void pcie_msi_pic_init(int pcie_port)
2461 +{
2462 + spin_lock(&ifx_pcie_msi_lock);
2463 + msi_irqs[pcie_port].msi_pic_p->pic_endian = IFX_MSI_PIC_BIG_ENDIAN;
2464 + spin_unlock(&ifx_pcie_msi_lock);
2465 +}
2466 +
2467 +/**
2468 + * \fn int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
2469 + * \brief Called when a driver request MSI interrupts instead of the
2470 + * legacy INT A-D. This routine will allocate multiple interrupts
2471 + * for MSI devices that support them. A device can override this by
2472 + * programming the MSI control bits [6:4] before calling
2473 + * pci_enable_msi().
2474 + *
2475 + * \param[in] pdev Device requesting MSI interrupts
2476 + * \param[in] desc MSI descriptor
2477 + *
2478 + * \return -EINVAL Invalid pcie root port or invalid msi bit
2479 + * \return 0 OK
2480 + * \ingroup IFX_PCIE_MSI
2481 + */
2482 +int
2483 +arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
2484 +{
2485 + int irq, pos;
2486 + u16 control;
2487 + int irq_idx;
2488 + int irq_step;
2489 + int configured_private_bits;
2490 + int request_private_bits;
2491 + struct msi_msg msg;
2492 + u16 search_mask;
2493 + struct ifx_pci_controller *ctrl = pdev->bus->sysdata;
2494 + int pcie_port = ctrl->port;
2495 +
2496 + IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s %s enter\n", __func__, pci_name(pdev));
2497 +
2498 + /* XXX, skip RC MSI itself */
2499 + if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
2500 + IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s RC itself doesn't use MSI interrupt\n", __func__);
2501 + return -EINVAL;
2502 + }
2503 +
2504 + /*
2505 + * Read the MSI config to figure out how many IRQs this device
2506 + * wants. Most devices only want 1, which will give
2507 + * configured_private_bits and request_private_bits equal 0.
2508 + */
2509 + pci_read_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS, &control);
2510 +
2511 + /*
2512 + * If the number of private bits has been configured then use
2513 + * that value instead of the requested number. This gives the
2514 + * driver the chance to override the number of interrupts
2515 + * before calling pci_enable_msi().
2516 + */
2517 + configured_private_bits = (control & PCI_MSI_FLAGS_QSIZE) >> 4;
2518 + if (configured_private_bits == 0) {
2519 + /* Nothing is configured, so use the hardware requested size */
2520 + request_private_bits = (control & PCI_MSI_FLAGS_QMASK) >> 1;
2521 + }
2522 + else {
2523 + /*
2524 + * Use the number of configured bits, assuming the
2525 + * driver wanted to override the hardware request
2526 + * value.
2527 + */
2528 + request_private_bits = configured_private_bits;
2529 + }
2530 +
2531 + /*
2532 + * The PCI 2.3 spec mandates that there are at most 32
2533 + * interrupts. If this device asks for more, only give it one.
2534 + */
2535 + if (request_private_bits > 5) {
2536 + request_private_bits = 0;
2537 + }
2538 +again:
2539 + /*
2540 + * The IRQs have to be aligned on a power of two based on the
2541 + * number being requested.
2542 + */
2543 + irq_step = (1 << request_private_bits);
2544 +
2545 + /* Mask with one bit for each IRQ */
2546 + search_mask = (1 << irq_step) - 1;
2547 +
2548 + /*
2549 + * We're going to search msi_free_irq_bitmask_lock for zero
2550 + * bits. This represents an MSI interrupt number that isn't in
2551 + * use.
2552 + */
2553 + spin_lock(&ifx_pcie_msi_lock);
2554 + for (pos = 0; pos < IFX_MSI_IRQ_NUM; pos += irq_step) {
2555 + if ((msi_irqs[pcie_port].msi_free_irq_bitmask & (search_mask << pos)) == 0) {
2556 + msi_irqs[pcie_port].msi_free_irq_bitmask |= search_mask << pos;
2557 + msi_irqs[pcie_port].msi_multiple_irq_bitmask |= (search_mask >> 1) << pos;
2558 + break;
2559 + }
2560 + }
2561 + spin_unlock(&ifx_pcie_msi_lock);
2562 +
2563 + /* Make sure the search for available interrupts didn't fail */
2564 + if (pos >= IFX_MSI_IRQ_NUM) {
2565 + if (request_private_bits) {
2566 + IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s: Unable to find %d free "
2567 + "interrupts, trying just one", __func__, 1 << request_private_bits);
2568 + request_private_bits = 0;
2569 + goto again;
2570 + }
2571 + else {
2572 + printk(KERN_ERR "%s: Unable to find a free MSI interrupt\n", __func__);
2573 + return -EINVAL;
2574 + }
2575 + }
2576 + irq = msi_irqs[pcie_port].msi_irq_idx[pos].irq;
2577 + irq_idx = msi_irqs[pcie_port].msi_irq_idx[pos].idx;
2578 +
2579 + IFX_PCIE_PRINT(PCIE_MSG_MSI, "pos %d, irq %d irq_idx %d\n", pos, irq, irq_idx);
2580 +
2581 + /*
2582 + * Initialize MSI. This has to match the memory-write endianess from the device
2583 + * Address bits [23:12]
2584 + */
2585 + spin_lock(&ifx_pcie_msi_lock);
2586 + msi_irqs[pcie_port].msi_pic_p->pic_table[pos] = SM(irq_idx, IFX_MSI_PIC_INT_LINE) |
2587 + SM((msi_irqs[pcie_port].msi_phy_base >> 12), IFX_MSI_PIC_MSG_ADDR) |
2588 + SM((1 << pos), IFX_MSI_PIC_MSG_DATA);
2589 +
2590 + /* Enable this entry */
2591 + msi_irqs[pcie_port].msi_pic_p->pic_table[pos] &= ~IFX_MSI_PCI_INT_DISABLE;
2592 + spin_unlock(&ifx_pcie_msi_lock);
2593 +
2594 + IFX_PCIE_PRINT(PCIE_MSG_MSI, "pic_table[%d]: 0x%08x\n",
2595 + pos, msi_irqs[pcie_port].msi_pic_p->pic_table[pos]);
2596 +
2597 + /* Update the number of IRQs the device has available to it */
2598 + control &= ~PCI_MSI_FLAGS_QSIZE;
2599 + control |= (request_private_bits << 4);
2600 + pci_write_config_word(pdev, desc->msi_attrib.pos + PCI_MSI_FLAGS, control);
2601 +
2602 + set_irq_msi(irq, desc);
2603 + msg.address_hi = 0x0;
2604 + msg.address_lo = msi_irqs[pcie_port].msi_phy_base;
2605 + msg.data = SM((1 << pos), IFX_MSI_PIC_MSG_DATA);
2606 + IFX_PCIE_PRINT(PCIE_MSG_MSI, "msi_data: pos %d 0x%08x\n", pos, msg.data);
2607 +
2608 + write_msi_msg(irq, &msg);
2609 + IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s exit\n", __func__);
2610 + return 0;
2611 +}
2612 +
2613 +static int
2614 +pcie_msi_irq_to_port(unsigned int irq, int *port)
2615 +{
2616 + int ret = 0;
2617 +
2618 + if (irq == IFX_PCIE_MSI_IR0 || irq == IFX_PCIE_MSI_IR1 ||
2619 + irq == IFX_PCIE_MSI_IR2 || irq == IFX_PCIE_MSI_IR3) {
2620 + *port = IFX_PCIE_PORT0;
2621 + }
2622 +#ifdef CONFIG_IFX_PCIE_2ND_CORE
2623 + else if (irq == IFX_PCIE1_MSI_IR0 || irq == IFX_PCIE1_MSI_IR1 ||
2624 + irq == IFX_PCIE1_MSI_IR2 || irq == IFX_PCIE1_MSI_IR3) {
2625 + *port = IFX_PCIE_PORT1;
2626 + }
2627 +#endif /* CONFIG_IFX_PCIE_2ND_CORE */
2628 + else {
2629 + printk(KERN_ERR "%s: Attempted to teardown illegal "
2630 + "MSI interrupt (%d)\n", __func__, irq);
2631 + ret = -EINVAL;
2632 + }
2633 + return ret;
2634 +}
2635 +
2636 +/**
2637 + * \fn void arch_teardown_msi_irq(unsigned int irq)
2638 + * \brief Called when a device no longer needs its MSI interrupts. All
2639 + * MSI interrupts for the device are freed.
2640 + *
2641 + * \param irq The devices first irq number. There may be multple in sequence.
2642 + * \return none
2643 + * \ingroup IFX_PCIE_MSI
2644 + */
2645 +void
2646 +arch_teardown_msi_irq(unsigned int irq)
2647 +{
2648 + int pos;
2649 + int number_irqs;
2650 + u16 bitmask;
2651 + int pcie_port;
2652 +
2653 + IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s enter\n", __func__);
2654 +
2655 + BUG_ON(irq > INT_NUM_IM4_IRL31);
2656 +
2657 + if (pcie_msi_irq_to_port(irq, &pcie_port) != 0) {
2658 + return;
2659 + }
2660 +
2661 + /* Shift the mask to the correct bit location, not always correct
2662 + * Probally, the first match will be chosen.
2663 + */
2664 + for (pos = 0; pos < IFX_MSI_IRQ_NUM; pos++) {
2665 + if ((msi_irqs[pcie_port].msi_irq_idx[pos].irq == irq)
2666 + && (msi_irqs[pcie_port].msi_free_irq_bitmask & ( 1 << pos))) {
2667 + break;
2668 + }
2669 + }
2670 + if (pos >= IFX_MSI_IRQ_NUM) {
2671 + printk(KERN_ERR "%s: Unable to find a matched MSI interrupt\n", __func__);
2672 + return;
2673 + }
2674 + spin_lock(&ifx_pcie_msi_lock);
2675 + /* Disable this entry */
2676 + msi_irqs[pcie_port].msi_pic_p->pic_table[pos] |= IFX_MSI_PCI_INT_DISABLE;
2677 + msi_irqs[pcie_port].msi_pic_p->pic_table[pos] &= ~(IFX_MSI_PIC_INT_LINE | IFX_MSI_PIC_MSG_ADDR | IFX_MSI_PIC_MSG_DATA);
2678 + spin_unlock(&ifx_pcie_msi_lock);
2679 + /*
2680 + * Count the number of IRQs we need to free by looking at the
2681 + * msi_multiple_irq_bitmask. Each bit set means that the next
2682 + * IRQ is also owned by this device.
2683 + */
2684 + number_irqs = 0;
2685 + while (((pos + number_irqs) < IFX_MSI_IRQ_NUM) &&
2686 + (msi_irqs[pcie_port].msi_multiple_irq_bitmask & (1 << (pos + number_irqs)))) {
2687 + number_irqs++;
2688 + }
2689 + number_irqs++;
2690 +
2691 + /* Mask with one bit for each IRQ */
2692 + bitmask = (1 << number_irqs) - 1;
2693 +
2694 + bitmask <<= pos;
2695 + if ((msi_irqs[pcie_port].msi_free_irq_bitmask & bitmask) != bitmask) {
2696 + printk(KERN_ERR "%s: Attempted to teardown MSI "
2697 + "interrupt (%d) not in use\n", __func__, irq);
2698 + return;
2699 + }
2700 + /* Checks are done, update the in use bitmask */
2701 + spin_lock(&ifx_pcie_msi_lock);
2702 + msi_irqs[pcie_port].msi_free_irq_bitmask &= ~bitmask;
2703 + msi_irqs[pcie_port].msi_multiple_irq_bitmask &= ~(bitmask >> 1);
2704 + spin_unlock(&ifx_pcie_msi_lock);
2705 + IFX_PCIE_PRINT(PCIE_MSG_MSI, "%s exit\n", __func__);
2706 +}
2707 +
2708 +MODULE_LICENSE("GPL");
2709 +MODULE_AUTHOR("Chuanhua.Lei@infineon.com");
2710 +MODULE_SUPPORTED_DEVICE("Infineon PCIe IP builtin MSI PIC module");
2711 +MODULE_DESCRIPTION("Infineon PCIe IP builtin MSI PIC driver");
2712 +
2713 diff --git a/arch/mips/pci/ifxmips_pcie_phy.c b/arch/mips/pci/ifxmips_pcie_phy.c
2714 new file mode 100644
2715 index 0000000..f5b0f13
2716 --- /dev/null
2717 +++ b/arch/mips/pci/ifxmips_pcie_phy.c
2718 @@ -0,0 +1,478 @@
2719 +/******************************************************************************
2720 +**
2721 +** FILE NAME : ifxmips_pcie_phy.c
2722 +** PROJECT : IFX UEIP for VRX200
2723 +** MODULES : PCIe PHY sub module
2724 +**
2725 +** DATE : 14 May 2009
2726 +** AUTHOR : Lei Chuanhua
2727 +** DESCRIPTION : PCIe Root Complex Driver
2728 +** COPYRIGHT : Copyright (c) 2009
2729 +** Infineon Technologies AG
2730 +** Am Campeon 1-12, 85579 Neubiberg, Germany
2731 +**
2732 +** This program is free software; you can redistribute it and/or modify
2733 +** it under the terms of the GNU General Public License as published by
2734 +** the Free Software Foundation; either version 2 of the License, or
2735 +** (at your option) any later version.
2736 +** HISTORY
2737 +** $Version $Date $Author $Comment
2738 +** 0.0.1 14 May,2009 Lei Chuanhua Initial version
2739 +*******************************************************************************/
2740 +/*!
2741 + \file ifxmips_pcie_phy.c
2742 + \ingroup IFX_PCIE
2743 + \brief PCIe PHY PLL register programming source file
2744 +*/
2745 +#include <linux/types.h>
2746 +#include <linux/kernel.h>
2747 +#include <asm/paccess.h>
2748 +#include <linux/delay.h>
2749 +
2750 +#include "ifxmips_pcie_reg.h"
2751 +#include "ifxmips_pcie.h"
2752 +
2753 +/* PCIe PDI only supports 16 bit operation */
2754 +
2755 +#define IFX_PCIE_PHY_REG_WRITE16(__addr, __data) \
2756 + ((*(volatile u16 *) (__addr)) = (__data))
2757 +
2758 +#define IFX_PCIE_PHY_REG_READ16(__addr) \
2759 + (*(volatile u16 *) (__addr))
2760 +
2761 +#define IFX_PCIE_PHY_REG16(__addr) \
2762 + (*(volatile u16 *) (__addr))
2763 +
2764 +#define IFX_PCIE_PHY_REG(__reg, __value, __mask) do { \
2765 + u16 read_data; \
2766 + u16 write_data; \
2767 + read_data = IFX_PCIE_PHY_REG_READ16((__reg)); \
2768 + write_data = (read_data & ((u16)~(__mask))) | (((u16)(__value)) & ((u16)(__mask)));\
2769 + IFX_PCIE_PHY_REG_WRITE16((__reg), write_data); \
2770 +} while (0)
2771 +
2772 +#define IFX_PCIE_PLL_TIMEOUT 1000 /* Tunnable */
2773 +
2774 +//#define IFX_PCI_PHY_REG_DUMP
2775 +
2776 +#ifdef IFX_PCI_PHY_REG_DUMP
2777 +static void
2778 +pcie_phy_reg_dump(int pcie_port)
2779 +{
2780 + printk("PLL REGFILE\n");
2781 + printk("PCIE_PHY_PLL_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL1(pcie_port)));
2782 + printk("PCIE_PHY_PLL_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL2(pcie_port)));
2783 + printk("PCIE_PHY_PLL_CTRL3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL3(pcie_port)));
2784 + printk("PCIE_PHY_PLL_CTRL4 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL4(pcie_port)));
2785 + printk("PCIE_PHY_PLL_CTRL5 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL5(pcie_port)));
2786 + printk("PCIE_PHY_PLL_CTRL6 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL6(pcie_port)));
2787 + printk("PCIE_PHY_PLL_CTRL7 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_CTRL7(pcie_port)));
2788 + printk("PCIE_PHY_PLL_A_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_A_CTRL1(pcie_port)));
2789 + printk("PCIE_PHY_PLL_A_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_A_CTRL2(pcie_port)));
2790 + printk("PCIE_PHY_PLL_A_CTRL3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_A_CTRL3(pcie_port)));
2791 + printk("PCIE_PHY_PLL_STATUS 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_STATUS(pcie_port)));
2792 +
2793 + printk("TX1 REGFILE\n");
2794 + printk("PCIE_PHY_TX1_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_CTRL1(pcie_port)));
2795 + printk("PCIE_PHY_TX1_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_CTRL2(pcie_port)));
2796 + printk("PCIE_PHY_TX1_CTRL3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_CTRL3(pcie_port)));
2797 + printk("PCIE_PHY_TX1_A_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_A_CTRL1(pcie_port)));
2798 + printk("PCIE_PHY_TX1_A_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_A_CTRL2(pcie_port)));
2799 + printk("PCIE_PHY_TX1_MOD1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_MOD1(pcie_port)));
2800 + printk("PCIE_PHY_TX1_MOD2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_MOD2(pcie_port)));
2801 + printk("PCIE_PHY_TX1_MOD3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX1_MOD3(pcie_port)));
2802 +
2803 + printk("TX2 REGFILE\n");
2804 + printk("PCIE_PHY_TX2_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_CTRL1(pcie_port)));
2805 + printk("PCIE_PHY_TX2_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_CTRL2(pcie_port)));
2806 + printk("PCIE_PHY_TX2_A_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_A_CTRL1(pcie_port)));
2807 + printk("PCIE_PHY_TX2_A_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_A_CTRL2(pcie_port)));
2808 + printk("PCIE_PHY_TX2_MOD1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_MOD1(pcie_port)));
2809 + printk("PCIE_PHY_TX2_MOD2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_MOD2(pcie_port)));
2810 + printk("PCIE_PHY_TX2_MOD3 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_TX2_MOD3(pcie_port)));
2811 +
2812 + printk("RX1 REGFILE\n");
2813 + printk("PCIE_PHY_RX1_CTRL1 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_CTRL1(pcie_port)));
2814 + printk("PCIE_PHY_RX1_CTRL2 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_CTRL2(pcie_port)));
2815 + printk("PCIE_PHY_RX1_CDR 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_CDR(pcie_port)));
2816 + printk("PCIE_PHY_RX1_EI 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_EI(pcie_port)));
2817 + printk("PCIE_PHY_RX1_A_CTRL 0x%04x\n", IFX_PCIE_PHY_REG16(PCIE_PHY_RX1_A_CTRL(pcie_port)));
2818 +}
2819 +#endif /* IFX_PCI_PHY_REG_DUMP */
2820 +
2821 +static void
2822 +pcie_phy_comm_setup(int pcie_port)
2823 +{
2824 + /* PLL Setting */
2825 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL1(pcie_port), 0x120e, 0xFFFF);
2826 +
2827 + /* increase the bias reference voltage */
2828 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x39D7, 0xFFFF);
2829 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x0900, 0xFFFF);
2830 +
2831 + /* Endcnt */
2832 + IFX_PCIE_PHY_REG(PCIE_PHY_RX1_EI(pcie_port), 0x0004, 0xFFFF);
2833 + IFX_PCIE_PHY_REG(PCIE_PHY_RX1_A_CTRL(pcie_port), 0x6803, 0xFFFF);
2834 +
2835 + /* force */
2836 + IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0008, 0x0008);
2837 +
2838 + /* predrv_ser_en */
2839 + IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL2(pcie_port), 0x0706, 0xFFFF);
2840 +
2841 + /* ctrl_lim */
2842 + IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL3(pcie_port), 0x1FFF, 0xFFFF);
2843 +
2844 + /* ctrl */
2845 + IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL1(pcie_port), 0x0800, 0xFF00);
2846 +
2847 + /* predrv_ser_en */
2848 + IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4702, 0x7F00);
2849 +
2850 + /* RTERM*/
2851 + IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL2(pcie_port), 0x2e00, 0xFFFF);
2852 +
2853 + /* Improved 100MHz clock output */
2854 + IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL2(pcie_port), 0x3096, 0xFFFF);
2855 + IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4707, 0xFFFF);
2856 +
2857 + /* Reduced CDR BW to avoid glitches */
2858 + IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CDR(pcie_port), 0x0235, 0xFFFF);
2859 +}
2860 +
2861 +#ifdef CONFIG_IFX_PCIE_PHY_36MHZ_MODE
2862 +static void
2863 +pcie_phy_36mhz_mode_setup(int pcie_port)
2864 +{
2865 + IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
2866 +#ifdef IFX_PCI_PHY_REG_DUMP
2867 + IFX_PCIE_PRINT(PCIE_MSG_PHY, "Initial PHY register dump\n");
2868 + pcie_phy_reg_dump(pcie_port);
2869 +#endif
2870 +
2871 + /* en_ext_mmd_div_ratio */
2872 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002);
2873 +
2874 + /* ext_mmd_div_ratio*/
2875 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070);
2876 +
2877 + /* pll_ensdm */
2878 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200);
2879 +
2880 + /* en_const_sdm */
2881 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100);
2882 +
2883 + /* mmd */
2884 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000);
2885 +
2886 + /* lf_mode */
2887 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000);
2888 +
2889 + /* const_sdm */
2890 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF);
2891 +
2892 + /* const sdm */
2893 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF);
2894 +
2895 + /* pllmod */
2896 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL7(pcie_port), 0x0002, 0xFFFF);
2897 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL6(pcie_port), 0x3a04, 0xFFFF);
2898 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL5(pcie_port), 0xfae3, 0xFFFF);
2899 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL4(pcie_port), 0x1b72, 0xFFFF);
2900 +
2901 + IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
2902 +}
2903 +#endif /* CONFIG_IFX_PCIE_PHY_36MHZ_MODE */
2904 +
2905 +#ifdef CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE
2906 +static void
2907 +pcie_phy_36mhz_ssc_mode_setup(int pcie_port)
2908 +{
2909 + IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
2910 +#ifdef IFX_PCI_PHY_REG_DUMP
2911 + IFX_PCIE_PRINT(PCIE_MSG_PHY, "Initial PHY register dump\n");
2912 + pcie_phy_reg_dump(pcie_port);
2913 +#endif
2914 +
2915 + /* PLL Setting */
2916 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL1(pcie_port), 0x120e, 0xFFFF);
2917 +
2918 + /* Increase the bias reference voltage */
2919 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x39D7, 0xFFFF);
2920 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x0900, 0xFFFF);
2921 +
2922 + /* Endcnt */
2923 + IFX_PCIE_PHY_REG(PCIE_PHY_RX1_EI(pcie_port), 0x0004, 0xFFFF);
2924 + IFX_PCIE_PHY_REG(PCIE_PHY_RX1_A_CTRL(pcie_port), 0x6803, 0xFFFF);
2925 +
2926 + /* Force */
2927 + IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0008, 0x0008);
2928 +
2929 + /* Predrv_ser_en */
2930 + IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL2(pcie_port), 0x0706, 0xFFFF);
2931 +
2932 + /* ctrl_lim */
2933 + IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL3(pcie_port), 0x1FFF, 0xFFFF);
2934 +
2935 + /* ctrl */
2936 + IFX_PCIE_PHY_REG(PCIE_PHY_TX1_A_CTRL1(pcie_port), 0x0800, 0xFF00);
2937 +
2938 + /* predrv_ser_en */
2939 + IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4702, 0x7F00);
2940 +
2941 + /* RTERM*/
2942 + IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL2(pcie_port), 0x2e00, 0xFFFF);
2943 +
2944 + /* en_ext_mmd_div_ratio */
2945 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002);
2946 +
2947 + /* ext_mmd_div_ratio*/
2948 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070);
2949 +
2950 + /* pll_ensdm */
2951 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0400, 0x0400);
2952 +
2953 + /* en_const_sdm */
2954 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200);
2955 +
2956 + /* mmd */
2957 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000);
2958 +
2959 + /* lf_mode */
2960 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000);
2961 +
2962 + /* const_sdm */
2963 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF);
2964 +
2965 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0000, 0x0100);
2966 + /* const sdm */
2967 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF);
2968 +
2969 + /* pllmod */
2970 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL7(pcie_port), 0x0002, 0xFFFF);
2971 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL6(pcie_port), 0x3a04, 0xFFFF);
2972 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL5(pcie_port), 0xfae3, 0xFFFF);
2973 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL4(pcie_port), 0x1c72, 0xFFFF);
2974 +
2975 + /* improved 100MHz clock output */
2976 + IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL2(pcie_port), 0x3096, 0xFFFF);
2977 + IFX_PCIE_PHY_REG(PCIE_PHY_TX2_A_CTRL2(pcie_port), 0x4707, 0xFFFF);
2978 +
2979 + /* reduced CDR BW to avoid glitches */
2980 + IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CDR(pcie_port), 0x0235, 0xFFFF);
2981 +
2982 + IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
2983 +}
2984 +#endif /* CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE */
2985 +
2986 +#ifdef CONFIG_IFX_PCIE_PHY_25MHZ_MODE
2987 +static void
2988 +pcie_phy_25mhz_mode_setup(int pcie_port)
2989 +{
2990 + IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
2991 +#ifdef IFX_PCI_PHY_REG_DUMP
2992 + IFX_PCIE_PRINT(PCIE_MSG_PHY, "Initial PHY register dump\n");
2993 + pcie_phy_reg_dump(pcie_port);
2994 +#endif
2995 + /* en_const_sdm */
2996 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100);
2997 +
2998 + /* pll_ensdm */
2999 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0000, 0x0200);
3000 +
3001 + /* en_ext_mmd_div_ratio*/
3002 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0002, 0x0002);
3003 +
3004 + /* ext_mmd_div_ratio*/
3005 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0040, 0x0070);
3006 +
3007 + /* mmd */
3008 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x6000, 0xe000);
3009 +
3010 + /* lf_mode */
3011 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x4000, 0x4000);
3012 +
3013 + IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
3014 +}
3015 +#endif /* CONFIG_IFX_PCIE_PHY_25MHZ_MODE */
3016 +
3017 +#ifdef CONFIG_IFX_PCIE_PHY_100MHZ_MODE
3018 +static void
3019 +pcie_phy_100mhz_mode_setup(int pcie_port)
3020 +{
3021 + IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d enter\n", __func__, pcie_port);
3022 +#ifdef IFX_PCI_PHY_REG_DUMP
3023 + IFX_PCIE_PRINT(PCIE_MSG_PHY, "Initial PHY register dump\n");
3024 + pcie_phy_reg_dump(pcie_port);
3025 +#endif
3026 + /* en_ext_mmd_div_ratio */
3027 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0002);
3028 +
3029 + /* ext_mmd_div_ratio*/
3030 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL3(pcie_port), 0x0000, 0x0070);
3031 +
3032 + /* pll_ensdm */
3033 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0200, 0x0200);
3034 +
3035 + /* en_const_sdm */
3036 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x0100, 0x0100);
3037 +
3038 + /* mmd */
3039 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL3(pcie_port), 0x2000, 0xe000);
3040 +
3041 + /* lf_mode */
3042 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_A_CTRL2(pcie_port), 0x0000, 0x4000);
3043 +
3044 + /* const_sdm */
3045 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL1(pcie_port), 0x38e4, 0xFFFF);
3046 +
3047 + /* const sdm */
3048 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL2(pcie_port), 0x00ee, 0x00FF);
3049 +
3050 + /* pllmod */
3051 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL7(pcie_port), 0x0002, 0xFFFF);
3052 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL6(pcie_port), 0x3a04, 0xFFFF);
3053 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL5(pcie_port), 0xfae3, 0xFFFF);
3054 + IFX_PCIE_PHY_REG(PCIE_PHY_PLL_CTRL4(pcie_port), 0x1b72, 0xFFFF);
3055 +
3056 + IFX_PCIE_PRINT(PCIE_MSG_PHY, "%s pcie_port %d exit\n", __func__, pcie_port);
3057 +}
3058 +#endif /* CONFIG_IFX_PCIE_PHY_100MHZ_MODE */
3059 +
3060 +static int
3061 +pcie_phy_wait_startup_ready(int pcie_port)
3062 +{
3063 + int i;
3064 +
3065 + for (i = 0; i < IFX_PCIE_PLL_TIMEOUT; i++) {
3066 + if ((IFX_PCIE_PHY_REG16(PCIE_PHY_PLL_STATUS(pcie_port)) & 0x0040) != 0) {
3067 + break;
3068 + }
3069 + udelay(10);
3070 + }
3071 + if (i >= IFX_PCIE_PLL_TIMEOUT) {
3072 + printk(KERN_ERR "%s PLL Link timeout\n", __func__);
3073 + return -1;
3074 + }
3075 + return 0;
3076 +}
3077 +
3078 +static void
3079 +pcie_phy_load_enable(int pcie_port, int slice)
3080 +{
3081 + /* Set the load_en of tx/rx slice to '1' */
3082 + switch (slice) {
3083 + case 1:
3084 + IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0010, 0x0010);
3085 + break;
3086 + case 2:
3087 + IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL1(pcie_port), 0x0010, 0x0010);
3088 + break;
3089 + case 3:
3090 + IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CTRL1(pcie_port), 0x0002, 0x0002);
3091 + break;
3092 + }
3093 +}
3094 +
3095 +static void
3096 +pcie_phy_load_disable(int pcie_port, int slice)
3097 +{
3098 + /* set the load_en of tx/rx slice to '0' */
3099 + switch (slice) {
3100 + case 1:
3101 + IFX_PCIE_PHY_REG(PCIE_PHY_TX1_CTRL1(pcie_port), 0x0000, 0x0010);
3102 + break;
3103 + case 2:
3104 + IFX_PCIE_PHY_REG(PCIE_PHY_TX2_CTRL1(pcie_port), 0x0000, 0x0010);
3105 + break;
3106 + case 3:
3107 + IFX_PCIE_PHY_REG(PCIE_PHY_RX1_CTRL1(pcie_port), 0x0000, 0x0002);
3108 + break;
3109 + }
3110 +}
3111 +
3112 +static void
3113 +pcie_phy_load_war(int pcie_port)
3114 +{
3115 + int slice;
3116 +
3117 + for (slice = 1; slice < 4; slice++) {
3118 + pcie_phy_load_enable(pcie_port, slice);
3119 + udelay(1);
3120 + pcie_phy_load_disable(pcie_port, slice);
3121 + }
3122 +}
3123 +
3124 +static void
3125 +pcie_phy_tx2_modulation(int pcie_port)
3126 +{
3127 + IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD1(pcie_port), 0x1FFE, 0xFFFF);
3128 + IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD2(pcie_port), 0xFFFE, 0xFFFF);
3129 + IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD3(pcie_port), 0x0601, 0xFFFF);
3130 + mdelay(1);
3131 + IFX_PCIE_PHY_REG(PCIE_PHY_TX2_MOD3(pcie_port), 0x0001, 0xFFFF);
3132 +}
3133 +
3134 +static void
3135 +pcie_phy_tx1_modulation(int pcie_port)
3136 +{
3137 + IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD1(pcie_port), 0x1FFE, 0xFFFF);
3138 + IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD2(pcie_port), 0xFFFE, 0xFFFF);
3139 + IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD3(pcie_port), 0x0601, 0xFFFF);
3140 + mdelay(1);
3141 + IFX_PCIE_PHY_REG(PCIE_PHY_TX1_MOD3(pcie_port), 0x0001, 0xFFFF);
3142 +}
3143 +
3144 +static void
3145 +pcie_phy_tx_modulation_war(int pcie_port)
3146 +{
3147 + int i;
3148 +
3149 +#define PCIE_PHY_MODULATION_NUM 5
3150 + for (i = 0; i < PCIE_PHY_MODULATION_NUM; i++) {
3151 + pcie_phy_tx2_modulation(pcie_port);
3152 + pcie_phy_tx1_modulation(pcie_port);
3153 + }
3154 +#undef PCIE_PHY_MODULATION_NUM
3155 +}
3156 +
3157 +void
3158 +pcie_phy_clock_mode_setup(int pcie_port)
3159 +{
3160 + pcie_pdi_big_endian(pcie_port);
3161 +
3162 + /* Enable PDI to access PCIe PHY register */
3163 + pcie_pdi_pmu_enable(pcie_port);
3164 +
3165 + /* Configure PLL and PHY clock */
3166 + pcie_phy_comm_setup(pcie_port);
3167 +
3168 +#ifdef CONFIG_IFX_PCIE_PHY_36MHZ_MODE
3169 + pcie_phy_36mhz_mode_setup(pcie_port);
3170 +#elif defined(CONFIG_IFX_PCIE_PHY_36MHZ_SSC_MODE)
3171 + pcie_phy_36mhz_ssc_mode_setup(pcie_port);
3172 +#elif defined(CONFIG_IFX_PCIE_PHY_25MHZ_MODE)
3173 + pcie_phy_25mhz_mode_setup(pcie_port);
3174 +#elif defined (CONFIG_IFX_PCIE_PHY_100MHZ_MODE)
3175 + pcie_phy_100mhz_mode_setup(pcie_port);
3176 +#else
3177 + #error "PCIE PHY Clock Mode must be chosen first!!!!"
3178 +#endif /* CONFIG_IFX_PCIE_PHY_36MHZ_MODE */
3179 +
3180 + /* Enable PCIe PHY and make PLL setting take effect */
3181 + pcie_phy_pmu_enable(pcie_port);
3182 +
3183 + /* Check if we are in startup_ready status */
3184 + pcie_phy_wait_startup_ready(pcie_port);
3185 +
3186 + pcie_phy_load_war(pcie_port);
3187 +
3188 + /* Apply TX modulation workarounds */
3189 + pcie_phy_tx_modulation_war(pcie_port);
3190 +
3191 +#ifdef IFX_PCI_PHY_REG_DUMP
3192 + IFX_PCIE_PRINT(PCIE_MSG_PHY, "Modified PHY register dump\n");
3193 + pcie_phy_reg_dump(pcie_port);
3194 +#endif
3195 +}
3196 +
3197 diff --git a/arch/mips/pci/ifxmips_pcie_pm.c b/arch/mips/pci/ifxmips_pcie_pm.c
3198 new file mode 100644
3199 index 0000000..a10ecad
3200 --- /dev/null
3201 +++ b/arch/mips/pci/ifxmips_pcie_pm.c
3202 @@ -0,0 +1,176 @@
3203 +/******************************************************************************
3204 +**
3205 +** FILE NAME : ifxmips_pcie_pm.c
3206 +** PROJECT : IFX UEIP
3207 +** MODULES : PCIE Root Complex Driver
3208 +**
3209 +** DATE : 21 Dec 2009
3210 +** AUTHOR : Lei Chuanhua
3211 +** DESCRIPTION : PCIE Root Complex Driver Power Managment
3212 +** COPYRIGHT : Copyright (c) 2009
3213 +** Lantiq Deutschland GmbH
3214 +** Am Campeon 3, 85579 Neubiberg, Germany
3215 +**
3216 +** This program is free software; you can redistribute it and/or modify
3217 +** it under the terms of the GNU General Public License as published by
3218 +** the Free Software Foundation; either version 2 of the License, or
3219 +** (at your option) any later version.
3220 +**
3221 +** HISTORY
3222 +** $Date $Author $Comment
3223 +** 21 Dec,2009 Lei Chuanhua First UEIP release
3224 +*******************************************************************************/
3225 +/*!
3226 + \defgroup IFX_PCIE_PM Power Management functions
3227 + \ingroup IFX_PCIE
3228 + \brief IFX PCIE Root Complex Driver power management functions
3229 +*/
3230 +
3231 +/*!
3232 + \file ifxmips_pcie_pm.c
3233 + \ingroup IFX_PCIE
3234 + \brief source file for PCIE Root Complex Driver Power Management
3235 +*/
3236 +
3237 +#ifndef EXPORT_SYMTAB
3238 +#define EXPORT_SYMTAB
3239 +#endif
3240 +#ifndef AUTOCONF_INCLUDED
3241 +#include <linux/config.h>
3242 +#endif /* AUTOCONF_INCLUDED */
3243 +#include <linux/version.h>
3244 +#include <linux/module.h>
3245 +#include <linux/types.h>
3246 +#include <linux/kernel.h>
3247 +#include <asm/system.h>
3248 +
3249 +/* Project header */
3250 +#include <asm/ifx/ifx_types.h>
3251 +#include <asm/ifx/ifx_regs.h>
3252 +#include <asm/ifx/common_routines.h>
3253 +#include <asm/ifx/ifx_pmcu.h>
3254 +#include "ifxmips_pcie_pm.h"
3255 +
3256 +/**
3257 + * \fn static IFX_PMCU_RETURN_t ifx_pcie_pmcu_state_change(IFX_PMCU_STATE_t pmcuState)
3258 + * \brief the callback function to request pmcu state in the power management hardware-dependent module
3259 + *
3260 + * \param pmcuState This parameter is a PMCU state.
3261 + *
3262 + * \return IFX_PMCU_RETURN_SUCCESS Set Power State successfully
3263 + * \return IFX_PMCU_RETURN_ERROR Failed to set power state.
3264 + * \return IFX_PMCU_RETURN_DENIED Not allowed to operate power state
3265 + * \ingroup IFX_PCIE_PM
3266 + */
3267 +static IFX_PMCU_RETURN_t
3268 +ifx_pcie_pmcu_state_change(IFX_PMCU_STATE_t pmcuState)
3269 +{
3270 + switch(pmcuState)
3271 + {
3272 + case IFX_PMCU_STATE_D0:
3273 + return IFX_PMCU_RETURN_SUCCESS;
3274 + case IFX_PMCU_STATE_D1: // Not Applicable
3275 + return IFX_PMCU_RETURN_DENIED;
3276 + case IFX_PMCU_STATE_D2: // Not Applicable
3277 + return IFX_PMCU_RETURN_DENIED;
3278 + case IFX_PMCU_STATE_D3: // Module clock gating and Power gating
3279 + return IFX_PMCU_RETURN_SUCCESS;
3280 + default:
3281 + return IFX_PMCU_RETURN_DENIED;
3282 + }
3283 +}
3284 +
3285 +/**
3286 + * \fn static IFX_PMCU_RETURN_t ifx_pcie_pmcu_state_get(IFX_PMCU_STATE_t *pmcuState)
3287 + * \brief the callback function to get pmcu state in the power management hardware-dependent module
3288 +
3289 + * \param pmcuState Pointer to return power state.
3290 + *
3291 + * \return IFX_PMCU_RETURN_SUCCESS Set Power State successfully
3292 + * \return IFX_PMCU_RETURN_ERROR Failed to set power state.
3293 + * \return IFX_PMCU_RETURN_DENIED Not allowed to operate power state
3294 + * \ingroup IFX_PCIE_PM
3295 + */
3296 +static IFX_PMCU_RETURN_t
3297 +ifx_pcie_pmcu_state_get(IFX_PMCU_STATE_t *pmcuState)
3298 +{
3299 + return IFX_PMCU_RETURN_SUCCESS;
3300 +}
3301 +
3302 +/**
3303 + * \fn IFX_PMCU_RETURN_t ifx_pcie_pmcu_prechange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
3304 + * \brief Apply all callbacks registered to be executed before a state change for pmcuModule
3305 + *
3306 + * \param pmcuModule Module
3307 + * \param newState New state
3308 + * \param oldState Old state
3309 + * \return IFX_PMCU_RETURN_SUCCESS Set Power State successfully
3310 + * \return IFX_PMCU_RETURN_ERROR Failed to set power state.
3311 + * \ingroup IFX_PCIE_PM
3312 + */
3313 +static IFX_PMCU_RETURN_t
3314 +ifx_pcie_pmcu_prechange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
3315 +{
3316 + return IFX_PMCU_RETURN_SUCCESS;
3317 +}
3318 +
3319 +/**
3320 + * \fn IFX_PMCU_RETURN_t ifx_pcie_pmcu_postchange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
3321 + * \brief Apply all callbacks registered to be executed before a state change for pmcuModule
3322 + *
3323 + * \param pmcuModule Module
3324 + * \param newState New state
3325 + * \param oldState Old state
3326 + * \return IFX_PMCU_RETURN_SUCCESS Set Power State successfully
3327 + * \return IFX_PMCU_RETURN_ERROR Failed to set power state.
3328 + * \ingroup IFX_PCIE_PM
3329 + */
3330 +static IFX_PMCU_RETURN_t
3331 +ifx_pcie_pmcu_postchange(IFX_PMCU_MODULE_t pmcuModule, IFX_PMCU_STATE_t newState, IFX_PMCU_STATE_t oldState)
3332 +{
3333 + return IFX_PMCU_RETURN_SUCCESS;
3334 +}
3335 +
3336 +/**
3337 + * \fn static void ifx_pcie_pmcu_init(void)
3338 + * \brief Register with central PMCU module
3339 + * \return none
3340 + * \ingroup IFX_PCIE_PM
3341 + */
3342 +void
3343 +ifx_pcie_pmcu_init(void)
3344 +{
3345 + IFX_PMCU_REGISTER_t pmcuRegister;
3346 +
3347 + /* XXX, hook driver context */
3348 +
3349 + /* State function register */
3350 + memset(&pmcuRegister, 0, sizeof(IFX_PMCU_REGISTER_t));
3351 + pmcuRegister.pmcuModule = IFX_PMCU_MODULE_PCIE;
3352 + pmcuRegister.pmcuModuleNr = 0;