Commit c8e482cf72929228b06adf82a0772ed060eb77c2

Authored by Aurelian Floricica
Committed by Larisa Grigore
1 parent b3d4a0d4bd

s32v234pcie: Bring in fix for link reset recovery

Enable EP ignoring ERR009852

Signed-off-by: Heinz Wrobel <Heinz.Wrobel@freescale.com>
Signed-off-by: Aurelian Floricica <b43657@freescale.com>
Signed-off-by: Costin Carabas <costin.carabas@nxp.com>
Signed-off-by: Stefan-Gabriel Mirea <stefan-gabriel.mirea@nxp.com>
Signed-off-by: Larisa Grigore <larisa.grigore@nxp.com>

Showing 7 changed files with 664 additions and 186 deletions Side-by-side Diff

arch/arm/cpu/armv8/s32v234/Makefile
... ... @@ -14,4 +14,5 @@
14 14 obj-$(CONFIG_S32V234_FLASH) += qspi_driver.o
15 15 obj-$(CONFIG_S32V234_USES_FLASH) += qspi_common.o
16 16 obj-$(CONFIG_FSL_DCU_FB) += dcu.o
  17 +obj-$(CONFIG_GICSUPPORT) += gicsupport.o
arch/arm/cpu/armv8/s32v234/gicsupport.c
  1 +// SPDX-License-Identifier: GPL-2.0+
  2 +/*
  3 + * (C) Copyright 2016,2020 NXP
  4 + * Heinz Wrobel <Heinz.Wrobel@nxp.com>
  5 + *
  6 + * Basic GIC support to permit dealing with interrupt handlers in ARMv8.
  7 + * This code is currently only tested on S32V234, but should be generic
  8 + * enough to be placed outside a CPU specific directory at some point.
  9 + * We ignore SGI/PPI because that is done in gic_64.S.
  10 + *
  11 + * Some of this code is taken from sources developed by <Jay.Tu@nxp.com>
  12 + */
  13 +
  14 +#include <common.h>
  15 +#include <linux/compiler.h>
  16 +#include <asm/io.h>
  17 +#include <asm/gicsupport.h>
  18 +#include <asm/gic.h>
  19 +#include <asm/proc-armv/system.h>
  20 +
  21 +#define GICD_INVALID_IRQ (-1)
  22 +
  23 +#define GICD_ICENABLERn_CLEAR_MASK (0xffffffff)
  24 +
  25 +#define HWIRQ_BIT(irq) BIT((irq) & 0x1f)
  26 +#define HWIRQ_BANK(irq) (((irq) >> 5) * sizeof(u32))
  27 +
  28 +#define HWIRQ_BANK_2BITS(irq) (((irq) >> 4) * sizeof(u32))
  29 +
  30 +#define GICD_INT_DEF_TARGET (0x01)
  31 +#define GICD_INT_DEF_TARGET_X4 ((GICD_INT_DEF_TARGET << 24) |\
  32 + (GICD_INT_DEF_TARGET << 16) |\
  33 + (GICD_INT_DEF_TARGET << 8) |\
  34 + GICD_INT_DEF_TARGET)
  35 +
  36 +#define GICD_INT_DEF_PRI (0xa0)
  37 +#define GICD_INT_DEF_PRI_X4 ((GICD_INT_DEF_PRI << 24) |\
  38 + (GICD_INT_DEF_PRI << 16) |\
  39 + (GICD_INT_DEF_PRI << 8) |\
  40 + GICD_INT_DEF_PRI)
  41 +
  42 +#define GICD_TYPER_SPIS(typer) ((((typer) & 0x1f) + 1) * 32)
  43 +#define GICD_CTLR_ENABLE_G1A BIT(1)
  44 +#define GICD_CTLR_ENABLE_G1 BIT(0)
  45 +#define GICR_PROPBASER_IDBITS_MASK (0x1f)
  46 +#define GICC_PMR_PRIORITY (0xff)
  47 +
  48 +#define GICD_ICFGR_MASK (0x3)
  49 +#define GICD_ICFGR_IRQ_SHIFT(irq) (((irq) & 0x0f) * 2)
  50 +#define GICD_ICFGR_IRQ_MASK(irq) (GICD_ICFGR_MASK << \
  51 + GICD_ICFGR_IRQ_SHIFT(irq))
  52 +#define GICD_ICFGR_IRQ_TYPE(type, irq) ((type & GICD_ICFGR_MASK) << \
  53 + GICD_ICFGR_IRQ_SHIFT(irq))
  54 +
  55 +#define GIC_SUPPORTED_HANDLERS (16)
  56 +
  57 +#define GIC_GROUP_IRQ (1022)
  58 +#define GIC_SPURIOUS_IRQ (1023)
  59 +
  60 +/* A performance implementation would use an indexed table.
  61 + * U-Boot has a need for a small footprint, so we do a simple search
  62 + * and only support a few handlers concurrently.
  63 + */
  64 +static struct
  65 +{
  66 + int irq;
  67 + void (*handler)(struct pt_regs *pt_regs, unsigned int esr);
  68 + const char *name;
  69 + int type;
  70 + u32 count;
  71 +} inthandlers[GIC_SUPPORTED_HANDLERS];
  72 +
  73 +static u32 count_spurious;
  74 +static bool pre_init_done, full_init_done;
  75 +
  76 +static void interrupt_handler_init(void)
  77 +{
  78 + /* We need to decouple this init from the generic
  79 + * interrupt_init() function because interrupt handlers
  80 + * may be preregistered by code before the GIC init has
  81 + * happened! PCIe support is a good example for this.
  82 + */
  83 + int i;
  84 +
  85 + if (!pre_init_done) {
  86 + pre_init_done = 1;
  87 + /* Make sure that we do not have any active handlers */
  88 + for (i = 0; i < ARRAY_SIZE(inthandlers); i++) {
  89 + inthandlers[i].irq = GICD_INVALID_IRQ;
  90 + inthandlers[i].count = 0;
  91 + }
  92 + count_spurious = 0;
  93 + }
  94 +}
  95 +
  96 +/* Function to support handlers. Benign to call before GIC init */
  97 +static void gic_unmask_irq(unsigned int irq)
  98 +{
  99 + u32 mask;
  100 +
  101 + if (full_init_done) {
  102 + mask = HWIRQ_BIT(irq);
  103 + writel(mask,
  104 + GICD_BASE + GICD_ISENABLERn + HWIRQ_BANK(irq));
  105 + }
  106 +}
  107 +
  108 +/* Function to support handlers. Benign to call before GIC init */
  109 +static void gic_mask_irq(unsigned int irq)
  110 +{
  111 + u32 mask = HWIRQ_BIT(irq);
  112 +
  113 + writel(mask, GICD_BASE + GICD_ICENABLERn + HWIRQ_BANK(irq));
  114 +}
  115 +
  116 +/* Function to support handlers. Benign to call before GIC init */
  117 +static void gic_set_type(unsigned int irq, int type)
  118 +{
  119 + u32 icfgr;
  120 +
  121 + if (full_init_done) {
  122 + icfgr = readl(GICD_BASE + GICD_ICFGR +
  123 + HWIRQ_BANK_2BITS(irq));
  124 + icfgr &= ~GICD_ICFGR_IRQ_MASK(irq);
  125 + icfgr |= GICD_ICFGR_IRQ_TYPE(type, irq);
  126 + writel(icfgr,
  127 + GICD_BASE + GICD_ICFGR + HWIRQ_BANK_2BITS(irq));
  128 + }
  129 +}
  130 +
  131 +static void gic_dist_init(unsigned long base)
  132 +{
  133 + unsigned int gic_irqs, i;
  134 + u32 ctlr = readl(base + GICD_CTLR);
  135 +
  136 + /* We turn off the GIC while we mess with it.
  137 + * The original init has happened in gic_64.S!
  138 + */
  139 + writel(ctlr & ~(GICD_CTLR_ENABLE_G1A | GICD_CTLR_ENABLE_G1),
  140 + base + GICD_CTLR);
  141 +
  142 + gic_irqs = GICD_TYPER_SPIS(readl(base + GICD_TYPER));
  143 +
  144 + /*
  145 + * Set all global interrupts to be level triggered, active low.
  146 + */
  147 + for (i = 32; i < gic_irqs; i += 16)
  148 + writel(0, base + GICD_ICFGR + i / 4);
  149 +
  150 + /*
  151 + * Set all global interrupts to this CPU only.
  152 + */
  153 + for (i = 32; i < gic_irqs; i += 4)
  154 + writel(GICD_INT_DEF_TARGET_X4, base + GICD_ITARGETSRn + i);
  155 +
  156 + /*
  157 + * Set priority on all global interrupts.
  158 + */
  159 +
  160 + for (i = 32; i < gic_irqs; i += 4)
  161 + writel(GICD_INT_DEF_PRI_X4, base + GICD_IPRIORITYRn + i);
  162 +
  163 + /*
  164 + * Disable all interrupts. Leave the PPI and SGIs alone
  165 + * as these enables are banked registers.
  166 + */
  167 + for (i = 32; i < gic_irqs; i += 32)
  168 + writel(GICD_ICENABLERn_CLEAR_MASK,
  169 + base + GICD_ICENABLERn + i / 8);
  170 +
  171 + writel(ctlr, base + GICD_CTLR);
  172 +}
  173 +
  174 +static void gic_cpu_clean(unsigned long dist_base, unsigned long cpu_base)
  175 +{
  176 + /* Initially we need to make sure that we do not have any
  177 + * left over requests that could cause a mess during
  178 + * initialization. This happens during sloppy SMP init in
  179 + * lowlevel.S and should be FIXED. *sigh*
  180 + */
  181 + writel(GICD_ICENABLERn_CLEAR_MASK, dist_base + GICD_ICENABLERn);
  182 +}
  183 +
  184 +static void gic_cpu_init(unsigned long dist_base, unsigned long cpu_base)
  185 +{
  186 + /* Accept just about anything */
  187 + writel(GICC_PMR_PRIORITY, cpu_base + GICC_PMR);
  188 +
  189 + /* gic_64.S doesn't set the recommended AckCtl value. We do */
  190 + writel(0x1e3, cpu_base + GICC_CTLR);
  191 +}
  192 +
  193 +/* Public function to support handlers. Benign to call before GIC init */
  194 +int gic_irq_status(unsigned int irq)
  195 +{
  196 + u32 mask = HWIRQ_BIT(irq);
  197 + u32 v = readl(GICD_BASE + GICD_ISPENDRn + HWIRQ_BANK(irq));
  198 +
  199 + return !!(v & mask);
  200 +}
  201 +
  202 +int gic_register_handler(int irq,
  203 + void (*handler)(struct pt_regs *pt_regs,
  204 + unsigned int esr), int type,
  205 + const char *name)
  206 +{
  207 + int i;
  208 +
  209 + interrupt_handler_init();
  210 +
  211 + if (full_init_done)
  212 + gic_mask_irq(irq);
  213 +
  214 + for (i = 0; i < ARRAY_SIZE(inthandlers); i++) {
  215 + if (inthandlers[i].irq < 0) {
  216 + inthandlers[i].handler = handler;
  217 + inthandlers[i].name = name;
  218 + inthandlers[i].type = type;
  219 +
  220 + /* Done last to avoid race condition */
  221 + inthandlers[i].irq = irq;
  222 +
  223 + if (full_init_done) {
  224 + gic_set_type(irq, type);
  225 + gic_unmask_irq(irq);
  226 + }
  227 + break;
  228 + }
  229 + }
  230 +
  231 + return i >= ARRAY_SIZE(inthandlers) ? 0 : 1;
  232 +}
  233 +
  234 +int interrupt_init(void)
  235 +{
  236 + int i;
  237 +
  238 + interrupt_handler_init();
  239 +
  240 + gic_cpu_clean(GICD_BASE, GICC_BASE);
  241 +
  242 + gic_dist_init(GICD_BASE);
  243 +
  244 + /* U-Boot runs with a single CPU only */
  245 + gic_cpu_init(GICD_BASE, GICC_BASE);
  246 +
  247 + full_init_done = 1;
  248 +
  249 + /* Now that we have set up the GIC, we need to start up
  250 + * any preregistered handlers.
  251 + */
  252 + for (i = 0; i < ARRAY_SIZE(inthandlers); i++) {
  253 + int irq = inthandlers[i].irq;
  254 +
  255 + if (irq >= 0) {
  256 + gic_set_type(irq, inthandlers[i].type);
  257 + gic_unmask_irq(irq);
  258 + }
  259 + }
  260 +
  261 + return 0;
  262 +}
  263 +
  264 +void enable_interrupts(void)
  265 +{
  266 + local_irq_enable();
  267 +}
  268 +
  269 +int disable_interrupts(void)
  270 +{
  271 + int flags;
  272 +
  273 + local_irq_save(flags);
  274 +
  275 + return flags;
  276 +}
  277 +
  278 +void do_irq(struct pt_regs *pt_regs, unsigned int esr)
  279 +{
  280 + int i, group = 0;
  281 + u32 thisirq = readl(GICC_BASE + GICC_IAR);
  282 +
  283 + if (thisirq == GIC_GROUP_IRQ) {
  284 + /* Group 1 interrupt! */
  285 + group = 1;
  286 + thisirq = readl(GICC_BASE + GICC_AIAR);
  287 + }
  288 +
  289 + if (thisirq == GIC_SPURIOUS_IRQ) {
  290 + count_spurious++;
  291 + return;
  292 + }
  293 +
  294 + for (i = 0; i < ARRAY_SIZE(inthandlers); i++) {
  295 + if (inthandlers[i].irq == thisirq) {
  296 + inthandlers[i].count++;
  297 + inthandlers[i].handler(pt_regs, esr);
  298 +
  299 + break;
  300 + }
  301 + }
  302 +
  303 + if (group)
  304 + writel(thisirq, GICC_BASE + GICC_AEOIR);
  305 + else
  306 + writel(thisirq, GICC_BASE + GICC_EOIR);
  307 +
  308 + if (i >= ARRAY_SIZE(inthandlers)) {
  309 + printf("\"Irq\" handler, esr 0x%08x for GIC irq %d, group %d\n",
  310 + esr, thisirq, group);
  311 + show_regs(pt_regs);
  312 + panic("Resetting CPU ...\n");
  313 + }
  314 +}
  315 +
  316 +#if defined(CONFIG_CMD_IRQ)
  317 +int do_irqinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
  318 +{
  319 + int i;
  320 +
  321 + printf("GIC support is enabled for GIC @ 0x%08x\n", GICD_BASE);
  322 + printf("Spurious: %d\n", count_spurious);
  323 + for (i = 0; i < ARRAY_SIZE(inthandlers); i++) {
  324 + if (inthandlers[i].irq >= 0) {
  325 + printf("%20s(%d): %d\n", inthandlers[i].name,
  326 + inthandlers[i].irq,
  327 + inthandlers[i].count);
  328 + }
  329 + }
  330 +
  331 + return 0;
  332 +}
  333 +#endif
arch/arm/include/asm/gicsupport.h
  1 +/* SPDX-License-Identifier: GPL-2.0+ */
  2 +/*
  3 + * Copyright 2016 NXP
  4 + *
  5 + */
  6 + /* Functions declared in arch/arm/cpu/armv8/s32/gicsupport.c */
  7 +int gic_irq_status(unsigned int irq);
  8 +int gic_register_handler(int irq,
  9 + void (*handler)(struct pt_regs *pt_regs,
  10 + unsigned int esr),
  11 + int type, const char *name);
arch/arm/lib/interrupts_64.c
1 1 // SPDX-License-Identifier: GPL-2.0+
2 2 /*
3 3 * (C) Copyright 2013
  4 + * Copyright 2016,2020 NXP
4 5 * David Feng <fenghua@phytium.com.cn>
5 6 */
6 7  
7 8  
8 9  
9 10  
... ... @@ -11,21 +12,28 @@
11 12  
12 13 DECLARE_GLOBAL_DATA_PTR;
13 14  
14   -int interrupt_init(void)
  15 +int __interrupt_init(void)
15 16 {
16 17 return 0;
17 18 }
18 19  
19   -void enable_interrupts(void)
  20 +void __enable_interrupts(void)
20 21 {
21 22 return;
22 23 }
23 24  
24   -int disable_interrupts(void)
  25 +int __disable_interrupts(void)
25 26 {
26 27 return 0;
27 28 }
28 29  
  30 +int interrupt_init(void)
  31 + __attribute__((weak, alias("__interrupt_init")));
  32 +void enable_interrupts(void)
  33 + __attribute__((weak, alias("__enable_interrupts")));
  34 +int disable_interrupts(void)
  35 + __attribute__((weak, alias("__disable_interrupts")));
  36 +
29 37 static void show_efi_loaded_images(struct pt_regs *regs)
30 38 {
31 39 efi_print_image_infos((void *)regs->elr);
32 40  
... ... @@ -120,9 +128,9 @@
120 128 }
121 129  
122 130 /*
123   - * do_irq handles the Irq exception.
  131 + * __do_irq handles the Irq exception.
124 132 */
125   -void do_irq(struct pt_regs *pt_regs, unsigned int esr)
  133 +void __do_irq(struct pt_regs *pt_regs, unsigned int esr)
126 134 {
127 135 efi_restore_gd();
128 136 printf("\"Irq\" handler, esr 0x%08x\n", esr);
129 137  
... ... @@ -132,9 +140,9 @@
132 140 }
133 141  
134 142 /*
135   - * do_fiq handles the Fiq exception.
  143 + * __do_fiq handles the Fiq exception.
136 144 */
137   -void do_fiq(struct pt_regs *pt_regs, unsigned int esr)
  145 +void __do_fiq(struct pt_regs *pt_regs, unsigned int esr)
138 146 {
139 147 efi_restore_gd();
140 148 printf("\"Fiq\" handler, esr 0x%08x\n", esr);
... ... @@ -142,6 +150,11 @@
142 150 show_efi_loaded_images(pt_regs);
143 151 panic("Resetting CPU ...\n");
144 152 }
  153 +
  154 +void do_irq(struct pt_regs *pt_regs, unsigned int esr)
  155 + __attribute__((weak, alias("__do_irq")));
  156 +void do_fiq(struct pt_regs *pt_regs, unsigned int esr)
  157 + __attribute__((weak, alias("__do_fiq")));
145 158  
146 159 /*
147 160 * do_error handles the Error exception.
drivers/pci/pcie_s32v2xx.c
... ... @@ -2,8 +2,9 @@
2 2 /*
3 3 * Freescale S32V234 PCI Express Root-Complex driver
4 4 *
5   - * Copyright (C) 2013 Marek Vasut <marex@denx.de>
6   - * Copyright 2020 NXP
  5 + * Copyright (C) 2016 Heinz Wrobel <heinz.wrobel@nxp.com>
  6 + * Copyright (C) 2015 Aurelian Voicu <aurelian.voicu@nxp.com>
  7 + * Copyright (C) 2016,2020 NXP
7 8 *
8 9 * Based on upstream iMX U-Boot driver:
9 10 * pcie_imx.c: Marek Vasut <marex@denx.de>
... ... @@ -19,6 +20,7 @@
19 20 #include <asm/arch/mc_me_regs.h>
20 21 #include <asm/arch/mc_cgm_regs.h>
21 22 #include <asm/io.h>
  23 +#include <asm/gicsupport.h>
22 24 #include <linux/sizes.h>
23 25  
24 26 #define PCI_ACCESS_READ 0
25 27  
26 28  
... ... @@ -82,30 +84,32 @@
82 84 #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
83 85 #define PCIE_ATU_UPPER_TARGET 0x91C
84 86  
85   -#ifdef CONFIG_PCIE_EP_MODE
  87 +/* The following defines are used for EP mode only */
86 88 #define MSI_REGION 0x72FB0000
87   -#define PCI_BASE_ADDR 0x72000000
88   -#define PCI_BASE_DBI 0x72FFC000
89   -#define MSI_REGION_NR 3
90   -#define NR_REGIONS 4
91   -#define PCI_REGION_MEM 0x00000000 /* PCI mem space */
92   -#define PCI_REGION_IO 0x00000001 /* PCI IO space */
93   -#define PCI_WIDTH_32b 0x00000000 /* 32-bit BAR */
94   -#define PCI_WIDTH_64b 0x00000004 /* 64-bit BAR */
95   -#define PCI_REGION_PREFETCH 0x00000008 /* prefetch PCI mem */
96   -#define PCI_REGION_NON_PREFETCH 0x00000000 /* non-prefetch PCI mem */
97   -#define PCIE_BAR0_SIZE SZ_1M /* 1MB */
98   -#define PCIE_BAR1_SIZE 0
99   -#define PCIE_BAR2_SIZE SZ_1M /* 1MB */
100   -#define PCIE_BAR3_SIZE 0 /* 256B Fixed sizing */
101   -#define PCIE_BAR4_SIZE 0 /* 4K Fixed sizing */
102   -#define PCIE_BAR5_SIZE 0 /* 64K Fixed sizing */
  89 +#define PCI_BASE_ADDR 0x72000000
  90 +#define PCI_BASE_DBI 0x72FFC000
  91 +#define MSI_REGION_NR 3
  92 +#define NR_REGIONS 4
  93 +#define PCI_REGION_MEM 0x00000000 /* PCI mem space */
  94 +#define PCI_REGION_IO 0x00000001 /* PCI IO space */
  95 +#define PCI_WIDTH_32b 0x00000000 /* 32-bit BAR */
  96 +#define PCI_WIDTH_64b 0x00000004 /* 64-bit BAR */
  97 +#define PCI_REGION_PREFETCH 0x00000008 /* prefetch PCI mem */
  98 +#define PCI_REGION_NON_PREFETCH 0x00000000 /* non-prefetch PCI mem */
  99 +#define PCIE_BAR0_SIZE SZ_1M /* 1MB */
  100 +#define PCIE_BAR1_SIZE 0
  101 +#define PCIE_BAR2_SIZE SZ_1M /* 1MB */
  102 +#define PCIE_BAR3_SIZE 0
  103 +#define PCIE_BAR4_SIZE 0
  104 +#define PCIE_BAR5_SIZE 0
  105 +#define PCIE_ROM_SIZE 0
103 106 #define PCIE_BAR0_EN_DIS 1
104 107 #define PCIE_BAR1_EN_DIS 0
105 108 #define PCIE_BAR2_EN_DIS 1
106 109 #define PCIE_BAR3_EN_DIS 1
107 110 #define PCIE_BAR4_EN_DIS 1
108 111 #define PCIE_BAR5_EN_DIS 1
  112 +#define PCIE_ROM_EN_DIS 0
109 113 #define PCIE_BAR0_INIT (PCI_REGION_MEM | PCI_WIDTH_32b | \
110 114 PCI_REGION_NON_PREFETCH)
111 115 #define PCIE_BAR1_INIT (PCI_REGION_MEM | PCI_WIDTH_32b | \
112 116  
... ... @@ -116,10 +120,24 @@
116 120 PCI_REGION_NON_PREFETCH)
117 121 #define PCIE_BAR4_INIT 0
118 122 #define PCIE_BAR5_INIT 0
119   -#endif
  123 +#define PCIE_ROM_INIT 0
  124 +
  125 +/* To do proper EP support, we need to have interrupt driven handlers
  126 + * to keep our EP configuration in proper shape.
  127 + */
  128 +#define PCIE_INTERRUPT_link_req_rst_not 135
  129 +
  130 +/* Global variables */
  131 +static int ignoreERR009852;
  132 +
120 133 /*
121 134 * PHY access functions
122 135 */
  136 + /* FIX: The RM does not document any of this. How should it be
  137 + * possible to understand any of the PHY handling if it is a hard
  138 + * requirement. Do we have to reinstate PHY docs in the manual?
  139 + * If so, what parts?
  140 + */
123 141 static int pcie_phy_poll_ack(void __iomem *dbi_base, int exp_val)
124 142 {
125 143 u32 val;
126 144  
... ... @@ -293,10 +311,147 @@
293 311 return 0;
294 312 }
295 313  
  314 +static void s32v234_pcie_set_bar(int baroffset, int enable, unsigned int size,
  315 + unsigned int init)
  316 +{
  317 + char __iomem *dbi_base = (char __iomem *)S32V234_DBI_ADDR;
  318 + u32 mask = (enable) ? ((size - 1) & ~1) : 0;
  319 +
  320 + /* According to the RM, you have to enable the BAR before you
  321 + * can modify the mask value. While it appears that this may
  322 + * be ok in a single write anyway, we play it safe.
  323 + */
  324 + writel(1, dbi_base + 0x1000 + baroffset);
  325 +
  326 + writel(enable | mask, dbi_base + 0x1000 + baroffset);
  327 + writel(init, dbi_base + baroffset);
  328 +}
  329 +
  330 +static void set_non_sticky_config_regs(void)
  331 +{
  332 + const int socmask_info = readl(SIUL2_MIDR1) & 0x000000ff;
  333 + const struct src *src_regs = (struct src *)SRC_SOC_BASE_ADDR;
  334 + const int ep_mode = (readl(&src_regs->gpr5) & 0x0000001c) == 0;
  335 +
  336 + /* We need this function because the PCIe IP loses some
  337 + * configuration values when it loses the link.
  338 + * THIS FUNCTION MUST BE INTERRUPT SAFE, so we don't use
  339 + * external complex functions.
  340 + */
  341 + if (!ep_mode) {
  342 + /* Set the CLASS_REV of RC CFG header to PCI_CLASS_BRIDGE_PCI */
  343 + setbits_le32(S32V234_DBI_ADDR + PCI_CLASS_REVISION,
  344 + PCI_CLASS_BRIDGE_PCI << 16);
  345 +
  346 + /* CMD reg:I/O space, MEM space, and Bus Master Enable */
  347 + setbits_le32(S32V234_DBI_ADDR | PCI_COMMAND,
  348 + PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
  349 + PCI_COMMAND_MASTER);
  350 +
  351 + /* Region #0 is used for Outbound CFG space access. */
  352 + writel(0, S32V234_DBI_ADDR + PCIE_ATU_VIEWPORT);
  353 + writel(S32V234_ROOT_ADDR,
  354 + S32V234_DBI_ADDR + PCIE_ATU_LOWER_BASE);
  355 + writel(0, S32V234_DBI_ADDR + PCIE_ATU_UPPER_BASE);
  356 + writel(S32V234_ROOT_ADDR + S32V234_ROOT_SIZE,
  357 + S32V234_DBI_ADDR + PCIE_ATU_LIMIT);
  358 + writel(0, S32V234_DBI_ADDR + PCIE_ATU_LOWER_TARGET);
  359 + writel(0, S32V234_DBI_ADDR + PCIE_ATU_UPPER_TARGET);
  360 + writel(PCIE_ATU_TYPE_CFG0, S32V234_DBI_ADDR + PCIE_ATU_CR1);
  361 + writel(PCIE_ATU_ENABLE, S32V234_DBI_ADDR + PCIE_ATU_CR2);
  362 + } else {
  363 + /* Set the CLASS_REV of RC CFG header to something that
  364 + * makes sense for this SoC by itself. For a product,
  365 + * the class setting should be board/product specific,
  366 + * so we'd technically need a CONFIG_PCIE_CLASS as part
  367 + * of the board configuration.
  368 + */
  369 + setbits_le32(S32V234_DBI_ADDR + PCI_CLASS_REVISION,
  370 + (PCI_BASE_CLASS_PROCESSOR << 24) |
  371 + (0x80 /* other */ << 16));
  372 +
  373 + /* Preconfigure the BAR registers, so that the RC can
  374 + * enumerate us properly and assign address spaces.
  375 + * Mask registers are W only!
  376 + */
  377 + if (!ignoreERR009852 && socmask_info == 0x00) {
  378 + /* Erratum ERR009852 requires us to avoid
  379 + * any memory access from the RC! We solve this
  380 + * by disabling all BARs and ROM access
  381 + */
  382 + s32v234_pcie_set_bar(PCI_BASE_ADDRESS_0, 0, 0, 0);
  383 + s32v234_pcie_set_bar(PCI_BASE_ADDRESS_1, 0, 0, 0);
  384 + s32v234_pcie_set_bar(PCI_BASE_ADDRESS_2, 0, 0, 0);
  385 + s32v234_pcie_set_bar(PCI_BASE_ADDRESS_3, 0, 0, 0);
  386 + s32v234_pcie_set_bar(PCI_BASE_ADDRESS_4, 0, 0, 0);
  387 + s32v234_pcie_set_bar(PCI_BASE_ADDRESS_5, 0, 0, 0);
  388 + s32v234_pcie_set_bar(PCI_ROM_ADDRESS, 0, 0, 0);
  389 + } else {
  390 + s32v234_pcie_set_bar(PCI_BASE_ADDRESS_0,
  391 + PCIE_BAR0_EN_DIS, PCIE_BAR0_SIZE,
  392 + PCIE_BAR0_INIT);
  393 + s32v234_pcie_set_bar(PCI_BASE_ADDRESS_1,
  394 + PCIE_BAR1_EN_DIS, PCIE_BAR1_SIZE,
  395 + PCIE_BAR1_INIT);
  396 + s32v234_pcie_set_bar(PCI_BASE_ADDRESS_2,
  397 + PCIE_BAR2_EN_DIS, PCIE_BAR2_SIZE,
  398 + PCIE_BAR2_INIT);
  399 + s32v234_pcie_set_bar(PCI_BASE_ADDRESS_3,
  400 + PCIE_BAR3_EN_DIS, PCIE_BAR3_SIZE,
  401 + PCIE_BAR3_INIT);
  402 + s32v234_pcie_set_bar(PCI_BASE_ADDRESS_4,
  403 + PCIE_BAR4_EN_DIS, PCIE_BAR4_SIZE,
  404 + PCIE_BAR4_INIT);
  405 + s32v234_pcie_set_bar(PCI_BASE_ADDRESS_5,
  406 + PCIE_BAR5_EN_DIS, PCIE_BAR5_SIZE,
  407 + PCIE_BAR5_INIT);
  408 + s32v234_pcie_set_bar(PCI_ROM_ADDRESS,
  409 + PCIE_ROM_EN_DIS, PCIE_ROM_SIZE,
  410 + PCIE_ROM_INIT);
  411 +
  412 + /* Region #0 is used for Inbound Mem
  413 + * space access on BAR2.
  414 + */
  415 + writel(0x80000000,
  416 + S32V234_DBI_ADDR + PCIE_ATU_VIEWPORT);
  417 + writel(0xcff00000,
  418 + S32V234_DBI_ADDR + PCIE_ATU_LOWER_TARGET);
  419 + writel(0, S32V234_DBI_ADDR + PCIE_ATU_UPPER_TARGET);
  420 + writel(PCIE_ATU_TYPE_MEM,
  421 + S32V234_DBI_ADDR + PCIE_ATU_CR1);
  422 + writel(0xC0000200, S32V234_DBI_ADDR + PCIE_ATU_CR2);
  423 +
  424 + /* CMD reg:I/O space, MEM space, Bus Master Enable */
  425 + setbits_le32(S32V234_DBI_ADDR | PCI_COMMAND,
  426 + PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
  427 + PCI_COMMAND_MASTER);
  428 + }
  429 + }
  430 +}
  431 +
  432 +static void inthandler_pcie_link_req_rst_not(struct pt_regs *pt_regs,
  433 + unsigned int esr)
  434 +{
  435 + const struct src *src_regs = (struct src *)SRC_SOC_BASE_ADDR;
  436 +
  437 + /* Clear link_req_rst_not interrupt signal */
  438 + clrsetbits_le32(&src_regs->pcie_config0, 0x00000001, 0x00000001);
  439 +
  440 + /* Once we get this interrupt, the link came down and all the
  441 + * non sticky registers in our configuration space got reset.
  442 + * We reestablish the register values now and finally
  443 + * permit configuration transactions
  444 + */
  445 + set_non_sticky_config_regs();
  446 +
  447 + /* Accept inbound configuration requests now */
  448 + clrsetbits_le32(&src_regs->gpr11, 0x00400000, 0x00400000);
  449 +}
  450 +
296 451 /*
297 452 * iATU region setup
298 453 */
299   -static int s32v234_pcie_regions_setup(void)
  454 +static int s32v234_pcie_regions_setup(const int ep_mode)
300 455 {
301 456 /*
302 457 * S32V234 defines 16MB in the AXI address map for PCIe.
303 458  
304 459  
305 460  
306 461  
307 462  
308 463  
309 464  
310 465  
311 466  
... ... @@ -310,107 +465,74 @@
310 465 * 0x01F0_0000 --- 0x01FF_FFFF 1MB Cfg + Registers
311 466 */
312 467  
313   - /* CMD reg:I/O space, MEM space, and Bus Master Enable */
314   - setbits_le32(S32V234_DBI_ADDR | PCI_COMMAND,
315   - PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER);
316   -#ifndef CONFIG_PCIE_EP_MODE
317   - /* Set the CLASS_REV of RC CFG header to PCI_CLASS_BRIDGE_PCI */
318   - setbits_le32(S32V234_DBI_ADDR + PCI_CLASS_REVISION,
319   - PCI_CLASS_BRIDGE_PCI << 16);
320   -#else
321   - /* Set the CLASS_REV of RC CFG header to PCI_CLASS_MEMORY_RAM */
322   - setbits_le32(S32V234_DBI_ADDR + PCI_CLASS_REVISION,
323   - PCI_CLASS_MEMORY_RAM << 16);
324   - /* 1MB 32bit none-prefetchable memory on BAR0 */
325   - writel(PCIE_BAR0_INIT, S32V234_DBI_ADDR + PCI_BASE_ADDRESS_0);
326   -#if PCIE_BAR0_EN_DIS
327   - writel((PCIE_BAR0_EN_DIS | (PCIE_BAR0_SIZE - 1)),
328   - S32V234_DBI_ADDR + (1 << 12) + PCI_BASE_ADDRESS_0);
329   -#else
330   - writel((PCIE_BAR0_EN_DIS & (PCIE_BAR0_SIZE - 1)),
331   - S32V234_DBI_ADDR + (1 << 12) + PCI_BASE_ADDRESS_0);
332   -#endif
  468 + /* We set up the ID for all Rev 1.x chips */
  469 + if (get_siul2_midr1_major() == 0x00) {
  470 + /*
  471 + * Vendor ID is Freescale (now NXP): 0x1957
  472 + * Device ID is split as follows
  473 + * Family 15:12, Device 11:6, Personality 5:0
  474 + * S32V is in the automotive family: 0100
  475 + * S32V is the first auto device with PCIe: 000000
  476 + * S32V does not have export controlled cryptography: 00001
  477 + */
  478 + printf("Setting PCIE Vendor and Device ID\n");
  479 + writel((0x4001 << 16) | 0x1957,
  480 + S32V234_DBI_ADDR + PCI_VENDOR_ID);
  481 + }
333 482  
334   - /* None used BAR1 */
335   - writel(PCIE_BAR1_INIT, S32V234_DBI_ADDR + PCI_BASE_ADDRESS_1);
336   -#if PCIE_BAR1_EN_DIS
337   - writel((PCIE_BAR1_EN_DIS | (PCIE_BAR1_SIZE - 1)),
338   - S32V234_DBI_ADDR + (1 << 12) + PCI_BASE_ADDRESS_1);
339   -#else
340   - writel((PCIE_BAR1_EN_DIS & (PCIE_BAR1_SIZE - 1)),
341   - S32V234_DBI_ADDR + (1 << 12) + PCI_BASE_ADDRESS_1);
  483 +#if defined(CONFIG_PCIE_SUBSYSTEM_VENDOR_ID) && \
  484 + defined(CONFIG_PCIE_SUBSYSTEM_ID)
  485 + writel((CONFIG_PCIE_SUBSYSTEM_ID << 16) |
  486 + CONFIG_PCIE_SUBSYSTEM_VENDOR_ID,
  487 + S32V234_DBI_ADDR + PCI_SUBSYSTEM_VENDOR_ID);
342 488 #endif
343 489  
344   - /* 64KB 32bit none-prefetchable memory on BAR2 */
345   - writel(PCIE_BAR2_INIT, S32V234_DBI_ADDR + PCI_BASE_ADDRESS_2);
346   -#if PCIE_BAR2_EN_DIS
347   - writel((PCIE_BAR2_EN_DIS | (PCIE_BAR2_SIZE - 1)),
348   - S32V234_DBI_ADDR + (1 << 12) + PCI_BASE_ADDRESS_2);
349   -#else
350   - writel((PCIE_BAR2_EN_DIS & (PCIE_BAR2_SIZE - 1)),
351   - S32V234_DBI_ADDR + (1 << 12) + PCI_BASE_ADDRESS_2);
352   -#endif
  490 + ignoreERR009852 = env_get("ignoreERR009852") ? true : false;
353 491  
354   - /* Default size BAR3 */
355   - writel(PCIE_BAR3_INIT, S32V234_DBI_ADDR + PCI_BASE_ADDRESS_3);
356   -#if PCIE_BAR3_EN_DIS
357   - writel((PCIE_BAR3_EN_DIS | (PCIE_BAR3_SIZE - 1)),
358   - S32V234_DBI_ADDR + (1 << 12) + PCI_BASE_ADDRESS_3);
359   -#else
360   - writel((PCIE_BAR3_EN_DIS & (PCIE_BAR3_SIZE - 1)),
361   - S32V234_DBI_ADDR + (1 << 12) + PCI_BASE_ADDRESS_3);
362   -#endif
  492 + set_non_sticky_config_regs();
363 493  
364   - /* Default size BAR4 */
365   - writel(PCIE_BAR4_INIT, S32V234_DBI_ADDR + PCI_BASE_ADDRESS_4);
366   -#if PCIE_BAR4_EN_DIS
367   - writel((PCIE_BAR4_EN_DIS | (PCIE_BAR4_SIZE - 1)),
368   - S32V234_DBI_ADDR + (1 << 12) + PCI_BASE_ADDRESS_4);
369   -#else
370   - writel((PCIE_BAR4_EN_DIS & (PCIE_BAR4_SIZE - 1)),
371   - S32V234_DBI_ADDR + (1 << 12) + PCI_BASE_ADDRESS_4);
372   -#endif
  494 + if (ep_mode) {
  495 + struct src *src_regs = (struct src *)SRC_SOC_BASE_ADDR;
373 496  
374   - /* Default size BAR5 */
375   - writel(PCIE_BAR5_INIT, S32V234_DBI_ADDR + PCI_BASE_ADDRESS_5);
376   -#if PCIE_BAR5_EN_DIS
377   - writel((PCIE_BAR5_EN_DIS | (PCIE_BAR5_SIZE - 1)),
378   - S32V234_DBI_ADDR + (1 << 12) + PCI_BASE_ADDRESS_5);
379   -#else
380   - writel((PCIE_BAR5_EN_DIS & (PCIE_BAR5_SIZE - 1)),
381   - S32V234_DBI_ADDR + (1 << 12) + PCI_BASE_ADDRESS_5);
382   -#endif
383   -#endif /* CONFIG_PCIE_EP_MODE */
  497 + if (ignoreERR009852)
  498 + printf("\n Ignoring errata ERR009852\n");
384 499  
385   -#ifndef CONFIG_PCIE_EP_MODE
386   - /* Region #0 is used for Outbound CFG space access. */
387   - writel(0, S32V234_DBI_ADDR + PCIE_ATU_VIEWPORT);
388   - writel(S32V234_ROOT_ADDR, S32V234_DBI_ADDR + PCIE_ATU_LOWER_BASE);
389   - writel(0, S32V234_DBI_ADDR + PCIE_ATU_UPPER_BASE);
390   - writel(S32V234_ROOT_ADDR + S32V234_ROOT_SIZE,
391   - S32V234_DBI_ADDR + PCIE_ATU_LIMIT);
392   - writel(0, S32V234_DBI_ADDR + PCIE_ATU_LOWER_TARGET);
393   - writel(0, S32V234_DBI_ADDR + PCIE_ATU_UPPER_TARGET);
394   - writel(PCIE_ATU_TYPE_CFG0, S32V234_DBI_ADDR + PCIE_ATU_CR1);
395   - writel(PCIE_ATU_ENABLE, S32V234_DBI_ADDR + PCIE_ATU_CR2);
396   -#else
397   - /* Region #0 is used for Inbound Mem space access on BAR2. */
398   - writel(0x80000000, S32V234_DBI_ADDR + PCIE_ATU_VIEWPORT);
399   - writel(0xcff00000, S32V234_DBI_ADDR + PCIE_ATU_LOWER_TARGET);
400   - writel(0, S32V234_DBI_ADDR + PCIE_ATU_UPPER_TARGET);
401   - writel(PCIE_ATU_TYPE_MEM, S32V234_DBI_ADDR + PCIE_ATU_CR1);
402   - writel(0xC0000200, S32V234_DBI_ADDR + PCIE_ATU_CR2);
403   -#endif
  500 + /* Ensure that if the link comes down we do not react
  501 + * to config accesses anymore until we have reconfigured
  502 + * ourselves properly! A link down event unfortunately
  503 + * clears non-sticky registers.
  504 + * Note that we permit automatic link training. This
  505 + * puts the responsibility on us to reconfigure and
  506 + * set PCIE_CFG_READY again if the link comes down.
  507 + */
  508 + clrsetbits_le32(&src_regs->gpr10, 0x40000000, 0x40000000);
  509 +
  510 + /* Assume the link is up and reset the link down event,
  511 + * so that we can properly try to set PCIE_CFG_READY.
  512 + */
  513 + clrsetbits_le32(&src_regs->pcie_config0, 0x00000001,
  514 + 0x00000001);
  515 +
  516 + /* Ensure that we can fix up our configuration again
  517 + * if the link came down!
  518 + */
  519 + gic_register_handler(PCIE_INTERRUPT_link_req_rst_not,
  520 + inthandler_pcie_link_req_rst_not,
  521 + 0, "PCIE_INTERRUPT_link_req_rst_not");
  522 +
  523 + /* Accept inbound configuration requests now */
  524 + clrsetbits_le32(&src_regs->gpr11, 0x00400000, 0x00400000);
  525 + }
  526 +
404 527 return 0;
405 528 }
406 529  
407   -#ifndef CONFIG_PCIE_EP_MODE
408 530 /*
409 531 * PCI Express accessors
410 532 */
411   -static u32 get_bus_address(pci_dev_t d, int where)
  533 +static u8 *get_bus_address(pci_dev_t d, int where)
412 534 {
413   - u32 va_address;
  535 + u8 *va_address;
414 536  
415 537 /* Reconfigure Region #0 */
416 538 writel(0, S32V234_DBI_ADDR + PCIE_ATU_VIEWPORT);
417 539  
... ... @@ -421,10 +543,10 @@
421 543 writel(PCIE_ATU_TYPE_CFG1, S32V234_DBI_ADDR + PCIE_ATU_CR1);
422 544  
423 545 if (PCI_BUS(d) == 0) {
424   - va_address = S32V234_DBI_ADDR;
  546 + va_address = (u8 *)S32V234_DBI_ADDR;
425 547 } else {
426 548 writel(d << 8, S32V234_DBI_ADDR + PCIE_ATU_LOWER_TARGET);
427   - va_address = S32V234_IO_ADDR + SZ_16M - SZ_1M;
  549 + va_address = (u8 *)(S32V234_IO_ADDR + SZ_16M - SZ_1M);
428 550 }
429 551  
430 552 va_address += (where & ~0x3);
... ... @@ -444,7 +566,7 @@
444 566 static int s32v234_pcie_read_config(struct pci_controller *hose, pci_dev_t d,
445 567 int where, u32 *val)
446 568 {
447   - u32 va_address;
  569 + u8 *va_address;
448 570 int ret;
449 571  
450 572 ret = s32v234_pcie_addr_valid(d);
... ... @@ -463,7 +585,7 @@
463 585 static int s32v234_pcie_write_config(struct pci_controller *hose, pci_dev_t d,
464 586 int where, u32 val)
465 587 {
466   - u32 va_address = 0;
  588 + void *va_address = 0;
467 589 int ret;
468 590  
469 591 ret = s32v234_pcie_addr_valid(d);
470 592  
471 593  
472 594  
473 595  
474 596  
... ... @@ -475,31 +597,21 @@
475 597  
476 598 return 0;
477 599 }
478   -#endif /* CONFIG_PCIE_EP_MODE */
479 600  
480   -static int s32v234_pcie_init_phy(void)
  601 +static int s32v234_pcie_init_phy(const int ep_mode)
481 602 {
482 603 struct src *src_regs = (struct src *)SRC_SOC_BASE_ADDR;
483 604  
484 605 clrbits_le32(&src_regs->gpr5, SRC_GPR5_PCIE_APP_LTSSM_ENABLE);
485 606  
486   -#ifndef CONFIG_PCIE_EP_MODE
487 607 clrsetbits_le32(&src_regs->gpr5,
488   - SRC_GPR5_PCIE_DEVICE_TYPE_MASK,
489   - SRC_GPR5_PCIE_DEVICE_TYPE_RC);
490   -#else
  608 + SRC_GPR5_PCIE_PHY_LOS_LEVEL_MASK,
  609 + SRC_GPR5_PCIE_PHY_LOS_LEVEL_9);
491 610 clrsetbits_le32(&src_regs->gpr5,
492   - SRC_GPR5_PCIE_DEVICE_TYPE_MASK,
493   - SRC_GPR5_PCIE_DEVICE_TYPE_EP);
494   -#endif
495   - clrsetbits_le32(&src_regs->gpr5,
496   - SRC_GPR5_PCIE_PHY_LOS_LEVEL_MASK,
497   - SRC_GPR5_PCIE_PHY_LOS_LEVEL_9);
498   - clrsetbits_le32(&src_regs->gpr5,
499   - SRC_GPR5_PCIE_PHY_RX0_EQ_MASK,
500   - SRC_GPR5_PCIE_PHY_RX0_EQ_2);
  611 + SRC_GPR5_PCIE_PHY_RX0_EQ_MASK,
  612 + SRC_GPR5_PCIE_PHY_RX0_EQ_2);
501 613  
502   - writel((0x0 << SRC_GPR6_PCIE_PCS_TX_DEEMPH_GEN1_OFFSET) |
  614 + writel((0x0 << SRC_GPR6_PCIE_PCS_TX_DEEMPH_GEN1_OFFSET) |
503 615 (0x0 << SRC_GPR6_PCIE_PCS_TX_DEEMPH_GEN2_3P5DB_OFFSET) |
504 616 (20 << SRC_GPR6_PCIE_PCS_TX_DEEMPH_GEN2_6DB_OFFSET) |
505 617 (127 << SRC_GPR6_PCIE_PCS_TX_SWING_FULL_OFFSET) |
506 618  
507 619  
508 620  
509 621  
... ... @@ -520,28 +632,24 @@
520 632 return 0;
521 633 }
522 634  
523   -static int s32v_pcie_link_up(void)
  635 +static int s32v_pcie_link_up(const int ep_mode)
524 636 {
525 637 struct src *src_regs = (struct src *)SRC_SOC_BASE_ADDR;
526 638  
527 639 u32 tmp;
528 640 int count = 0;
529 641  
530   - s32v234_pcie_init_phy();
  642 + s32v234_pcie_init_phy(ep_mode);
531 643 s32v234_pcie_deassert_core_reset();
532   - s32v234_pcie_regions_setup();
  644 + s32v234_pcie_regions_setup(ep_mode);
533 645  
534   -#ifdef CONFIG_PCIE_EP_MODE
535   - writel(readl(&src_regs->gpr11) | 0x00400000, &src_regs->gpr11);
536   -#endif
537   -
538 646 /*
539 647 * FIXME: Force the PCIe RC to Gen1 operation
540 648 * The RC must be forced into Gen1 mode before bringing the link
541 649 * up, otherwise no downstream devices are detected. After the
542 650 * link is up, a managed Gen1->Gen2 transition can be initiated.
543 651 */
544   - printf("\n Forcing PCIe RC to Gen1 operation");
  652 + printf("\nForcing PCIe to Gen1 operation\n");
545 653  
546 654 tmp = readl(S32V234_DBI_ADDR + 0x7c);
547 655 tmp &= ~0xf;
548 656  
549 657  
550 658  
551 659  
552 660  
553 661  
554 662  
555 663  
556 664  
557 665  
558 666  
559 667  
560 668  
... ... @@ -566,57 +674,67 @@
566 674 return 0;
567 675 }
568 676  
569   -void s32v234_pcie_init(void)
  677 +void s32v234_pcie_init(const int ep_mode)
570 678 {
571   -#ifndef CONFIG_PCIE_EP_MODE
572 679 /* Static instance of the controller. */
573 680 static struct pci_controller pcc;
574 681 struct pci_controller *hose = &pcc;
575   -#endif
576 682 int ret;
  683 + struct src *src_regs = (struct src *)SRC_SOC_BASE_ADDR;
577 684  
578   -#ifndef CONFIG_PCIE_EP_MODE
579   - memset(&pcc, 0, sizeof(pcc));
  685 + /* Set device type */
  686 + clrsetbits_le32(&src_regs->gpr5,
  687 + SRC_GPR5_PCIE_DEVICE_TYPE_MASK,
  688 + (ep_mode) ? SRC_GPR5_PCIE_DEVICE_TYPE_EP :
  689 + SRC_GPR5_PCIE_DEVICE_TYPE_RC);
580 690  
581   - /* PCI I/O space */
582   - pci_set_region(&hose->regions[0],
583   - S32V234_IO_ADDR, S32V234_IO_ADDR,
584   - S32V234_IO_SIZE, PCI_REGION_IO);
  691 + if (!ep_mode) {
  692 + memset(&pcc, 0, sizeof(pcc));
585 693  
586   - /* PCI memory space */
587   - pci_set_region(&hose->regions[1],
588   - S32V234_MEM_ADDR, S32V234_MEM_ADDR,
589   - S32V234_MEM_SIZE, PCI_REGION_MEM);
  694 + /* PCI I/O space */
  695 + pci_set_region(&hose->regions[0],
  696 + S32V234_IO_ADDR, S32V234_IO_ADDR,
  697 + S32V234_IO_SIZE, PCI_REGION_IO);
590 698  
591   - /* System memory space */
592   - /* For now, allocating only 1024MB from address 0x80000000 */
  699 + /* PCI memory space */
  700 + pci_set_region(&hose->regions[1],
  701 + S32V234_MEM_ADDR, S32V234_MEM_ADDR,
  702 + S32V234_MEM_SIZE, PCI_REGION_MEM);
593 703  
594   - pci_set_region(&hose->regions[2],
595   - MMDC0_ARB_BASE_ADDR, MMDC0_ARB_BASE_ADDR,
596   - 0x3FFFFFFF, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
  704 + /* System memory space */
  705 + pci_set_region(&hose->regions[2],
  706 + MMDC0_ARB_BASE_ADDR, MMDC0_ARB_BASE_ADDR,
  707 + 0x3FFFFFFF,
  708 + PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
597 709  
598   - hose->region_count = 3;
  710 + hose->region_count = 3;
599 711  
600   - pci_set_ops(hose,
601   - pci_hose_read_config_byte_via_dword,
602   - pci_hose_read_config_word_via_dword,
603   - s32v234_pcie_read_config,
604   - pci_hose_write_config_byte_via_dword,
605   - pci_hose_write_config_word_via_dword,
606   - s32v234_pcie_write_config);
607   -#endif
  712 + pci_set_ops(hose,
  713 + pci_hose_read_config_byte_via_dword,
  714 + pci_hose_read_config_word_via_dword,
  715 + s32v234_pcie_read_config,
  716 + pci_hose_write_config_byte_via_dword,
  717 + pci_hose_write_config_word_via_dword,
  718 + s32v234_pcie_write_config);
  719 + }
  720 +
608 721 /* Start the controller. */
609   - ret = s32v_pcie_link_up();
610   -#ifndef CONFIG_PCIE_EP_MODE
611   - if (!ret) {
612   - pci_register_hose(hose);
613   - hose->last_busno = pci_hose_scan(hose);
  722 + ret = s32v_pcie_link_up(ep_mode);
  723 +
  724 + if (!ep_mode) {
  725 + if (!ret) {
  726 + pci_register_hose(hose);
  727 + hose->last_busno = pci_hose_scan(hose);
  728 + }
614 729 }
615   -#endif
616 730 }
617 731  
618 732 void pci_init_board(void)
619 733 {
620   - s32v234_pcie_init();
  734 +#ifdef CONFIG_PCIE_EP_MODE
  735 + s32v234_pcie_init(1);
  736 +#else
  737 + s32v234_pcie_init(0);
  738 +#endif
621 739 }
include/configs/s32v234pcie.h
... ... @@ -24,6 +24,7 @@
24 24  
25 25 #ifdef CONFIG_CMD_PCI
26 26 #define CONFIG_PCIE_EP_MODE
  27 +#define CONFIG_GICSUPPORT
27 28 #endif
28 29  
29 30 #define FDT_FILE fsl-s32v234-pcie.dtb
scripts/config_whitelist.txt
... ... @@ -663,6 +663,7 @@
663 663 CONFIG_FTWDT010_WATCHDOG
664 664 CONFIG_FZOTG266HD0A_BASE
665 665 CONFIG_GATEWAYIP
  666 +CONFIG_GICSUPPORT
666 667 CONFIG_GICV2
667 668 CONFIG_GLOBAL_DATA_NOT_REG10
668 669 CONFIG_GLOBAL_TIMER