1/* Stand alone funtions for QSpan Tundra support.
2 */
3#include <linux/types.h>
4#include <linux/pci.h>
5#include <asm/mpc8xx.h>
6
7extern void puthex(unsigned long val);
8extern void puts(const char *);
9
10/* To map PCI devices, you first write 0xffffffff into the device
11 * base address registers.  When the register is read back, the
12 * number of most significant '1' bits describes the amount of address
13 * space needed for mapping.  If the most significant bit is not set,
14 * either the device does not use that address register, or it has
15 * a fixed address that we can't change.  After the address is assigned,
16 * the command register has to be written to enable the card.
17 */
18typedef struct {
19	u_char	pci_bus;
20	u_char	pci_devfn;
21	ushort	pci_command;
22	uint	pci_addrs[6];
23} pci_map_t;
24
25/* We should probably dynamically allocate these structures.
26*/
27#define MAX_PCI_DEVS	32
28int	pci_dev_cnt;
29pci_map_t	pci_map[MAX_PCI_DEVS];
30
31void pci_conf_write(int bus, int device, int func, int reg, uint writeval);
32void pci_conf_read(int bus, int device, int func, int reg, void *readval);
33void probe_addresses(int bus, int devfn);
34void map_pci_addrs(void);
35
36extern int
37qs_pci_read_config_byte(unsigned char bus, unsigned char dev_fn,
38			unsigned char offset, unsigned char *val);
39extern int
40qs_pci_read_config_word(unsigned char bus, unsigned char dev_fn,
41			unsigned char offset, unsigned short *val);
42extern int
43qs_pci_read_config_dword(unsigned char bus, unsigned char dev_fn,
44			 unsigned char offset, unsigned int *val);
45extern int
46qs_pci_write_config_byte(unsigned char bus, unsigned char dev_fn,
47			 unsigned char offset, unsigned char val);
48extern int
49qs_pci_write_config_word(unsigned char bus, unsigned char dev_fn,
50			 unsigned char offset, unsigned short val);
51extern int
52qs_pci_write_config_dword(unsigned char bus, unsigned char dev_fn,
53			  unsigned char offset, unsigned int val);
54
55
56/* This is a really stripped version of PCI bus scan.  All we are
57 * looking for are devices that exist.
58 */
59void
60pci_scanner(int addr_probe)
61{
62	unsigned int devfn, l, class, bus_number;
63	unsigned char hdr_type, is_multi;
64
65	is_multi = 0;
66	bus_number = 0;
67	for (devfn = 0; devfn < 0xff; ++devfn) {
68		/* The device numbers are comprised of upper 5 bits of
69		 * device number and lower 3 bits of multi-function number.
70		 */
71		if ((devfn & 7) && !is_multi) {
72			/* Don't scan multifunction addresses if this is
73			 * not a multifunction device.
74			 */
75			continue;
76		}
77
78		/* Read the header to determine card type.
79		*/
80		qs_pci_read_config_byte(bus_number, devfn, PCI_HEADER_TYPE,
81								&hdr_type);
82
83		/* If this is a base device number, check the header to
84		 * determine if it is mulifunction.
85		 */
86		if ((devfn & 7) == 0)
87			is_multi = hdr_type & 0x80;
88
89		/* Check to see if the board is really in the slot.
90		*/
91		qs_pci_read_config_dword(bus_number, devfn, PCI_VENDOR_ID, &l);
92		/* some broken boards return 0 if a slot is empty: */
93		if (l == 0xffffffff || l == 0x00000000 || l == 0x0000ffff ||
94							l == 0xffff0000) {
95			/* Nothing there.
96			*/
97			is_multi = 0;
98			continue;
99		}
100
101		/* If we are not performing an address probe,
102		 * just simply print out some information.
103		 */
104		if (!addr_probe) {
105			qs_pci_read_config_dword(bus_number, devfn,
106						PCI_CLASS_REVISION, &class);
107
108			class >>= 8;	    /* upper 3 bytes */
109
110			puts("Found ("); puthex(devfn >> 3);
111			puts(":"); puthex(devfn & 7);
112			puts("): vendor "); puthex(l & 0xffff);
113			puts(", device "); puthex((l >> 16) & 0xffff);
114			puts(", class "); puthex(class); puts("\n");
115		}
116		else {
117			/* If this is a "normal" device, build address list.
118			*/
119			if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_NORMAL)
120				probe_addresses(bus_number, devfn);
121		}
122	}
123
124	/* Now map the boards.
125	*/
126	if (addr_probe)
127		map_pci_addrs();
128}
129
130/* Probe addresses for the specified device.  This is a destructive
131 * operation because it writes the registers.
132 */
133void
134probe_addresses(bus, devfn)
135{
136	int	i;
137	uint	pciaddr;
138	ushort	pcicmd;
139	pci_map_t	*pm;
140
141	if (pci_dev_cnt >= MAX_PCI_DEVS) {
142		puts("Too many PCI devices\n");
143		return;
144	}
145
146	pm = &pci_map[pci_dev_cnt++];
147
148	pm->pci_bus = bus;
149	pm->pci_devfn = devfn;
150
151	for (i=0; i<6; i++) {
152		qs_pci_write_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4), -1);
153		qs_pci_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0 + (i * 4),
154								&pciaddr);
155		pm->pci_addrs[i] = pciaddr;
156		qs_pci_read_config_word(bus, devfn, PCI_COMMAND, &pcicmd);
157		pm->pci_command = pcicmd;
158	}
159}
160
161/* Map the cards into the PCI space.  The PCI has separate memory
162 * and I/O spaces.  In addition, some memory devices require mapping
163 * below 1M.  The least significant 4 bits of the address register
164 * provide information.  If this is an I/O device, only the LS bit
165 * is used to indicate that, so I/O devices can be mapped to a two byte
166 * boundard.  Memory addresses can be mapped to a 32 byte boundary.
167 * The QSpan implementations usually have a 1Gbyte space for each
168 * memory and I/O spaces.
169 *
170 * This isn't a terribly fancy algorithm.  I just map the spaces from
171 * the top starting with the largest address space.  When finished,
172 * the registers are written and the card enabled.
173 *
174 * While the Tundra can map a large address space on most boards, we
175 * need to be careful because it may overlap other devices (like IMMR).
176 */
177#define MEMORY_SPACE_SIZE	0x20000000
178#define IO_SPACE_SIZE		0x20000000
179
180void
181map_pci_addrs()
182{
183	uint	pci_mem_top, pci_mem_low;
184	uint	pci_io_top;
185	uint	addr_mask, reg_addr, space;
186	int	i, j;
187	pci_map_t *pm;
188
189	pci_mem_top = MEMORY_SPACE_SIZE;
190	pci_io_top = IO_SPACE_SIZE;
191	pci_mem_low = (1 * 1024 * 1024);	/* Below one meg addresses */
192
193	/* We can't map anything more than the maximum space, but test
194	 * for it anyway to catch devices out of range.
195	 */
196	addr_mask = 0x80000000;
197
198	do {
199		space = (~addr_mask) + 1;	/* Size of the space */
200		for (i=0; i<pci_dev_cnt; i++) {
201			pm = &pci_map[i];
202			for (j=0; j<6; j++) {
203				/* If the MS bit is not set, this has either
204				 * already been mapped, or is not used.
205				 */
206				reg_addr = pm->pci_addrs[j];
207				if ((reg_addr & 0x80000000) == 0)
208					continue;
209				if (reg_addr & PCI_BASE_ADDRESS_SPACE_IO) {
210					if ((reg_addr & PCI_BASE_ADDRESS_IO_MASK) != addr_mask)
211						continue;
212					if (pci_io_top < space) {
213						puts("Out of PCI I/O space\n");
214					}
215					else {
216						pci_io_top -= space;
217						pm->pci_addrs[j] = pci_io_top;
218						pm->pci_command |= PCI_COMMAND_IO;
219					}
220				}
221				else {
222					if ((reg_addr & PCI_BASE_ADDRESS_MEM_MASK) != addr_mask)
223						continue;
224
225					/* Memory space.  Test if below 1M.
226					*/
227					if (reg_addr & PCI_BASE_ADDRESS_MEM_TYPE_1M) {
228						if (pci_mem_low < space) {
229							puts("Out of PCI 1M space\n");
230						}
231						else {
232							pci_mem_low -= space;
233							pm->pci_addrs[j] = pci_mem_low;
234						}
235					}
236					else {
237						if (pci_mem_top < space) {
238							puts("Out of PCI Mem space\n");
239						}
240						else {
241							pci_mem_top -= space;
242							pm->pci_addrs[j] = pci_mem_top;
243						}
244					}
245					pm->pci_command |= PCI_COMMAND_MEMORY;
246				}
247			}
248		}
249		addr_mask >>= 1;
250		addr_mask |= 0x80000000;
251	} while (addr_mask != 0xfffffffe);
252
253	/* Now, run the list one more time and map everything.
254	*/
255	for (i=0; i<pci_dev_cnt; i++) {
256		pm = &pci_map[i];
257		for (j=0; j<6; j++) {
258			qs_pci_write_config_dword(pm->pci_bus, pm->pci_devfn,
259				PCI_BASE_ADDRESS_0 + (j * 4), pm->pci_addrs[j]);
260		}
261
262		/* Enable memory or address mapping.
263		*/
264		qs_pci_write_config_word(pm->pci_bus, pm->pci_devfn, PCI_COMMAND,
265			pm->pci_command);
266	}
267}
268