2 * arch/arm/mach-ks8695/pci.c
4 * Copyright (C) 2003, Micrel Semiconductors
5 * Copyright (C) 2006, Greg Ungerer <gerg@snapgear.com>
6 * Copyright (C) 2006, Ben Dooks
7 * Copyright (C) 2007, Andrew Victor
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include <linux/kernel.h>
25 #include <linux/pci.h>
27 #include <linux/init.h>
28 #include <linux/irq.h>
29 #include <linux/delay.h>
32 #include <asm/signal.h>
33 #include <asm/mach/pci.h>
34 #include <asm/hardware.h>
36 #include <asm/arch/devices.h>
37 #include <asm/arch/regs-pci.h>
41 static int pci_cfg_dbg
;
44 static void ks8695_pci_setupconfig(unsigned int bus_nr
, unsigned int devfn
, unsigned int where
)
48 pbca
= PBCA_ENABLE
| (where
& ~3);
49 pbca
|= PCI_SLOT(devfn
) << 11 ;
50 pbca
|= PCI_FUNC(devfn
) << 8;
54 /* use Type-0 transaction */
55 __raw_writel(pbca
, KS8695_PCI_VA
+ KS8695_PBCA
);
57 /* use Type-1 transaction */
58 __raw_writel(pbca
| PBCA_TYPE1
, KS8695_PCI_VA
+ KS8695_PBCA
);
64 * The KS8695 datasheet prohibits anything other than 32bit accesses
65 * to the IO registers, so all our configuration must be done with
66 * 32bit operations, and the correct bit masking and shifting.
69 static int ks8695_pci_readconfig(struct pci_bus
*bus
,
70 unsigned int devfn
, int where
, int size
, u32
*value
)
72 ks8695_pci_setupconfig(bus
->number
, devfn
, where
);
74 *value
= __raw_readl(KS8695_PCI_VA
+ KS8695_PBCD
);
80 *value
= *value
>> ((where
& 2) * 8);
84 *value
= *value
>> ((where
& 3) * 8);
90 printk("read: %d,%08x,%02x,%d: %08x (%08x)\n",
91 bus
->number
, devfn
, where
, size
, *value
,
92 __raw_readl(KS8695_PCI_VA
+ KS8695_PBCD
));
95 return PCIBIOS_SUCCESSFUL
;
98 static int ks8695_pci_writeconfig(struct pci_bus
*bus
,
99 unsigned int devfn
, int where
, int size
, u32 value
)
104 printk("write: %d,%08x,%02x,%d: %08x\n",
105 bus
->number
, devfn
, where
, size
, value
);
108 ks8695_pci_setupconfig(bus
->number
, devfn
, where
);
112 __raw_writel(value
, KS8695_PCI_VA
+ KS8695_PBCD
);
115 tmp
= __raw_readl(KS8695_PCI_VA
+ KS8695_PBCD
);
116 tmp
&= ~(0xffff << ((where
& 2) * 8));
117 tmp
|= value
<< ((where
& 2) * 8);
119 __raw_writel(tmp
, KS8695_PCI_VA
+ KS8695_PBCD
);
122 tmp
= __raw_readl(KS8695_PCI_VA
+ KS8695_PBCD
);
123 tmp
&= ~(0xff << ((where
& 3) * 8));
124 tmp
|= value
<< ((where
& 3) * 8);
126 __raw_writel(tmp
, KS8695_PCI_VA
+ KS8695_PBCD
);
130 return PCIBIOS_SUCCESSFUL
;
133 static void ks8695_local_writeconfig(int where
, u32 value
)
135 ks8695_pci_setupconfig(0, 0, where
);
136 __raw_writel(value
, KS8695_PCI_VA
+ KS8695_PBCD
);
139 static struct pci_ops ks8695_pci_ops
= {
140 .read
= ks8695_pci_readconfig
,
141 .write
= ks8695_pci_writeconfig
,
144 static struct pci_bus
*ks8695_pci_scan_bus(int nr
, struct pci_sys_data
*sys
)
146 return pci_scan_bus(sys
->busnr
, &ks8695_pci_ops
, sys
);
149 static struct resource pci_mem
= {
150 .name
= "PCI Memory space",
151 .start
= KS8695_PCIMEM_PA
,
152 .end
= KS8695_PCIMEM_PA
+ (KS8695_PCIMEM_SIZE
- 1),
153 .flags
= IORESOURCE_MEM
,
156 static struct resource pci_io
= {
157 .name
= "PCI IO space",
158 .start
= KS8695_PCIIO_PA
,
159 .end
= KS8695_PCIIO_PA
+ (KS8695_PCIIO_SIZE
- 1),
160 .flags
= IORESOURCE_IO
,
163 static int __init
ks8695_pci_setup(int nr
, struct pci_sys_data
*sys
)
168 request_resource(&iomem_resource
, &pci_mem
);
169 request_resource(&ioport_resource
, &pci_io
);
171 sys
->resource
[0] = &pci_io
;
172 sys
->resource
[1] = &pci_mem
;
173 sys
->resource
[2] = NULL
;
175 /* Assign and enable processor bridge */
176 ks8695_local_writeconfig(PCI_BASE_ADDRESS_0
, KS8695_PCIMEM_PA
);
178 /* Enable bus-master & Memory Space access */
179 ks8695_local_writeconfig(PCI_COMMAND
, PCI_COMMAND_MASTER
| PCI_COMMAND_MEMORY
);
181 /* Set cache-line size & latency. */
182 ks8695_local_writeconfig(PCI_CACHE_LINE_SIZE
, (32 << 8) | (L1_CACHE_BYTES
/ sizeof(u32
)));
184 /* Reserve PCI memory space for PCI-AHB resources */
185 if (!request_mem_region(KS8695_PCIMEM_PA
, SZ_64M
, "PCI-AHB Bridge")) {
186 printk(KERN_ERR
"Cannot allocate PCI-AHB Bridge memory.\n");
193 static inline unsigned int size_mask(unsigned long size
)
198 static int ks8695_pci_fault(unsigned long addr
, unsigned int fsr
, struct pt_regs
*regs
)
200 unsigned long pc
= instruction_pointer(regs
);
201 unsigned long instr
= *(unsigned long *)pc
;
202 unsigned long cmdstat
;
204 cmdstat
= __raw_readl(KS8695_PCI_VA
+ KS8695_CRCFCS
);
206 printk(KERN_ERR
"PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx [%s%s%s%s%s]\n",
207 addr
, fsr
, regs
->ARM_pc
, regs
->ARM_lr
,
208 cmdstat
& (PCI_STATUS_SIG_TARGET_ABORT
<< 16) ? "GenTarget" : " ",
209 cmdstat
& (PCI_STATUS_REC_TARGET_ABORT
<< 16) ? "RecvTarget" : " ",
210 cmdstat
& (PCI_STATUS_REC_MASTER_ABORT
<< 16) ? "MasterAbort" : " ",
211 cmdstat
& (PCI_STATUS_SIG_SYSTEM_ERROR
<< 16) ? "SysError" : " ",
212 cmdstat
& (PCI_STATUS_DETECTED_PARITY
<< 16) ? "Parity" : " "
215 __raw_writel(cmdstat
, KS8695_PCI_VA
+ KS8695_CRCFCS
);
218 * If the instruction being executed was a read,
219 * make it look like it read all-ones.
221 if ((instr
& 0x0c100000) == 0x04100000) {
222 int reg
= (instr
>> 12) & 15;
225 if (instr
& 0x00400000)
230 regs
->uregs
[reg
] = val
;
235 if ((instr
& 0x0e100090) == 0x00100090) {
236 int reg
= (instr
>> 12) & 15;
238 regs
->uregs
[reg
] = -1;
246 static void __init
ks8695_pci_preinit(void)
248 /* stage 1 initialization, subid, subdevice = 0x0001 */
249 __raw_writel(0x00010001, KS8695_PCI_VA
+ KS8695_CRCSID
);
251 /* stage 2 initialization */
252 /* prefetch limits with 16 words, retry enable */
253 __raw_writel(0x40000000, KS8695_PCI_VA
+ KS8695_PBCS
);
255 /* configure memory mapping */
256 __raw_writel(KS8695_PCIMEM_PA
, KS8695_PCI_VA
+ KS8695_PMBA
);
257 __raw_writel(size_mask(KS8695_PCIMEM_SIZE
), KS8695_PCI_VA
+ KS8695_PMBAM
);
258 __raw_writel(KS8695_PCIMEM_PA
, KS8695_PCI_VA
+ KS8695_PMBAT
);
259 __raw_writel(0, KS8695_PCI_VA
+ KS8695_PMBAC
);
261 /* configure IO mapping */
262 __raw_writel(KS8695_PCIIO_PA
, KS8695_PCI_VA
+ KS8695_PIOBA
);
263 __raw_writel(size_mask(KS8695_PCIIO_SIZE
), KS8695_PCI_VA
+ KS8695_PIOBAM
);
264 __raw_writel(KS8695_PCIIO_PA
, KS8695_PCI_VA
+ KS8695_PIOBAT
);
265 __raw_writel(0, KS8695_PCI_VA
+ KS8695_PIOBAC
);
267 /* hook in fault handlers */
268 hook_fault_code(8, ks8695_pci_fault
, SIGBUS
, "external abort on non-linefetch");
269 hook_fault_code(10, ks8695_pci_fault
, SIGBUS
, "external abort on non-linefetch");
272 static void ks8695_show_pciregs(void)
277 printk(KERN_INFO
"PCI: CRCFID = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_CRCFID
));
278 printk(KERN_INFO
"PCI: CRCFCS = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_CRCFCS
));
279 printk(KERN_INFO
"PCI: CRCFRV = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_CRCFRV
));
280 printk(KERN_INFO
"PCI: CRCFLT = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_CRCFLT
));
281 printk(KERN_INFO
"PCI: CRCBMA = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_CRCBMA
));
282 printk(KERN_INFO
"PCI: CRCSID = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_CRCSID
));
283 printk(KERN_INFO
"PCI: CRCFIT = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_CRCFIT
));
285 printk(KERN_INFO
"PCI: PBM = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PBM
));
286 printk(KERN_INFO
"PCI: PBCS = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PBCS
));
288 printk(KERN_INFO
"PCI: PMBA = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PMBA
));
289 printk(KERN_INFO
"PCI: PMBAC = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PMBAC
));
290 printk(KERN_INFO
"PCI: PMBAM = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PMBAM
));
291 printk(KERN_INFO
"PCI: PMBAT = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PMBAT
));
293 printk(KERN_INFO
"PCI: PIOBA = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PIOBA
));
294 printk(KERN_INFO
"PCI: PIOBAC = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PIOBAC
));
295 printk(KERN_INFO
"PCI: PIOBAM = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PIOBAM
));
296 printk(KERN_INFO
"PCI: PIOBAT = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PIOBAT
));
300 static struct hw_pci ks8695_pci __initdata
= {
302 .preinit
= ks8695_pci_preinit
,
303 .setup
= ks8695_pci_setup
,
304 .scan
= ks8695_pci_scan_bus
,
306 .swizzle
= pci_std_swizzle
,
310 void __init
ks8695_init_pci(struct ks8695_pci_cfg
*cfg
)
312 if (__raw_readl(KS8695_PCI_VA
+ KS8695_CRCFRV
) & CFRV_GUEST
) {
313 printk("PCI: KS8695 in guest mode, not initialising\n");
317 printk(KERN_INFO
"PCI: Initialising\n");
318 ks8695_show_pciregs();
321 __raw_writel(cfg
->mode
<< 29, KS8695_PCI_VA
+ KS8695_PBM
);
323 ks8695_pci
.map_irq
= cfg
->map_irq
; /* board-specific map_irq method */
325 pci_common_init(&ks8695_pci
);