1/*
2 * pci.c - Low-Level PCI Access in IA-64
3 *
4 * Derived from bios32.c of i386 tree.
5 */
6#include <linux/config.h>
7
8#include <linux/types.h>
9#include <linux/kernel.h>
10#include <linux/pci.h>
11#include <linux/init.h>
12#include <linux/ioport.h>
13#include <linux/slab.h>
14#include <linux/smp_lock.h>
15#include <linux/spinlock.h>
16#include <linux/acpi.h>
17
18#include <asm/machvec.h>
19#include <asm/page.h>
20#include <asm/segment.h>
21#include <asm/system.h>
22#include <asm/io.h>
23
24#include <asm/sal.h>
25
26
27#ifdef CONFIG_SMP
28# include <asm/smp.h>
29#endif
30#include <asm/irq.h>
31
32
33#undef DEBUG
34#define DEBUG
35
36#ifdef DEBUG
37#define DBG(x...) printk(x)
38#else
39#define DBG(x...)
40#endif
41
42#ifdef CONFIG_IA64_MCA
43extern void ia64_mca_check_errors( void );
44#endif
45
46struct pci_fixup pcibios_fixups[1];
47
48struct pci_ops *pci_root_ops;
49
50int (*pci_config_read)(int seg, int bus, int dev, int fn, int reg, int len, u32 *value);
51int (*pci_config_write)(int seg, int bus, int dev, int fn, int reg, int len, u32 value);
52
53
54/*
55 * Low-level SAL-based PCI configuration access functions. Note that SAL
56 * calls are already serialized (via sal_lock), so we don't need another
57 * synchronization mechanism here.
58 */
59
60#define PCI_SAL_ADDRESS(seg, bus, dev, fn, reg) \
61	((u64)(seg << 24) | (u64)(bus << 16) | \
62	 (u64)(dev << 11) | (u64)(fn << 8) | (u64)(reg))
63
64static int
65pci_sal_read (int seg, int bus, int dev, int fn, int reg, int len, u32 *value)
66{
67	int result = 0;
68	u64 data = 0;
69
70	if (!value || (seg > 255) || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
71		return -EINVAL;
72
73	result = ia64_sal_pci_config_read(PCI_SAL_ADDRESS(seg, bus, dev, fn, reg), len, &data);
74
75	*value = (u32) data;
76
77	return result;
78}
79
80static int
81pci_sal_write (int seg, int bus, int dev, int fn, int reg, int len, u32 value)
82{
83	if ((seg > 255) || (bus > 255) || (dev > 31) || (fn > 7) || (reg > 255))
84		return -EINVAL;
85
86	return ia64_sal_pci_config_write(PCI_SAL_ADDRESS(seg, bus, dev, fn, reg), len, value);
87}
88
89
90static int
91pci_sal_read_config_byte (struct pci_dev *dev, int where, u8 *value)
92{
93	int result = 0;
94	u32 data = 0;
95
96	if (!value)
97		return -EINVAL;
98
99	result = pci_sal_read(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
100			      PCI_FUNC(dev->devfn), where, 1, &data);
101
102	*value = (u8) data;
103
104	return result;
105}
106
107static int
108pci_sal_read_config_word (struct pci_dev *dev, int where, u16 *value)
109{
110	int result = 0;
111	u32 data = 0;
112
113	if (!value)
114		return -EINVAL;
115
116	result = pci_sal_read(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
117			      PCI_FUNC(dev->devfn), where, 2, &data);
118
119	*value = (u16) data;
120
121	return result;
122}
123
124static int
125pci_sal_read_config_dword (struct pci_dev *dev, int where, u32 *value)
126{
127	if (!value)
128		return -EINVAL;
129
130	return pci_sal_read(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
131			    PCI_FUNC(dev->devfn), where, 4, value);
132}
133
134static int
135pci_sal_write_config_byte (struct pci_dev *dev, int where, u8 value)
136{
137	return pci_sal_write(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
138			     PCI_FUNC(dev->devfn), where, 1, value);
139}
140
141static int
142pci_sal_write_config_word (struct pci_dev *dev, int where, u16 value)
143{
144	return pci_sal_write(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
145			     PCI_FUNC(dev->devfn), where, 2, value);
146}
147
148static int
149pci_sal_write_config_dword (struct pci_dev *dev, int where, u32 value)
150{
151	return pci_sal_write(PCI_SEGMENT(dev), dev->bus->number, PCI_SLOT(dev->devfn),
152			     PCI_FUNC(dev->devfn), where, 4, value);
153}
154
155struct pci_ops pci_sal_ops = {
156	pci_sal_read_config_byte,
157	pci_sal_read_config_word,
158	pci_sal_read_config_dword,
159	pci_sal_write_config_byte,
160	pci_sal_write_config_word,
161	pci_sal_write_config_dword
162};
163
164
165/*
166 * Initialization. Uses the SAL interface
167 */
168
169static struct pci_controller *
170alloc_pci_controller(int seg)
171{
172	struct pci_controller *controller;
173
174	controller = kmalloc(sizeof(*controller), GFP_KERNEL);
175	if (!controller)
176		return NULL;
177
178	memset(controller, 0, sizeof(*controller));
179	controller->segment = seg;
180	return controller;
181}
182
183static struct pci_bus *
184scan_root_bus(int bus, struct pci_ops *ops, void *sysdata)
185{
186	struct pci_bus *b;
187
188	/*
189	 * We know this is a new root bus we haven't seen before, so
190	 * scan it, even if we've seen the same bus number in a different
191	 * segment.
192	 */
193	b = kmalloc(sizeof(*b), GFP_KERNEL);
194	if (!b)
195		return NULL;
196
197	memset(b, 0, sizeof(*b));
198	INIT_LIST_HEAD(&b->children);
199	INIT_LIST_HEAD(&b->devices);
200
201	list_add_tail(&b->node, &pci_root_buses);
202
203	b->number = b->secondary = bus;
204	b->resource[0] = &ioport_resource;
205	b->resource[1] = &iomem_resource;
206
207	b->sysdata = sysdata;
208	b->ops = ops;
209	b->subordinate = pci_do_scan_bus(b);
210
211	return b;
212}
213
214struct pci_bus *
215pcibios_scan_root(void *handle, int seg, int bus)
216{
217	struct pci_controller *controller;
218	u64 base, size, offset;
219
220	printk("PCI: Probing PCI hardware on bus (%02x:%02x)\n", seg, bus);
221
222	controller = alloc_pci_controller(seg);
223	if (!controller)
224		return NULL;
225
226	controller->acpi_handle = handle;
227
228	acpi_get_addr_space(handle, ACPI_MEMORY_RANGE, &base, &size, &offset);
229	controller->mem_offset = offset;
230
231	return scan_root_bus(bus, pci_root_ops, controller);
232}
233
234void __init
235pcibios_config_init (void)
236{
237	if (pci_root_ops)
238		return;
239
240	printk("PCI: Using SAL to access configuration space\n");
241
242	pci_root_ops = &pci_sal_ops;
243	pci_config_read = pci_sal_read;
244	pci_config_write = pci_sal_write;
245
246	return;
247}
248
249void __init
250pcibios_init (void)
251{
252#	define PCI_BUSES_TO_SCAN 255
253	int i = 0;
254	struct pci_controller *controller;
255
256#ifdef CONFIG_IA64_MCA
257	ia64_mca_check_errors();    /* For post-failure MCA error logging */
258#endif
259
260	pcibios_config_init();
261
262	platform_pci_fixup(0);	/* phase 0 fixups (before buses scanned) */
263
264	printk("PCI: Probing PCI hardware\n");
265	controller = alloc_pci_controller(0);
266	if (controller)
267		for (i = 0; i < PCI_BUSES_TO_SCAN; i++)
268			pci_scan_bus(i, pci_root_ops, controller);
269
270	platform_pci_fixup(1);	/* phase 1 fixups (after buses scanned) */
271
272	return;
273}
274
275static void __init
276pcibios_fixup_resource(struct resource *res, u64 offset)
277{
278	res->start += offset;
279	res->end += offset;
280}
281
282void __init
283pcibios_fixup_device_resources(struct pci_dev *dev, struct pci_bus *bus)
284{
285	int i;
286
287	for (i = 0; i < PCI_NUM_RESOURCES; i++) {
288		if (!dev->resource[i].start)
289			continue;
290		if (dev->resource[i].flags & IORESOURCE_MEM)
291			pcibios_fixup_resource(&dev->resource[i],
292				PCI_CONTROLLER(dev)->mem_offset);
293	}
294}
295
296/*
297 *  Called after each bus is probed, but before its children
298 *  are examined.
299 */
300void __init
301pcibios_fixup_bus (struct pci_bus *b)
302{
303	struct list_head *ln;
304
305	for (ln = b->devices.next; ln != &b->devices; ln = ln->next)
306		pcibios_fixup_device_resources(pci_dev_b(ln), b);
307}
308
309void __init
310pcibios_update_resource (struct pci_dev *dev, struct resource *root,
311			 struct resource *res, int resource)
312{
313	unsigned long where, size;
314	u32 reg;
315
316	where = PCI_BASE_ADDRESS_0 + (resource * 4);
317	size = res->end - res->start;
318	pci_read_config_dword(dev, where, &reg);
319	reg = (reg & size) | (((u32)(res->start - root->start)) & ~size);
320	pci_write_config_dword(dev, where, reg);
321
322}
323
324void __init
325pcibios_update_irq (struct pci_dev *dev, int irq)
326{
327	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
328
329}
330
331void __init
332pcibios_fixup_pbus_ranges (struct pci_bus * bus, struct pbus_set_ranges_data * ranges)
333{
334	ranges->io_start -= bus->resource[0]->start;
335	ranges->io_end -= bus->resource[0]->start;
336	ranges->mem_start -= bus->resource[1]->start;
337	ranges->mem_end -= bus->resource[1]->start;
338}
339
340int
341pcibios_enable_device (struct pci_dev *dev)
342{
343	u16 cmd, old_cmd;
344	int idx;
345	struct resource *r;
346
347	if (!dev)
348		return -EINVAL;
349
350 	platform_pci_enable_device(dev);
351
352	pci_read_config_word(dev, PCI_COMMAND, &cmd);
353	old_cmd = cmd;
354	for (idx=0; idx<6; idx++) {
355		r = &dev->resource[idx];
356		if (!r->start && r->end) {
357			printk(KERN_ERR
358			       "PCI: Device %s not available because of resource collisions\n",
359			       dev->slot_name);
360			return -EINVAL;
361		}
362		if (r->flags & IORESOURCE_IO)
363			cmd |= PCI_COMMAND_IO;
364		if (r->flags & IORESOURCE_MEM)
365			cmd |= PCI_COMMAND_MEMORY;
366	}
367	if (dev->resource[PCI_ROM_RESOURCE].start)
368		cmd |= PCI_COMMAND_MEMORY;
369	if (cmd != old_cmd) {
370		printk("PCI: Enabling device %s (%04x -> %04x)\n", dev->slot_name, old_cmd, cmd);
371		pci_write_config_word(dev, PCI_COMMAND, cmd);
372	}
373
374	printk(KERN_INFO "PCI: Found IRQ %d for device %s\n", dev->irq, dev->slot_name);
375
376	return 0;
377}
378
379void
380pcibios_align_resource (void *data, struct resource *res,
381		        unsigned long size, unsigned long align)
382{
383}
384
385/*
386 * PCI BIOS setup, always defaults to SAL interface
387 */
388char * __init
389pcibios_setup (char *str)
390{
391	return NULL;
392}
393
394int
395pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma,
396		     enum pci_mmap_state mmap_state, int write_combine)
397{
398	/*
399	 * I/O space cannot be accessed via normal processor loads and stores on this
400	 * platform.
401	 */
402	if (mmap_state == pci_mmap_io)
403		return -EINVAL;
404
405	/*
406	 * Leave vm_pgoff as-is, the PCI space address is the physical address on this
407	 * platform.
408	 */
409	vma->vm_flags |= (VM_SHM | VM_LOCKED | VM_IO);
410
411	if (write_combine)
412		vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
413	else
414		vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
415
416	if (remap_page_range(vma->vm_start, vma->vm_pgoff << PAGE_SHIFT,
417			     vma->vm_end - vma->vm_start,
418			     vma->vm_page_prot))
419		return -EAGAIN;
420
421	return 0;
422}
423