2 * Copyright (C) 2009-2010 DENX Software Engineering <wd@denx.de>
3 * Copyright (C) Freescale Semiconductor, Inc. 2006, 2007.
5 * SPDX-License-Identifier: GPL-2.0+
12 #include <asm/global_data.h>
14 #if defined(CONFIG_OF_LIBFDT)
16 #include <fdt_support.h>
19 DECLARE_GLOBAL_DATA_PTR;
21 /* System RAM mapped to PCI space */
22 #define CONFIG_PCI_SYS_MEM_BUS CONFIG_SYS_SDRAM_BASE
23 #define CONFIG_PCI_SYS_MEM_PHYS CONFIG_SYS_SDRAM_BASE
25 static struct pci_controller pci_hose;
28 /**************************************************************************
35 volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
36 volatile law512x_t *pci_law;
37 volatile pot512x_t *pci_pot;
38 volatile pcictrl512x_t *pci_ctrl;
43 struct pci_controller *hose;
45 /* Set PCI divider for 33MHz */
46 reg32 = in_be32(&im->clk.scfr[0]);
47 reg32 &= ~(SCFR1_PCI_DIV_MASK);
48 reg32 |= SCFR1_PCI_DIV << SCFR1_PCI_DIV_SHIFT;
49 out_be32(&im->clk.scfr[0], reg32);
51 clrsetbits_be32(&im->clk.scfr[0],
53 SCFR1_PCI_DIV << SCFR1_PCI_DIV_SHIFT
56 pci_law = im->sysconf.pcilaw;
57 pci_pot = im->ios.pot;
58 pci_ctrl = &im->pci_ctrl;
63 * Release PCI RST Output signal
65 out_be32(&pci_ctrl->gcr, 0);
67 out_be32(&pci_ctrl->gcr, 1);
69 /* We need to wait at least a 1sec based on PCI specs */
70 for (i = 0; i < 1000; i++)
74 * Configure PCI Local Access Windows
76 out_be32(&pci_law[0].bar, CONFIG_SYS_PCI_MEM_PHYS & LAWBAR_BAR);
77 out_be32(&pci_law[0].ar, LAWAR_EN | LAWAR_SIZE_512M);
79 out_be32(&pci_law[1].bar, CONFIG_SYS_PCI_IO_PHYS & LAWBAR_BAR);
80 out_be32(&pci_law[1].ar, LAWAR_EN | LAWAR_SIZE_16M);
83 * Configure PCI Outbound Translation Windows
86 /* PCI mem space - prefetch */
87 out_be32(&pci_pot[0].potar,
88 (CONFIG_SYS_PCI_MEM_BASE >> 12) & POTAR_TA_MASK);
89 out_be32(&pci_pot[0].pobar,
90 (CONFIG_SYS_PCI_MEM_PHYS >> 12) & POBAR_BA_MASK);
91 out_be32(&pci_pot[0].pocmr,
92 POCMR_EN | POCMR_PRE | POCMR_CM_256M);
95 out_be32(&pci_pot[1].potar,
96 (CONFIG_SYS_PCI_IO_BASE >> 12) & POTAR_TA_MASK);
97 out_be32(&pci_pot[1].pobar,
98 (CONFIG_SYS_PCI_IO_PHYS >> 12) & POBAR_BA_MASK);
99 out_be32(&pci_pot[1].pocmr,
100 POCMR_EN | POCMR_IO | POCMR_CM_16M);
102 /* PCI mmio - non-prefetch mem space */
103 out_be32(&pci_pot[2].potar,
104 (CONFIG_SYS_PCI_MMIO_BASE >> 12) & POTAR_TA_MASK);
105 out_be32(&pci_pot[2].pobar,
106 (CONFIG_SYS_PCI_MMIO_PHYS >> 12) & POBAR_BA_MASK);
107 out_be32(&pci_pot[2].pocmr,
108 POCMR_EN | POCMR_CM_256M);
111 * Configure PCI Inbound Translation Windows
114 /* we need RAM mapped to PCI space for the devices to
115 * access main memory */
116 out_be32(&pci_ctrl[0].pitar1, 0x0);
117 out_be32(&pci_ctrl[0].pibar1, 0x0);
118 out_be32(&pci_ctrl[0].piebar1, 0x0);
119 out_be32(&pci_ctrl[0].piwar1,
120 PIWAR_EN | PIWAR_PF | PIWAR_RTT_SNOOP |
121 PIWAR_WTT_SNOOP | (__ilog2(gd->ram_size) - 1));
123 hose->first_busno = 0;
124 hose->last_busno = 0xff;
126 /* PCI memory prefetch space */
127 pci_set_region(hose->regions + 0,
128 CONFIG_SYS_PCI_MEM_BASE,
129 CONFIG_SYS_PCI_MEM_PHYS,
130 CONFIG_SYS_PCI_MEM_SIZE,
131 PCI_REGION_MEM|PCI_REGION_PREFETCH);
133 /* PCI memory space */
134 pci_set_region(hose->regions + 1,
135 CONFIG_SYS_PCI_MMIO_BASE,
136 CONFIG_SYS_PCI_MMIO_PHYS,
137 CONFIG_SYS_PCI_MMIO_SIZE,
141 pci_set_region(hose->regions + 2,
142 CONFIG_SYS_PCI_IO_BASE,
143 CONFIG_SYS_PCI_IO_PHYS,
144 CONFIG_SYS_PCI_IO_SIZE,
147 /* System memory space */
148 pci_set_region(hose->regions + 3,
149 CONFIG_PCI_SYS_MEM_BUS,
150 CONFIG_PCI_SYS_MEM_PHYS,
152 PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
154 hose->region_count = 4;
156 pci_setup_indirect(hose,
157 (CONFIG_SYS_IMMR + 0x8300),
158 (CONFIG_SYS_IMMR + 0x8304));
160 pci_register_hose(hose);
163 * Write to Command register
166 dev = PCI_BDF(hose->first_busno, 0, 0);
167 pci_hose_read_config_word(hose, dev, PCI_COMMAND, ®16);
168 reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
169 pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16);
172 * Clear non-reserved bits in status register.
174 pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
175 pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
176 pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
178 #ifdef CONFIG_PCI_SCAN_SHOW
179 printf("PCI: Bus Dev VenId DevId Class Int\n");
184 hose->last_busno = pci_hose_scan(hose);
187 #if defined(CONFIG_OF_LIBFDT)
188 void ft_pci_setup(void *blob, bd_t *bd)
194 nodeoffset = fdt_path_offset(blob, "/aliases");
195 if (nodeoffset >= 0) {
196 path = fdt_getprop(blob, nodeoffset, "pci", NULL);
198 tmp[0] = cpu_to_be32(pci_hose.first_busno);
199 tmp[1] = cpu_to_be32(pci_hose.last_busno);
200 do_fixup_by_path(blob, path, "bus-range",
201 &tmp, sizeof(tmp), 1);
203 tmp[0] = cpu_to_be32(gd->pci_clk);
204 do_fixup_by_path(blob, path, "clock-frequency",
205 &tmp, sizeof(tmp[0]), 1);
209 #endif /* CONFIG_OF_LIBFDT */