1/* pci-frv.c: low-level PCI access routines
2 *
3 * Copyright (C) 2003-5 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 * - Derived from the i386 equivalent stuff
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version
10 * 2 of the License, or (at your option) any later version.
11 */
12
13#include <linux/types.h>
14#include <linux/kernel.h>
15#include <linux/pci.h>
16#include <linux/init.h>
17#include <linux/ioport.h>
18#include <linux/errno.h>
19
20#include "pci-frv.h"
21
22
23/*
24 * We need to avoid collisions with `mirrored' VGA ports
25 * and other strange ISA hardware, so we always want the
26 * addresses to be allocated in the 0x000-0x0ff region
27 * modulo 0x400.
28 *
29 * Why? Because some silly external IO cards only decode
30 * the low 10 bits of the IO address. The 0x00-0xff region
31 * is reserved for motherboard devices that decode all 16
32 * bits, so it's ok to allocate at, say, 0x2800-0x28ff,
33 * but we want to try to avoid allocating at 0x2900-0x2bff
34 * which might have be mirrored at 0x0100-0x03ff..
35 */
36void
37pcibios_align_resource(void *data, struct resource *res,
38		       resource_size_t size, resource_size_t align)
39{
40	if (res->flags & IORESOURCE_IO) {
41		resource_size_t start = res->start;
42
43		if (start & 0x300) {
44			start = (start + 0x3ff) & ~0x3ff;
45			res->start = start;
46		}
47	}
48}
49
50
51
52static void __init pcibios_allocate_bus_resources(struct list_head *bus_list)
53{
54	struct list_head *ln;
55	struct pci_bus *bus;
56	struct pci_dev *dev;
57	int idx;
58	struct resource *r, *pr;
59
60	/* Depth-First Search on bus tree */
61	for (ln=bus_list->next; ln != bus_list; ln=ln->next) {
62		bus = pci_bus_b(ln);
63		if ((dev = bus->self)) {
64			for (idx = PCI_BRIDGE_RESOURCES; idx < PCI_NUM_RESOURCES; idx++) {
65				r = &dev->resource[idx];
66				if (!r->start)
67					continue;
68				pr = pci_find_parent_resource(dev, r);
69				if (!pr || request_resource(pr, r) < 0)
70					printk(KERN_ERR "PCI: Cannot allocate resource region %d of bridge %s\n", idx, pci_name(dev));
71			}
72		}
73		pcibios_allocate_bus_resources(&bus->children);
74	}
75}
76
77static void __init pcibios_allocate_resources(int pass)
78{
79	struct pci_dev *dev = NULL;
80	int idx, disabled;
81	u16 command;
82	struct resource *r, *pr;
83
84	for_each_pci_dev(dev) {
85		pci_read_config_word(dev, PCI_COMMAND, &command);
86		for(idx = 0; idx < 6; idx++) {
87			r = &dev->resource[idx];
88			if (r->parent)		/* Already allocated */
89				continue;
90			if (!r->start)		/* Address not assigned at all */
91				continue;
92			if (r->flags & IORESOURCE_IO)
93				disabled = !(command & PCI_COMMAND_IO);
94			else
95				disabled = !(command & PCI_COMMAND_MEMORY);
96			if (pass == disabled) {
97				DBG("PCI: Resource %08lx-%08lx (f=%lx, d=%d, p=%d)\n",
98				    r->start, r->end, r->flags, disabled, pass);
99				pr = pci_find_parent_resource(dev, r);
100				if (!pr || request_resource(pr, r) < 0) {
101					printk(KERN_ERR "PCI: Cannot allocate resource region %d of device %s\n", idx, pci_name(dev));
102					/* We'll assign a new address later */
103					r->end -= r->start;
104					r->start = 0;
105				}
106			}
107		}
108		if (!pass) {
109			r = &dev->resource[PCI_ROM_RESOURCE];
110			if (r->flags & IORESOURCE_ROM_ENABLE) {
111				/* Turn the ROM off, leave the resource region, but keep it unregistered. */
112				u32 reg;
113				DBG("PCI: Switching off ROM of %s\n", pci_name(dev));
114				r->flags &= ~IORESOURCE_ROM_ENABLE;
115				pci_read_config_dword(dev, dev->rom_base_reg, &reg);
116				pci_write_config_dword(dev, dev->rom_base_reg, reg & ~PCI_ROM_ADDRESS_ENABLE);
117			}
118		}
119	}
120}
121
122static void __init pcibios_assign_resources(void)
123{
124	struct pci_dev *dev = NULL;
125	int idx;
126	struct resource *r;
127
128	for_each_pci_dev(dev) {
129		int class = dev->class >> 8;
130
131		/* Don't touch classless devices and host bridges */
132		if (!class || class == PCI_CLASS_BRIDGE_HOST)
133			continue;
134
135		for(idx=0; idx<6; idx++) {
136			r = &dev->resource[idx];
137
138			/*
139			 *  Don't touch IDE controllers and I/O ports of video cards!
140			 */
141			if ((class == PCI_CLASS_STORAGE_IDE && idx < 4) ||
142			    (class == PCI_CLASS_DISPLAY_VGA && (r->flags & IORESOURCE_IO)))
143				continue;
144
145			/*
146			 *  We shall assign a new address to this resource, either because
147			 *  the BIOS forgot to do so or because we have decided the old
148			 *  address was unusable for some reason.
149			 */
150			if (!r->start && r->end)
151				pci_assign_resource(dev, idx);
152		}
153
154		if (pci_probe & PCI_ASSIGN_ROMS) {
155			r = &dev->resource[PCI_ROM_RESOURCE];
156			r->end -= r->start;
157			r->start = 0;
158			if (r->end)
159				pci_assign_resource(dev, PCI_ROM_RESOURCE);
160		}
161	}
162}
163
164void __init pcibios_resource_survey(void)
165{
166	DBG("PCI: Allocating resources\n");
167	pcibios_allocate_bus_resources(&pci_root_buses);
168	pcibios_allocate_resources(0);
169	pcibios_allocate_resources(1);
170	pcibios_assign_resources();
171}
172
173int pcibios_enable_resources(struct pci_dev *dev, int mask)
174{
175	u16 cmd, old_cmd;
176	int idx;
177	struct resource *r;
178
179	pci_read_config_word(dev, PCI_COMMAND, &cmd);
180	old_cmd = cmd;
181	for(idx=0; idx<6; idx++) {
182		/* Only set up the requested stuff */
183		if (!(mask & (1<<idx)))
184			continue;
185
186		r = &dev->resource[idx];
187		if (!r->start && r->end) {
188			printk(KERN_ERR "PCI: Device %s not available because of resource collisions\n", pci_name(dev));
189			return -EINVAL;
190		}
191		if (r->flags & IORESOURCE_IO)
192			cmd |= PCI_COMMAND_IO;
193		if (r->flags & IORESOURCE_MEM)
194			cmd |= PCI_COMMAND_MEMORY;
195	}
196	if (dev->resource[PCI_ROM_RESOURCE].start)
197		cmd |= PCI_COMMAND_MEMORY;
198	if (cmd != old_cmd) {
199		printk("PCI: Enabling device %s (%04x -> %04x)\n", pci_name(dev), old_cmd, cmd);
200		pci_write_config_word(dev, PCI_COMMAND, cmd);
201	}
202	return 0;
203}
204
205/*
206 *  If we set up a device for bus mastering, we need to check the latency
207 *  timer as certain crappy BIOSes forget to set it properly.
208 */
209unsigned int pcibios_max_latency = 255;
210
211void pcibios_set_master(struct pci_dev *dev)
212{
213	u8 lat;
214	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat);
215	if (lat < 16)
216		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency;
217	else if (lat > pcibios_max_latency)
218		lat = pcibios_max_latency;
219	else
220		return;
221	printk(KERN_DEBUG "PCI: Setting latency timer of device %s to %d\n", pci_name(dev), lat);
222	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat);
223}
224