[POWERPC] Add common clock setting routine mpc52xx_psc_set_clkdiv()
[deliverable/linux.git] / arch / ppc / syslib / m82xx_pci.c
CommitLineData
a6dbba77
VB
1/*
2 *
3 * (C) Copyright 2003
4 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
5 *
6 * (C) Copyright 2004 Red Hat, Inc.
7 *
8 * 2005 (c) MontaVista Software, Inc.
9 * Vitaly Bordug <vbordug@ru.mvista.com>
10 *
11 * See file CREDITS for list of people who contributed to this
12 * project.
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of
17 * the License, or (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
27 * MA 02111-1307 USA
28 */
29
30#include <linux/kernel.h>
31#include <linux/init.h>
32#include <linux/pci.h>
33#include <linux/slab.h>
34#include <linux/delay.h>
35#include <linux/irq.h>
36#include <linux/interrupt.h>
37
38#include <asm/byteorder.h>
39#include <asm/io.h>
40#include <asm/irq.h>
41#include <asm/uaccess.h>
42#include <asm/machdep.h>
43#include <asm/pci-bridge.h>
44#include <asm/immap_cpm2.h>
45#include <asm/mpc8260.h>
46#include <asm/cpm2.h>
47
48#include "m82xx_pci.h"
49
50/*
51 * Interrupt routing
52 */
53
54static inline int
55pq2pci_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin)
56{
57 static char pci_irq_table[][4] =
58 /*
59 * PCI IDSEL/INTPIN->INTLINE
60 * A B C D
61 */
62 {
63 { PIRQA, PIRQB, PIRQC, PIRQD }, /* IDSEL 22 - PCI slot 0 */
64 { PIRQD, PIRQA, PIRQB, PIRQC }, /* IDSEL 23 - PCI slot 1 */
65 { PIRQC, PIRQD, PIRQA, PIRQB }, /* IDSEL 24 - PCI slot 2 */
66 };
67
68 const long min_idsel = 22, max_idsel = 24, irqs_per_slot = 4;
69 return PCI_IRQ_TABLE_LOOKUP;
70}
71
72static void
73pq2pci_mask_irq(unsigned int irq)
74{
75 int bit = irq - NR_CPM_INTS;
76
77 *(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit));
78 return;
79}
80
81static void
82pq2pci_unmask_irq(unsigned int irq)
83{
84 int bit = irq - NR_CPM_INTS;
85
86 *(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit));
87 return;
88}
89
90static void
91pq2pci_mask_and_ack(unsigned int irq)
92{
93 int bit = irq - NR_CPM_INTS;
94
95 *(volatile unsigned long *) PCI_INT_MASK_REG |= (1 << (31 - bit));
96 return;
97}
98
99static void
100pq2pci_end_irq(unsigned int irq)
101{
102 int bit = irq - NR_CPM_INTS;
103
104 *(volatile unsigned long *) PCI_INT_MASK_REG &= ~(1 << (31 - bit));
105 return;
106}
107
108struct hw_interrupt_type pq2pci_ic = {
109 "PQ2 PCI",
110 NULL,
111 NULL,
112 pq2pci_unmask_irq,
113 pq2pci_mask_irq,
114 pq2pci_mask_and_ack,
115 pq2pci_end_irq,
116 0
117};
118
119static irqreturn_t
39e3eb72 120pq2pci_irq_demux(int irq, void *dev_id)
a6dbba77
VB
121{
122 unsigned long stat, mask, pend;
123 int bit;
124
125 for(;;) {
126 stat = *(volatile unsigned long *) PCI_INT_STAT_REG;
127 mask = *(volatile unsigned long *) PCI_INT_MASK_REG;
128 pend = stat & ~mask & 0xf0000000;
129 if (!pend)
130 break;
131 for (bit = 0; pend != 0; ++bit, pend <<= 1) {
132 if (pend & 0x80000000)
39e3eb72 133 __do_IRQ(NR_CPM_INTS + bit);
a6dbba77
VB
134 }
135 }
136
137 return IRQ_HANDLED;
138}
139
140static struct irqaction pq2pci_irqaction = {
141 .handler = pq2pci_irq_demux,
bc59d280 142 .flags = IRQF_DISABLED,
a6dbba77
VB
143 .mask = CPU_MASK_NONE,
144 .name = "PQ2 PCI cascade",
145};
146
147
148void
149pq2pci_init_irq(void)
150{
151 int irq;
152 volatile cpm2_map_t *immap = cpm2_immr;
153#if defined CONFIG_ADS8272
154 /* configure chip select for PCI interrupt controller */
155 immap->im_memctl.memc_br3 = PCI_INT_STAT_REG | 0x00001801;
156 immap->im_memctl.memc_or3 = 0xffff8010;
157#elif defined CONFIG_PQ2FADS
158 immap->im_memctl.memc_br8 = PCI_INT_STAT_REG | 0x00001801;
159 immap->im_memctl.memc_or8 = 0xffff8010;
160#endif
161 for (irq = NR_CPM_INTS; irq < NR_CPM_INTS + 4; irq++)
d1bef4ed 162 irq_desc[irq].chip = &pq2pci_ic;
a6dbba77
VB
163
164 /* make PCI IRQ level sensitive */
165 immap->im_intctl.ic_siexr &=
166 ~(1 << (14 - (PCI_INT_TO_SIU - SIU_INT_IRQ1)));
167
168 /* mask all PCI interrupts */
169 *(volatile unsigned long *) PCI_INT_MASK_REG |= 0xfff00000;
170
171 /* install the demultiplexer for the PCI cascade interrupt */
172 setup_irq(PCI_INT_TO_SIU, &pq2pci_irqaction);
173 return;
174}
175
176static int
177pq2pci_exclude_device(u_char bus, u_char devfn)
178{
179 return PCIBIOS_SUCCESSFUL;
180}
181
182/* PCI bus configuration registers.
183 */
184static void
185pq2ads_setup_pci(struct pci_controller *hose)
186{
187 __u32 val;
188 volatile cpm2_map_t *immap = cpm2_immr;
189 bd_t* binfo = (bd_t*) __res;
190 u32 sccr = immap->im_clkrst.car_sccr;
191 uint pci_div,freq,time;
192 /* PCI int lowest prio */
193 /* Each 4 bits is a device bus request and the MS 4bits
194 is highest priority */
195 /* Bus 4bit value
196 --- ----------
197 CPM high 0b0000
198 CPM middle 0b0001
199 CPM low 0b0010
a8de5ce9 200 PCI request 0b0011
a6dbba77
VB
201 Reserved 0b0100
202 Reserved 0b0101
203 Internal Core 0b0110
204 External Master 1 0b0111
205 External Master 2 0b1000
206 External Master 3 0b1001
207 The rest are reserved
208 */
209 immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x61207893;
210 /* park bus on core */
211 immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_CORE;
212 /*
213 * Set up master windows that allow the CPU to access PCI space. These
214 * windows are set up using the two SIU PCIBR registers.
215 */
216
217 immap->im_memctl.memc_pcimsk0 = M82xx_PCI_PRIM_WND_SIZE;
218 immap->im_memctl.memc_pcibr0 = M82xx_PCI_PRIM_WND_BASE | PCIBR_ENABLE;
219
220#ifdef M82xx_PCI_SEC_WND_SIZE
221 immap->im_memctl.memc_pcimsk1 = M82xx_PCI_SEC_WND_SIZE;
222 immap->im_memctl.memc_pcibr1 = M82xx_PCI_SEC_WND_BASE | PCIBR_ENABLE;
223#endif
224
225#if defined CONFIG_ADS8272
226 immap->im_siu_conf.siu_82xx.sc_siumcr =
227 (immap->im_siu_conf.siu_82xx.sc_siumcr &
228 ~(SIUMCR_BBD | SIUMCR_ESE | SIUMCR_PBSE |
229 SIUMCR_CDIS | SIUMCR_DPPC11 | SIUMCR_L2CPC11 |
230 SIUMCR_LBPC11 | SIUMCR_APPC11 |
231 SIUMCR_CS10PC11 | SIUMCR_BCTLC11 | SIUMCR_MMR11)) |
232 SIUMCR_DPPC11 | SIUMCR_L2CPC01 | SIUMCR_LBPC00 |
233 SIUMCR_APPC10 | SIUMCR_CS10PC00 |
234 SIUMCR_BCTLC00 | SIUMCR_MMR11 ;
235
236#elif defined CONFIG_PQ2FADS
237 /*
238 * Setting required to enable IRQ1-IRQ7 (SIUMCR [DPPC]),
239 * and local bus for PCI (SIUMCR [LBPC]).
240 */
c41b72d5
DT
241 immap->im_siu_conf.siu_82xx.sc_siumcr = (immap->im_siu_conf.siu_82xx.sc_siumcr &
242 ~(SIUMCR_L2CPC11 | SIUMCR_LBPC11 | SIUMCR_CS10PC11 | SIUMCR_APPC11) |
243 SIUMCR_BBD | SIUMCR_LBPC01 | SIUMCR_DPPC11 | SIUMCR_APPC10);
a6dbba77
VB
244#endif
245 /* Enable PCI */
246 immap->im_pci.pci_gcr = cpu_to_le32(PCIGCR_PCI_BUS_EN);
247
248 pci_div = ( (sccr & SCCR_PCI_MODCK) ? 2 : 1) *
249 ( ( (sccr & SCCR_PCIDF_MSK) >> SCCR_PCIDF_SHIFT) + 1);
250 freq = (uint)((2*binfo->bi_cpmfreq)/(pci_div));
42ea0d03
VB
251 time = (int)66666666/freq;
252
a6dbba77
VB
253 /* due to PCI Local Bus spec, some devices needs to wait such a long
254 time after RST deassertion. More specifically, 0.508s for 66MHz & twice more for 33 */
255 printk("%s: The PCI bus is %d Mhz.\nWaiting %s after deasserting RST...\n",__FILE__,freq,
256 (time==1) ? "0.5 seconds":"1 second" );
257
258 {
259 int i;
260 for(i=0;i<(500*time);i++)
261 udelay(1000);
262 }
263
264 /* setup ATU registers */
265 immap->im_pci.pci_pocmr0 = cpu_to_le32(POCMR_ENABLE | POCMR_PCI_IO |
266 ((~(M82xx_PCI_IO_SIZE - 1U)) >> POTA_ADDR_SHIFT));
267 immap->im_pci.pci_potar0 = cpu_to_le32(M82xx_PCI_LOWER_IO >> POTA_ADDR_SHIFT);
268 immap->im_pci.pci_pobar0 = cpu_to_le32(M82xx_PCI_IO_BASE >> POTA_ADDR_SHIFT);
269
270 /* Set-up non-prefetchable window */
271 immap->im_pci.pci_pocmr1 = cpu_to_le32(POCMR_ENABLE | ((~(M82xx_PCI_MMIO_SIZE-1U)) >> POTA_ADDR_SHIFT));
272 immap->im_pci.pci_potar1 = cpu_to_le32(M82xx_PCI_LOWER_MMIO >> POTA_ADDR_SHIFT);
273 immap->im_pci.pci_pobar1 = cpu_to_le32((M82xx_PCI_LOWER_MMIO - M82xx_PCI_MMIO_OFFSET) >> POTA_ADDR_SHIFT);
274
275 /* Set-up prefetchable window */
276 immap->im_pci.pci_pocmr2 = cpu_to_le32(POCMR_ENABLE |POCMR_PREFETCH_EN |
277 (~(M82xx_PCI_MEM_SIZE-1U) >> POTA_ADDR_SHIFT));
278 immap->im_pci.pci_potar2 = cpu_to_le32(M82xx_PCI_LOWER_MEM >> POTA_ADDR_SHIFT);
279 immap->im_pci.pci_pobar2 = cpu_to_le32((M82xx_PCI_LOWER_MEM - M82xx_PCI_MEM_OFFSET) >> POTA_ADDR_SHIFT);
280
281 /* Inbound transactions from PCI memory space */
282 immap->im_pci.pci_picmr0 = cpu_to_le32(PICMR_ENABLE | PICMR_PREFETCH_EN |
283 ((~(M82xx_PCI_SLAVE_MEM_SIZE-1U)) >> PITA_ADDR_SHIFT));
284 immap->im_pci.pci_pibar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_BUS >> PITA_ADDR_SHIFT);
285 immap->im_pci.pci_pitar0 = cpu_to_le32(M82xx_PCI_SLAVE_MEM_LOCAL>> PITA_ADDR_SHIFT);
286
287#if defined CONFIG_ADS8272
288 /* PCI int highest prio */
289 immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x01236745;
290#elif defined CONFIG_PQ2FADS
291 immap->im_siu_conf.siu_82xx.sc_ppc_alrh = 0x03124567;
292#endif
293 /* park bus on PCI */
294 immap->im_siu_conf.siu_82xx.sc_ppc_acr = PPC_ACR_BUS_PARK_PCI;
295
296 /* Enable bus mastering and inbound memory transactions */
297 early_read_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, &val);
298 val &= 0xffff0000;
299 val |= PCI_COMMAND_MEMORY|PCI_COMMAND_MASTER;
300 early_write_config_dword(hose, hose->first_busno, 0, PCI_COMMAND, val);
301
302}
303
304void __init pq2_find_bridges(void)
305{
399fe2bd 306 extern int pci_assign_all_buses;
a6dbba77
VB
307 struct pci_controller * hose;
308 int host_bridge;
309
ab590ccb 310 pci_assign_all_buses = 1;
a6dbba77
VB
311
312 hose = pcibios_alloc_controller();
313
314 if (!hose)
315 return;
316
317 ppc_md.pci_swizzle = common_swizzle;
318
319 hose->first_busno = 0;
320 hose->bus_offset = 0;
321 hose->last_busno = 0xff;
322
323#ifdef CONFIG_ADS8272
324 hose->set_cfg_type = 1;
325#endif
326
327 setup_m8260_indirect_pci(hose,
328 (unsigned long)&cpm2_immr->im_pci.pci_cfg_addr,
329 (unsigned long)&cpm2_immr->im_pci.pci_cfg_data);
330
331 /* Make sure it is a supported bridge */
332 early_read_config_dword(hose,
333 0,
334 PCI_DEVFN(0,0),
335 PCI_VENDOR_ID,
336 &host_bridge);
337 switch (host_bridge) {
338 case PCI_DEVICE_ID_MPC8265:
339 break;
340 case PCI_DEVICE_ID_MPC8272:
341 break;
342 default:
343 printk("Attempting to use unrecognized host bridge ID"
344 " 0x%08x.\n", host_bridge);
345 break;
346 }
347
348 pq2ads_setup_pci(hose);
349
350 hose->io_space.start = M82xx_PCI_LOWER_IO;
351 hose->io_space.end = M82xx_PCI_UPPER_IO;
352 hose->mem_space.start = M82xx_PCI_LOWER_MEM;
353 hose->mem_space.end = M82xx_PCI_UPPER_MMIO;
354 hose->pci_mem_offset = M82xx_PCI_MEM_OFFSET;
355
356 isa_io_base =
357 (unsigned long) ioremap(M82xx_PCI_IO_BASE,
358 M82xx_PCI_IO_SIZE);
359 hose->io_base_virt = (void *) isa_io_base;
360
361 /* setup resources */
362 pci_init_resource(&hose->mem_resources[0],
363 M82xx_PCI_LOWER_MEM,
364 M82xx_PCI_UPPER_MEM,
365 IORESOURCE_MEM|IORESOURCE_PREFETCH, "PCI prefetchable memory");
366
367 pci_init_resource(&hose->mem_resources[1],
368 M82xx_PCI_LOWER_MMIO,
369 M82xx_PCI_UPPER_MMIO,
370 IORESOURCE_MEM, "PCI memory");
371
372 pci_init_resource(&hose->io_resource,
373 M82xx_PCI_LOWER_IO,
374 M82xx_PCI_UPPER_IO,
375 IORESOURCE_IO | 1, "PCI I/O");
376
377 ppc_md.pci_exclude_device = pq2pci_exclude_device;
378 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno);
379
380 ppc_md.pci_map_irq = pq2pci_map_irq;
381 ppc_md.pcibios_fixup = NULL;
382 ppc_md.pcibios_fixup_bus = NULL;
383
384}
This page took 0.306427 seconds and 5 git commands to generate.