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 <mach/hardware.h>
42 static void ks8695_pci_setupconfig(unsigned int bus_nr
, unsigned int devfn
, unsigned int where
)
46 pbca
= PBCA_ENABLE
| (where
& ~3);
47 pbca
|= PCI_SLOT(devfn
) << 11 ;
48 pbca
|= PCI_FUNC(devfn
) << 8;
52 /* use Type-0 transaction */
53 __raw_writel(pbca
, KS8695_PCI_VA
+ KS8695_PBCA
);
55 /* use Type-1 transaction */
56 __raw_writel(pbca
| PBCA_TYPE1
, KS8695_PCI_VA
+ KS8695_PBCA
);
60 static void __iomem
*ks8695_pci_map_bus(struct pci_bus
*bus
, unsigned int devfn
,
63 ks8695_pci_setupconfig(bus
->number
, devfn
, where
);
64 return KS8695_PCI_VA
+ KS8695_PBCD
;
67 static void ks8695_local_writeconfig(int where
, u32 value
)
69 ks8695_pci_setupconfig(0, 0, where
);
70 __raw_writel(value
, KS8695_PCI_VA
+ KS8695_PBCD
);
73 static struct pci_ops ks8695_pci_ops
= {
74 .map_bus
= ks8695_pci_map_bus
,
75 .read
= pci_generic_config_read32
,
76 .write
= pci_generic_config_write32
,
79 static struct resource pci_mem
= {
80 .name
= "PCI Memory space",
81 .start
= KS8695_PCIMEM_PA
,
82 .end
= KS8695_PCIMEM_PA
+ (KS8695_PCIMEM_SIZE
- 1),
83 .flags
= IORESOURCE_MEM
,
86 static struct resource pci_io
= {
87 .name
= "PCI IO space",
88 .start
= KS8695_PCIIO_PA
,
89 .end
= KS8695_PCIIO_PA
+ (KS8695_PCIIO_SIZE
- 1),
90 .flags
= IORESOURCE_IO
,
93 static int __init
ks8695_pci_setup(int nr
, struct pci_sys_data
*sys
)
98 request_resource(&iomem_resource
, &pci_mem
);
99 request_resource(&ioport_resource
, &pci_io
);
101 pci_add_resource_offset(&sys
->resources
, &pci_io
, sys
->io_offset
);
102 pci_add_resource_offset(&sys
->resources
, &pci_mem
, sys
->mem_offset
);
104 /* Assign and enable processor bridge */
105 ks8695_local_writeconfig(PCI_BASE_ADDRESS_0
, KS8695_PCIMEM_PA
);
107 /* Enable bus-master & Memory Space access */
108 ks8695_local_writeconfig(PCI_COMMAND
, PCI_COMMAND_MASTER
| PCI_COMMAND_MEMORY
);
110 /* Set cache-line size & latency. */
111 ks8695_local_writeconfig(PCI_CACHE_LINE_SIZE
, (32 << 8) | (L1_CACHE_BYTES
/ sizeof(u32
)));
113 /* Reserve PCI memory space for PCI-AHB resources */
114 if (!request_mem_region(KS8695_PCIMEM_PA
, SZ_64M
, "PCI-AHB Bridge")) {
115 printk(KERN_ERR
"Cannot allocate PCI-AHB Bridge memory.\n");
122 static inline unsigned int size_mask(unsigned long size
)
127 static int ks8695_pci_fault(unsigned long addr
, unsigned int fsr
, struct pt_regs
*regs
)
129 unsigned long pc
= instruction_pointer(regs
);
130 unsigned long instr
= *(unsigned long *)pc
;
131 unsigned long cmdstat
;
133 cmdstat
= __raw_readl(KS8695_PCI_VA
+ KS8695_CRCFCS
);
135 printk(KERN_ERR
"PCI abort: address = 0x%08lx fsr = 0x%03x PC = 0x%08lx LR = 0x%08lx [%s%s%s%s%s]\n",
136 addr
, fsr
, regs
->ARM_pc
, regs
->ARM_lr
,
137 cmdstat
& (PCI_STATUS_SIG_TARGET_ABORT
<< 16) ? "GenTarget" : " ",
138 cmdstat
& (PCI_STATUS_REC_TARGET_ABORT
<< 16) ? "RecvTarget" : " ",
139 cmdstat
& (PCI_STATUS_REC_MASTER_ABORT
<< 16) ? "MasterAbort" : " ",
140 cmdstat
& (PCI_STATUS_SIG_SYSTEM_ERROR
<< 16) ? "SysError" : " ",
141 cmdstat
& (PCI_STATUS_DETECTED_PARITY
<< 16) ? "Parity" : " "
144 __raw_writel(cmdstat
, KS8695_PCI_VA
+ KS8695_CRCFCS
);
147 * If the instruction being executed was a read,
148 * make it look like it read all-ones.
150 if ((instr
& 0x0c100000) == 0x04100000) {
151 int reg
= (instr
>> 12) & 15;
154 if (instr
& 0x00400000)
159 regs
->uregs
[reg
] = val
;
164 if ((instr
& 0x0e100090) == 0x00100090) {
165 int reg
= (instr
>> 12) & 15;
167 regs
->uregs
[reg
] = -1;
175 static void __init
ks8695_pci_preinit(void)
177 /* make software reset to avoid freeze if PCI bus was messed up */
178 __raw_writel(0x80000000, KS8695_PCI_VA
+ KS8695_PBCS
);
180 /* stage 1 initialization, subid, subdevice = 0x0001 */
181 __raw_writel(0x00010001, KS8695_PCI_VA
+ KS8695_CRCSID
);
183 /* stage 2 initialization */
184 /* prefetch limits with 16 words, retry enable */
185 __raw_writel(0x40000000, KS8695_PCI_VA
+ KS8695_PBCS
);
187 /* configure memory mapping */
188 __raw_writel(KS8695_PCIMEM_PA
, KS8695_PCI_VA
+ KS8695_PMBA
);
189 __raw_writel(size_mask(KS8695_PCIMEM_SIZE
), KS8695_PCI_VA
+ KS8695_PMBAM
);
190 __raw_writel(KS8695_PCIMEM_PA
, KS8695_PCI_VA
+ KS8695_PMBAT
);
191 __raw_writel(0, KS8695_PCI_VA
+ KS8695_PMBAC
);
193 /* configure IO mapping */
194 __raw_writel(KS8695_PCIIO_PA
, KS8695_PCI_VA
+ KS8695_PIOBA
);
195 __raw_writel(size_mask(KS8695_PCIIO_SIZE
), KS8695_PCI_VA
+ KS8695_PIOBAM
);
196 __raw_writel(KS8695_PCIIO_PA
, KS8695_PCI_VA
+ KS8695_PIOBAT
);
197 __raw_writel(0, KS8695_PCI_VA
+ KS8695_PIOBAC
);
199 /* hook in fault handlers */
200 hook_fault_code(8, ks8695_pci_fault
, SIGBUS
, 0, "external abort on non-linefetch");
201 hook_fault_code(10, ks8695_pci_fault
, SIGBUS
, 0, "external abort on non-linefetch");
204 static void ks8695_show_pciregs(void)
209 printk(KERN_INFO
"PCI: CRCFID = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_CRCFID
));
210 printk(KERN_INFO
"PCI: CRCFCS = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_CRCFCS
));
211 printk(KERN_INFO
"PCI: CRCFRV = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_CRCFRV
));
212 printk(KERN_INFO
"PCI: CRCFLT = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_CRCFLT
));
213 printk(KERN_INFO
"PCI: CRCBMA = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_CRCBMA
));
214 printk(KERN_INFO
"PCI: CRCSID = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_CRCSID
));
215 printk(KERN_INFO
"PCI: CRCFIT = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_CRCFIT
));
217 printk(KERN_INFO
"PCI: PBM = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PBM
));
218 printk(KERN_INFO
"PCI: PBCS = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PBCS
));
220 printk(KERN_INFO
"PCI: PMBA = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PMBA
));
221 printk(KERN_INFO
"PCI: PMBAC = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PMBAC
));
222 printk(KERN_INFO
"PCI: PMBAM = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PMBAM
));
223 printk(KERN_INFO
"PCI: PMBAT = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PMBAT
));
225 printk(KERN_INFO
"PCI: PIOBA = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PIOBA
));
226 printk(KERN_INFO
"PCI: PIOBAC = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PIOBAC
));
227 printk(KERN_INFO
"PCI: PIOBAM = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PIOBAM
));
228 printk(KERN_INFO
"PCI: PIOBAT = %08x\n", __raw_readl(KS8695_PCI_VA
+ KS8695_PIOBAT
));
232 static struct hw_pci ks8695_pci __initdata
= {
234 .ops
= &ks8695_pci_ops
,
235 .preinit
= ks8695_pci_preinit
,
236 .setup
= ks8695_pci_setup
,
241 void __init
ks8695_init_pci(struct ks8695_pci_cfg
*cfg
)
243 if (__raw_readl(KS8695_PCI_VA
+ KS8695_CRCFRV
) & CFRV_GUEST
) {
244 printk("PCI: KS8695 in guest mode, not initialising\n");
251 printk(KERN_INFO
"PCI: Initialising\n");
252 ks8695_show_pciregs();
255 __raw_writel(cfg
->mode
<< 29, KS8695_PCI_VA
+ KS8695_PBM
);
257 ks8695_pci
.map_irq
= cfg
->map_irq
; /* board-specific map_irq method */
259 pci_common_init(&ks8695_pci
);