1 /*
2  * arch/arm/mach-ixp2000/pci.c
3  *
4  * PCI routines for IXDP2400/IXDP2800 boards
5  *
6  * Original Author: Naeem Afzal <naeem.m.afzal@intel.com>
7  * Maintained by: Deepak Saxena <dsaxena@plexity.net>
8  *
9  * Copyright 2002 Intel Corp.
10  * Copyright (C) 2003-2004 MontaVista Software, Inc.
11  *
12  *  This program is free software; you can redistribute  it and/or modify it
13  *  under  the terms of  the GNU General  Public License as published by the
14  *  Free Software Foundation;  either version 2 of the  License, or (at your
15  *  option) any later version.
16  */
17 
18 #include <linux/sched.h>
19 #include <linux/kernel.h>
20 #include <linux/pci.h>
21 #include <linux/interrupt.h>
22 #include <linux/mm.h>
23 #include <linux/init.h>
24 #include <linux/ioport.h>
25 #include <linux/delay.h>
26 #include <linux/io.h>
27 
28 #include <asm/irq.h>
29 #include <asm/system.h>
30 #include <mach/hardware.h>
31 
32 #include <asm/mach/pci.h>
33 
34 static volatile int pci_master_aborts = 0;
35 
36 static int clear_master_aborts(void);
37 
38 u32 *
ixp2000_pci_config_addr(unsigned int bus_nr,unsigned int devfn,int where)39 ixp2000_pci_config_addr(unsigned int bus_nr, unsigned int devfn, int where)
40 {
41 	u32 *paddress;
42 
43 	if (PCI_SLOT(devfn) > 7)
44 		return 0;
45 
46 	/* Must be dword aligned */
47 	where &= ~3;
48 
49 	/*
50 	 * For top bus, generate type 0, else type 1
51 	 */
52 	if (!bus_nr) {
53 		/* only bits[23:16] are used for IDSEL */
54 		paddress = (u32 *) (IXP2000_PCI_CFG0_VIRT_BASE
55 				    | (1 << (PCI_SLOT(devfn) + 16))
56 				    | (PCI_FUNC(devfn) << 8) | where);
57 	} else {
58 		paddress = (u32 *) (IXP2000_PCI_CFG1_VIRT_BASE
59 				    | (bus_nr << 16)
60 				    | (PCI_SLOT(devfn) << 11)
61 				    | (PCI_FUNC(devfn) << 8) | where);
62 	}
63 
64 	return paddress;
65 }
66 
67 /*
68  * Mask table, bits to mask for quantity of size 1, 2 or 4 bytes.
69  * 0 and 3 are not valid indexes...
70  */
71 static u32 bytemask[] = {
72 	/*0*/	0,
73 	/*1*/	0xff,
74 	/*2*/	0xffff,
75 	/*3*/	0,
76 	/*4*/	0xffffffff,
77 };
78 
79 
ixp2000_pci_read_config(struct pci_bus * bus,unsigned int devfn,int where,int size,u32 * value)80 int ixp2000_pci_read_config(struct pci_bus *bus, unsigned int devfn, int where,
81 				int size, u32 *value)
82 {
83 	u32 n;
84 	u32 *addr;
85 
86 	n = where % 4;
87 
88 	addr = ixp2000_pci_config_addr(bus->number, devfn, where);
89 	if (!addr)
90 		return PCIBIOS_DEVICE_NOT_FOUND;
91 
92 	pci_master_aborts = 0;
93 	*value = (*addr >> (8*n)) & bytemask[size];
94 	if (pci_master_aborts) {
95 		pci_master_aborts = 0;
96 		*value = 0xffffffff;
97 		return PCIBIOS_DEVICE_NOT_FOUND;
98 	}
99 
100 	return PCIBIOS_SUCCESSFUL;
101 }
102 
103 /*
104  * We don't do error checks by calling clear_master_aborts() b/c the
105  * assumption is that the caller did a read first to make sure a device
106  * exists.
107  */
ixp2000_pci_write_config(struct pci_bus * bus,unsigned int devfn,int where,int size,u32 value)108 int ixp2000_pci_write_config(struct pci_bus *bus, unsigned int devfn, int where,
109 				int size, u32 value)
110 {
111 	u32 mask;
112 	u32 *addr;
113 	u32 temp;
114 
115 	mask = ~(bytemask[size] << ((where % 0x4) * 8));
116 	addr = ixp2000_pci_config_addr(bus->number, devfn, where);
117 	if (!addr)
118 		return PCIBIOS_DEVICE_NOT_FOUND;
119 	temp = (u32) (value) << ((where % 0x4) * 8);
120 	*addr = (*addr & mask) | temp;
121 
122 	clear_master_aborts();
123 
124 	return PCIBIOS_SUCCESSFUL;
125 }
126 
127 
128 static struct pci_ops ixp2000_pci_ops = {
129 	.read	= ixp2000_pci_read_config,
130 	.write	= ixp2000_pci_write_config
131 };
132 
ixp2000_pci_scan_bus(int nr,struct pci_sys_data * sysdata)133 struct pci_bus *ixp2000_pci_scan_bus(int nr, struct pci_sys_data *sysdata)
134 {
135 	return pci_scan_root_bus(NULL, sysdata->busnr, &ixp2000_pci_ops,
136 				 sysdata, &sysdata->resources);
137 }
138 
139 
ixp2000_pci_abort_handler(unsigned long addr,unsigned int fsr,struct pt_regs * regs)140 int ixp2000_pci_abort_handler(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
141 {
142 
143 	volatile u32 temp;
144 	unsigned long flags;
145 
146 	pci_master_aborts = 1;
147 
148 	local_irq_save(flags);
149 	temp = *(IXP2000_PCI_CONTROL);
150 	if (temp & ((1 << 8) | (1 << 5))) {
151 		ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp);
152 	}
153 
154 	temp = *(IXP2000_PCI_CMDSTAT);
155 	if (temp & (1 << 29)) {
156 		while (temp & (1 << 29)) {
157 			ixp2000_reg_write(IXP2000_PCI_CMDSTAT, temp);
158 			temp = *(IXP2000_PCI_CMDSTAT);
159 		}
160 	}
161 	local_irq_restore(flags);
162 
163 	/*
164 	 * If it was an imprecise abort, then we need to correct the
165 	 * return address to be _after_ the instruction.
166 	 */
167 	if (fsr & (1 << 10))
168 		regs->ARM_pc += 4;
169 
170 	return 0;
171 }
172 
173 int
clear_master_aborts(void)174 clear_master_aborts(void)
175 {
176 	volatile u32 temp;
177 	unsigned long flags;
178 
179 	local_irq_save(flags);
180 	temp = *(IXP2000_PCI_CONTROL);
181 	if (temp & ((1 << 8) | (1 << 5))) {
182 		ixp2000_reg_wrb(IXP2000_PCI_CONTROL, temp);
183 	}
184 
185 	temp = *(IXP2000_PCI_CMDSTAT);
186 	if (temp & (1 << 29)) {
187 		while (temp & (1 << 29)) {
188 			ixp2000_reg_write(IXP2000_PCI_CMDSTAT, temp);
189 			temp = *(IXP2000_PCI_CMDSTAT);
190 		}
191 	}
192 	local_irq_restore(flags);
193 
194 	return 0;
195 }
196 
197 void __init
ixp2000_pci_preinit(void)198 ixp2000_pci_preinit(void)
199 {
200 	pci_set_flags(0);
201 
202 	pcibios_min_io = 0;
203 	pcibios_min_mem = 0;
204 
205 #ifndef CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO
206 	/*
207 	 * Configure the PCI unit to properly byteswap I/O transactions,
208 	 * and verify that it worked.
209 	 */
210 	ixp2000_reg_write(IXP2000_PCI_CONTROL,
211 			  (*IXP2000_PCI_CONTROL | PCI_CONTROL_IEE));
212 
213 	if ((*IXP2000_PCI_CONTROL & PCI_CONTROL_IEE) == 0)
214 		panic("IXP2000: PCI I/O is broken on this ixp model, and "
215 			"the needed workaround has not been configured in");
216 #endif
217 
218 	hook_fault_code(16+6, ixp2000_pci_abort_handler, SIGBUS, 0,
219 				"PCI config cycle to non-existent device");
220 }
221 
222 
223 /*
224  * IXP2000 systems often have large resource requirements, so we just
225  * use our own resource space.
226  */
227 static struct resource ixp2000_pci_mem_space = {
228 	.start	= 0xe0000000,
229 	.end	= 0xffffffff,
230 	.flags	= IORESOURCE_MEM,
231 	.name	= "PCI Mem Space"
232 };
233 
234 static struct resource ixp2000_pci_io_space = {
235 	.start	= 0x00010000,
236 	.end	= 0x0001ffff,
237 	.flags	= IORESOURCE_IO,
238 	.name	= "PCI I/O Space"
239 };
240 
ixp2000_pci_setup(int nr,struct pci_sys_data * sys)241 int ixp2000_pci_setup(int nr, struct pci_sys_data *sys)
242 {
243 	if (nr >= 1)
244 		return 0;
245 
246 	pci_add_resource(&sys->resources, &ixp2000_pci_io_space);
247 	pci_add_resource(&sys->resources, &ixp2000_pci_mem_space);
248 
249 	return 1;
250 }
251 
252