]>
Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * (C) Copyright 2003 | |
3 | * Wolfgang Denk, DENX Software Engineering, wd@denx.de. | |
4 | * | |
5 | * (C) Copyright 2004 Red Hat, Inc. | |
6 | * | |
7 | * See file CREDITS for list of people who contributed to this | |
8 | * project. | |
9 | * | |
10 | * This program is free software; you can redistribute it and/or | |
11 | * modify it under the terms of the GNU General Public License as | |
12 | * published by the Free Software Foundation; either version 2 of | |
13 | * the License, or (at your option) any later version. | |
14 | * | |
15 | * This program is distributed in the hope that it will be useful, | |
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | * GNU General Public License for more details. | |
19 | * | |
20 | * You should have received a copy of the GNU General Public License | |
21 | * along with this program; if not, write to the Free Software | |
22 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
23 | * MA 02111-1307 USA | |
24 | */ | |
25 | ||
26 | #include <linux/kernel.h> | |
27 | #include <linux/init.h> | |
28 | #include <linux/pci.h> | |
29 | #include <linux/slab.h> | |
30 | #include <linux/delay.h> | |
31 | ||
32 | #include <asm/byteorder.h> | |
33 | #include <asm/io.h> | |
34 | #include <asm/irq.h> | |
35 | #include <asm/uaccess.h> | |
36 | #include <asm/machdep.h> | |
37 | #include <asm/pci-bridge.h> | |
38 | #include <asm/immap_cpm2.h> | |
39 | #include <asm/mpc8260.h> | |
40 | ||
41 | #include "m8260_pci.h" | |
42 | ||
43 | ||
44 | /* PCI bus configuration registers. | |
45 | */ | |
46 | ||
47 | static void __init m8260_setup_pci(struct pci_controller *hose) | |
48 | { | |
49 | volatile cpm2_map_t *immap = cpm2_immr; | |
50 | unsigned long pocmr; | |
51 | u16 tempShort; | |
52 | ||
53 | #ifndef CONFIG_ATC /* already done in U-Boot */ | |
54 | /* | |
55 | * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]), | |
56 | * and local bus for PCI (SIUMCR [LBPC]). | |
57 | */ | |
58 | immap->im_siu_conf.siu_82xx.sc_siumcr = 0x00640000; | |
59 | #endif | |
60 | ||
61 | /* Make PCI lowest priority */ | |
62 | /* Each 4 bits is a device bus request and the MS 4bits | |
63 | is highest priority */ | |
64 | /* Bus 4bit value | |
65 | --- ---------- | |
66 | CPM high 0b0000 | |
67 | CPM middle 0b0001 | |
68 | CPM low 0b0010 | |
69 | PCI reguest 0b0011 | |
70 | Reserved 0b0100 | |
71 | Reserved 0b0101 | |
72 | Internal Core 0b0110 | |
73 | External Master 1 0b0111 | |
74 | External Master 2 0b1000 | |
75 | External Master 3 0b1001 | |
76 | The rest are reserved */ | |
77 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893; | |
78 | ||
79 | /* Park bus on core while modifying PCI Bus accesses */ | |
80 | immap->im_siu_conf.siu_82xx.sc_ppc_acr = 0x6; | |
81 | ||
82 | /* | |
83 | * Set up master window that allows the CPU to access PCI space. This | |
84 | * window is set up using the first SIU PCIBR registers. | |
85 | */ | |
86 | immap->im_memctl.memc_pcimsk0 = MPC826x_PCI_MASK; | |
87 | immap->im_memctl.memc_pcibr0 = MPC826x_PCI_BASE | PCIBR_ENABLE; | |
88 | ||
89 | /* Disable machine check on no response or target abort */ | |
90 | immap->im_pci.pci_emr = cpu_to_le32(0x1fe7); | |
91 | /* Release PCI RST (by default the PCI RST signal is held low) */ | |
92 | immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN); | |
93 | ||
94 | /* give it some time */ | |
95 | mdelay(1); | |
96 | ||
97 | /* | |
98 | * Set up master window that allows the CPU to access PCI Memory (prefetch) | |
99 | * space. This window is set up using the first set of Outbound ATU registers. | |
100 | */ | |
101 | immap->im_pci.pci_potar0 = cpu_to_le32(MPC826x_PCI_LOWER_MEM >> 12); | |
102 | immap->im_pci.pci_pobar0 = cpu_to_le32((MPC826x_PCI_LOWER_MEM - MPC826x_PCI_MEM_OFFSET) >> 12); | |
103 | pocmr = ((MPC826x_PCI_UPPER_MEM - MPC826x_PCI_LOWER_MEM) >> 12) ^ 0xfffff; | |
104 | immap->im_pci.pci_pocmr0 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PREFETCH_EN); | |
105 | ||
106 | /* | |
107 | * Set up master window that allows the CPU to access PCI Memory (non-prefetch) | |
108 | * space. This window is set up using the second set of Outbound ATU registers. | |
109 | */ | |
110 | immap->im_pci.pci_potar1 = cpu_to_le32(MPC826x_PCI_LOWER_MMIO >> 12); | |
111 | immap->im_pci.pci_pobar1 = cpu_to_le32((MPC826x_PCI_LOWER_MMIO - MPC826x_PCI_MMIO_OFFSET) >> 12); | |
112 | pocmr = ((MPC826x_PCI_UPPER_MMIO - MPC826x_PCI_LOWER_MMIO) >> 12) ^ 0xfffff; | |
113 | immap->im_pci.pci_pocmr1 = cpu_to_le32(pocmr | POCMR_ENABLE); | |
114 | ||
115 | /* | |
116 | * Set up master window that allows the CPU to access PCI IO space. This window | |
117 | * is set up using the third set of Outbound ATU registers. | |
118 | */ | |
119 | immap->im_pci.pci_potar2 = cpu_to_le32(MPC826x_PCI_IO_BASE >> 12); | |
120 | immap->im_pci.pci_pobar2 = cpu_to_le32(MPC826x_PCI_LOWER_IO >> 12); | |
121 | pocmr = ((MPC826x_PCI_UPPER_IO - MPC826x_PCI_LOWER_IO) >> 12) ^ 0xfffff; | |
122 | immap->im_pci.pci_pocmr2 = cpu_to_le32(pocmr | POCMR_ENABLE | POCMR_PCI_IO); | |
123 | ||
124 | /* | |
125 | * Set up slave window that allows PCI masters to access MPC826x local memory. | |
126 | * This window is set up using the first set of Inbound ATU registers | |
127 | */ | |
128 | ||
129 | immap->im_pci.pci_pitar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_LOCAL >> 12); | |
130 | immap->im_pci.pci_pibar0 = cpu_to_le32(MPC826x_PCI_SLAVE_MEM_BUS >> 12); | |
131 | pocmr = ((MPC826x_PCI_SLAVE_MEM_SIZE-1) >> 12) ^ 0xfffff; | |
132 | immap->im_pci.pci_picmr0 = cpu_to_le32(pocmr | PICMR_ENABLE | PICMR_PREFETCH_EN); | |
133 | ||
134 | /* See above for description - puts PCI request as highest priority */ | |
135 | immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567; | |
136 | ||
137 | /* Park the bus on the PCI */ | |
138 | immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI; | |
139 | ||
140 | /* Host mode - specify the bridge as a host-PCI bridge */ | |
141 | early_write_config_word(hose, 0, 0, PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_HOST); | |
142 | ||
143 | /* Enable the host bridge to be a master on the PCI bus, and to act as a PCI memory target */ | |
144 | early_read_config_word(hose, 0, 0, PCI_COMMAND, &tempShort); | |
145 | early_write_config_word(hose, 0, 0, PCI_COMMAND, | |
146 | tempShort | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); | |
147 | } | |
148 | ||
149 | void __init m8260_find_bridges(void) | |
150 | { | |
151 | extern int pci_assign_all_busses; | |
152 | struct pci_controller * hose; | |
153 | ||
154 | pci_assign_all_busses = 1; | |
155 | ||
156 | hose = pcibios_alloc_controller(); | |
157 | ||
158 | if (!hose) | |
159 | return; | |
160 | ||
161 | ppc_md.pci_swizzle = common_swizzle; | |
162 | ||
163 | hose->first_busno = 0; | |
164 | hose->bus_offset = 0; | |
165 | hose->last_busno = 0xff; | |
166 | ||
167 | setup_m8260_indirect_pci(hose, | |
168 | (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr, | |
169 | (unsigned long)&cpm2_immr->im_pci.pci_cfg_data); | |
170 | ||
171 | m8260_setup_pci(hose); | |
172 | hose->pci_mem_offset = MPC826x_PCI_MEM_OFFSET; | |
173 | ||
174 | isa_io_base = | |
175 | (unsigned long) ioremap(MPC826x_PCI_IO_BASE, | |
176 | MPC826x_PCI_IO_SIZE); | |
177 | hose->io_base_virt = (void *) isa_io_base; | |
178 | ||
179 | /* setup resources */ | |
180 | pci_init_resource(&hose->mem_resources[0], | |
181 | MPC826x_PCI_LOWER_MEM, | |
182 | MPC826x_PCI_UPPER_MEM, | |
183 | IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory"); | |
184 | ||
185 | pci_init_resource(&hose->mem_resources[1], | |
186 | MPC826x_PCI_LOWER_MMIO, | |
187 | MPC826x_PCI_UPPER_MMIO, | |
188 | IORESOURCE_MEM, "PCI memory"); | |
189 | ||
190 | pci_init_resource(&hose->io_resource, | |
191 | MPC826x_PCI_LOWER_IO, | |
192 | MPC826x_PCI_UPPER_IO, | |
193 | IORESOURCE_IO, "PCI I/O"); | |
194 | } |