xref: /openbmc/u-boot/drivers/pci/pci_auto_old.c (revision 3eceff64)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
276a8b6a5SSimon Glass /*
32b81e8a3SSimon Glass  * PCI autoconfiguration library (legacy version, do not change)
476a8b6a5SSimon Glass  *
576a8b6a5SSimon Glass  * Author: Matt Porter <mporter@mvista.com>
676a8b6a5SSimon Glass  *
776a8b6a5SSimon Glass  * Copyright 2000 MontaVista Software Inc.
876a8b6a5SSimon Glass  */
976a8b6a5SSimon Glass 
1076a8b6a5SSimon Glass #include <common.h>
1176a8b6a5SSimon Glass #include <errno.h>
1276a8b6a5SSimon Glass #include <pci.h>
1376a8b6a5SSimon Glass 
142b81e8a3SSimon Glass /*
152b81e8a3SSimon Glass  * Do not change this file. Instead, convert your board to use CONFIG_DM_PCI
162b81e8a3SSimon Glass  * and change pci_auto.c.
172b81e8a3SSimon Glass  */
182b81e8a3SSimon Glass 
1976a8b6a5SSimon Glass /* the user can define CONFIG_SYS_PCI_CACHE_LINE_SIZE to avoid problems */
2076a8b6a5SSimon Glass #ifndef CONFIG_SYS_PCI_CACHE_LINE_SIZE
2176a8b6a5SSimon Glass #define CONFIG_SYS_PCI_CACHE_LINE_SIZE	8
2276a8b6a5SSimon Glass #endif
2376a8b6a5SSimon Glass 
2476a8b6a5SSimon Glass /*
2576a8b6a5SSimon Glass  *
2676a8b6a5SSimon Glass  */
2776a8b6a5SSimon Glass 
pciauto_setup_device(struct pci_controller * hose,pci_dev_t dev,int bars_num,struct pci_region * mem,struct pci_region * prefetch,struct pci_region * io)2876a8b6a5SSimon Glass void pciauto_setup_device(struct pci_controller *hose,
2976a8b6a5SSimon Glass 			  pci_dev_t dev, int bars_num,
3076a8b6a5SSimon Glass 			  struct pci_region *mem,
3176a8b6a5SSimon Glass 			  struct pci_region *prefetch,
3276a8b6a5SSimon Glass 			  struct pci_region *io)
3376a8b6a5SSimon Glass {
3476a8b6a5SSimon Glass 	u32 bar_response;
3576a8b6a5SSimon Glass 	pci_size_t bar_size;
3676a8b6a5SSimon Glass 	u16 cmdstat = 0;
3776a8b6a5SSimon Glass 	int bar, bar_nr = 0;
3876a8b6a5SSimon Glass #ifndef CONFIG_PCI_ENUM_ONLY
3976a8b6a5SSimon Glass 	u8 header_type;
4076a8b6a5SSimon Glass 	int rom_addr;
4176a8b6a5SSimon Glass 	pci_addr_t bar_value;
4276a8b6a5SSimon Glass 	struct pci_region *bar_res;
4376a8b6a5SSimon Glass 	int found_mem64 = 0;
4476a8b6a5SSimon Glass #endif
4576a8b6a5SSimon Glass 	u16 class;
4676a8b6a5SSimon Glass 
4776a8b6a5SSimon Glass 	pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat);
4876a8b6a5SSimon Glass 	cmdstat = (cmdstat & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)) | PCI_COMMAND_MASTER;
4976a8b6a5SSimon Glass 
5076a8b6a5SSimon Glass 	for (bar = PCI_BASE_ADDRESS_0;
5176a8b6a5SSimon Glass 		bar < PCI_BASE_ADDRESS_0 + (bars_num * 4); bar += 4) {
5276a8b6a5SSimon Glass 		/* Tickle the BAR and get the response */
5376a8b6a5SSimon Glass #ifndef CONFIG_PCI_ENUM_ONLY
5476a8b6a5SSimon Glass 		pci_hose_write_config_dword(hose, dev, bar, 0xffffffff);
5576a8b6a5SSimon Glass #endif
5676a8b6a5SSimon Glass 		pci_hose_read_config_dword(hose, dev, bar, &bar_response);
5776a8b6a5SSimon Glass 
5876a8b6a5SSimon Glass 		/* If BAR is not implemented go to the next BAR */
5976a8b6a5SSimon Glass 		if (!bar_response)
6076a8b6a5SSimon Glass 			continue;
6176a8b6a5SSimon Glass 
6276a8b6a5SSimon Glass #ifndef CONFIG_PCI_ENUM_ONLY
6376a8b6a5SSimon Glass 		found_mem64 = 0;
6476a8b6a5SSimon Glass #endif
6576a8b6a5SSimon Glass 
6676a8b6a5SSimon Glass 		/* Check the BAR type and set our address mask */
6776a8b6a5SSimon Glass 		if (bar_response & PCI_BASE_ADDRESS_SPACE) {
6876a8b6a5SSimon Glass 			bar_size = ((~(bar_response & PCI_BASE_ADDRESS_IO_MASK))
6976a8b6a5SSimon Glass 				   & 0xffff) + 1;
7076a8b6a5SSimon Glass #ifndef CONFIG_PCI_ENUM_ONLY
7176a8b6a5SSimon Glass 			bar_res = io;
7276a8b6a5SSimon Glass #endif
7376a8b6a5SSimon Glass 
7476a8b6a5SSimon Glass 			debug("PCI Autoconfig: BAR %d, I/O, size=0x%llx, ",
7576a8b6a5SSimon Glass 			      bar_nr, (unsigned long long)bar_size);
7676a8b6a5SSimon Glass 		} else {
7776a8b6a5SSimon Glass 			if ((bar_response & PCI_BASE_ADDRESS_MEM_TYPE_MASK) ==
7876a8b6a5SSimon Glass 			     PCI_BASE_ADDRESS_MEM_TYPE_64) {
7976a8b6a5SSimon Glass 				u32 bar_response_upper;
8076a8b6a5SSimon Glass 				u64 bar64;
8176a8b6a5SSimon Glass 
8276a8b6a5SSimon Glass #ifndef CONFIG_PCI_ENUM_ONLY
8376a8b6a5SSimon Glass 				pci_hose_write_config_dword(hose, dev, bar + 4,
8476a8b6a5SSimon Glass 					0xffffffff);
8576a8b6a5SSimon Glass #endif
8676a8b6a5SSimon Glass 				pci_hose_read_config_dword(hose, dev, bar + 4,
8776a8b6a5SSimon Glass 					&bar_response_upper);
8876a8b6a5SSimon Glass 
8976a8b6a5SSimon Glass 				bar64 = ((u64)bar_response_upper << 32) | bar_response;
9076a8b6a5SSimon Glass 
9176a8b6a5SSimon Glass 				bar_size = ~(bar64 & PCI_BASE_ADDRESS_MEM_MASK) + 1;
9276a8b6a5SSimon Glass #ifndef CONFIG_PCI_ENUM_ONLY
9376a8b6a5SSimon Glass 				found_mem64 = 1;
9476a8b6a5SSimon Glass #endif
9576a8b6a5SSimon Glass 			} else {
9676a8b6a5SSimon Glass 				bar_size = (u32)(~(bar_response & PCI_BASE_ADDRESS_MEM_MASK) + 1);
9776a8b6a5SSimon Glass 			}
9876a8b6a5SSimon Glass #ifndef CONFIG_PCI_ENUM_ONLY
9976a8b6a5SSimon Glass 			if (prefetch && (bar_response & PCI_BASE_ADDRESS_MEM_PREFETCH))
10076a8b6a5SSimon Glass 				bar_res = prefetch;
10176a8b6a5SSimon Glass 			else
10276a8b6a5SSimon Glass 				bar_res = mem;
10376a8b6a5SSimon Glass 
10476a8b6a5SSimon Glass 			debug("PCI Autoconfig: BAR %d, %s, size=0x%llx, ",
10576a8b6a5SSimon Glass 			      bar_nr, bar_res == prefetch ? "Prf" : "Mem",
10676a8b6a5SSimon Glass 			      (unsigned long long)bar_size);
10711131467SPhil Sutter #endif
10876a8b6a5SSimon Glass 		}
10976a8b6a5SSimon Glass 
11076a8b6a5SSimon Glass #ifndef CONFIG_PCI_ENUM_ONLY
111*d71975aeSTuomas Tynkkynen 		if (pciauto_region_allocate(bar_res, bar_size,
112*d71975aeSTuomas Tynkkynen 					    &bar_value, found_mem64) == 0) {
11376a8b6a5SSimon Glass 			/* Write it out and update our limit */
11476a8b6a5SSimon Glass 			pci_hose_write_config_dword(hose, dev, bar, (u32)bar_value);
11576a8b6a5SSimon Glass 
11676a8b6a5SSimon Glass 			if (found_mem64) {
11776a8b6a5SSimon Glass 				bar += 4;
11876a8b6a5SSimon Glass #ifdef CONFIG_SYS_PCI_64BIT
11976a8b6a5SSimon Glass 				pci_hose_write_config_dword(hose, dev, bar, (u32)(bar_value>>32));
12076a8b6a5SSimon Glass #else
12176a8b6a5SSimon Glass 				/*
12276a8b6a5SSimon Glass 				 * If we are a 64-bit decoder then increment to the
12376a8b6a5SSimon Glass 				 * upper 32 bits of the bar and force it to locate
12476a8b6a5SSimon Glass 				 * in the lower 4GB of memory.
12576a8b6a5SSimon Glass 				 */
12676a8b6a5SSimon Glass 				pci_hose_write_config_dword(hose, dev, bar, 0x00000000);
12776a8b6a5SSimon Glass #endif
12876a8b6a5SSimon Glass 			}
12976a8b6a5SSimon Glass 
13076a8b6a5SSimon Glass 		}
13176a8b6a5SSimon Glass #endif
13276a8b6a5SSimon Glass 		cmdstat |= (bar_response & PCI_BASE_ADDRESS_SPACE) ?
13376a8b6a5SSimon Glass 			PCI_COMMAND_IO : PCI_COMMAND_MEMORY;
13476a8b6a5SSimon Glass 
13576a8b6a5SSimon Glass 		debug("\n");
13676a8b6a5SSimon Glass 
13776a8b6a5SSimon Glass 		bar_nr++;
13876a8b6a5SSimon Glass 	}
13976a8b6a5SSimon Glass 
14076a8b6a5SSimon Glass #ifndef CONFIG_PCI_ENUM_ONLY
14176a8b6a5SSimon Glass 	/* Configure the expansion ROM address */
14276a8b6a5SSimon Glass 	pci_hose_read_config_byte(hose, dev, PCI_HEADER_TYPE, &header_type);
14376a8b6a5SSimon Glass 	header_type &= 0x7f;
14476a8b6a5SSimon Glass 	if (header_type != PCI_HEADER_TYPE_CARDBUS) {
14576a8b6a5SSimon Glass 		rom_addr = (header_type == PCI_HEADER_TYPE_NORMAL) ?
14676a8b6a5SSimon Glass 			   PCI_ROM_ADDRESS : PCI_ROM_ADDRESS1;
14776a8b6a5SSimon Glass 		pci_hose_write_config_dword(hose, dev, rom_addr, 0xfffffffe);
14876a8b6a5SSimon Glass 		pci_hose_read_config_dword(hose, dev, rom_addr, &bar_response);
14976a8b6a5SSimon Glass 		if (bar_response) {
15076a8b6a5SSimon Glass 			bar_size = -(bar_response & ~1);
15176a8b6a5SSimon Glass 			debug("PCI Autoconfig: ROM, size=%#x, ",
15276a8b6a5SSimon Glass 			      (unsigned int)bar_size);
15376a8b6a5SSimon Glass 			if (pciauto_region_allocate(mem, bar_size,
154*d71975aeSTuomas Tynkkynen 						    &bar_value, false) == 0) {
15576a8b6a5SSimon Glass 				pci_hose_write_config_dword(hose, dev, rom_addr,
15676a8b6a5SSimon Glass 							    bar_value);
15776a8b6a5SSimon Glass 			}
15876a8b6a5SSimon Glass 			cmdstat |= PCI_COMMAND_MEMORY;
15976a8b6a5SSimon Glass 			debug("\n");
16076a8b6a5SSimon Glass 		}
16176a8b6a5SSimon Glass 	}
16276a8b6a5SSimon Glass #endif
16376a8b6a5SSimon Glass 
16476a8b6a5SSimon Glass 	/* PCI_COMMAND_IO must be set for VGA device */
16576a8b6a5SSimon Glass 	pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
16676a8b6a5SSimon Glass 	if (class == PCI_CLASS_DISPLAY_VGA)
16776a8b6a5SSimon Glass 		cmdstat |= PCI_COMMAND_IO;
16876a8b6a5SSimon Glass 
16976a8b6a5SSimon Glass 	pci_hose_write_config_word(hose, dev, PCI_COMMAND, cmdstat);
17076a8b6a5SSimon Glass 	pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE,
17176a8b6a5SSimon Glass 		CONFIG_SYS_PCI_CACHE_LINE_SIZE);
17276a8b6a5SSimon Glass 	pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
17376a8b6a5SSimon Glass }
17476a8b6a5SSimon Glass 
pciauto_prescan_setup_bridge(struct pci_controller * hose,pci_dev_t dev,int sub_bus)17576a8b6a5SSimon Glass void pciauto_prescan_setup_bridge(struct pci_controller *hose,
17676a8b6a5SSimon Glass 					 pci_dev_t dev, int sub_bus)
17776a8b6a5SSimon Glass {
17876a8b6a5SSimon Glass 	struct pci_region *pci_mem;
17976a8b6a5SSimon Glass 	struct pci_region *pci_prefetch;
18076a8b6a5SSimon Glass 	struct pci_region *pci_io;
18176a8b6a5SSimon Glass 	u16 cmdstat, prefechable_64;
18276a8b6a5SSimon Glass 
18376a8b6a5SSimon Glass 	pci_mem = hose->pci_mem;
18476a8b6a5SSimon Glass 	pci_prefetch = hose->pci_prefetch;
18576a8b6a5SSimon Glass 	pci_io = hose->pci_io;
18676a8b6a5SSimon Glass 
18776a8b6a5SSimon Glass 	pci_hose_read_config_word(hose, dev, PCI_COMMAND, &cmdstat);
18876a8b6a5SSimon Glass 	pci_hose_read_config_word(hose, dev, PCI_PREF_MEMORY_BASE,
18976a8b6a5SSimon Glass 				&prefechable_64);
19076a8b6a5SSimon Glass 	prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK;
19176a8b6a5SSimon Glass 
19276a8b6a5SSimon Glass 	/* Configure bus number registers */
19376a8b6a5SSimon Glass 	pci_hose_write_config_byte(hose, dev, PCI_PRIMARY_BUS,
19476a8b6a5SSimon Glass 				   PCI_BUS(dev) - hose->first_busno);
19576a8b6a5SSimon Glass 	pci_hose_write_config_byte(hose, dev, PCI_SECONDARY_BUS,
19676a8b6a5SSimon Glass 				   sub_bus - hose->first_busno);
19776a8b6a5SSimon Glass 	pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS, 0xff);
19876a8b6a5SSimon Glass 
19976a8b6a5SSimon Glass 	if (pci_mem) {
20076a8b6a5SSimon Glass 		/* Round memory allocator to 1MB boundary */
20176a8b6a5SSimon Glass 		pciauto_region_align(pci_mem, 0x100000);
20276a8b6a5SSimon Glass 
20376a8b6a5SSimon Glass 		/* Set up memory and I/O filter limits, assume 32-bit I/O space */
20476a8b6a5SSimon Glass 		pci_hose_write_config_word(hose, dev, PCI_MEMORY_BASE,
20576a8b6a5SSimon Glass 					(pci_mem->bus_lower & 0xfff00000) >> 16);
20676a8b6a5SSimon Glass 
20776a8b6a5SSimon Glass 		cmdstat |= PCI_COMMAND_MEMORY;
20876a8b6a5SSimon Glass 	}
20976a8b6a5SSimon Glass 
21076a8b6a5SSimon Glass 	if (pci_prefetch) {
21176a8b6a5SSimon Glass 		/* Round memory allocator to 1MB boundary */
21276a8b6a5SSimon Glass 		pciauto_region_align(pci_prefetch, 0x100000);
21376a8b6a5SSimon Glass 
21476a8b6a5SSimon Glass 		/* Set up memory and I/O filter limits, assume 32-bit I/O space */
21576a8b6a5SSimon Glass 		pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE,
21676a8b6a5SSimon Glass 					(pci_prefetch->bus_lower & 0xfff00000) >> 16);
21776a8b6a5SSimon Glass 		if (prefechable_64 == PCI_PREF_RANGE_TYPE_64)
21876a8b6a5SSimon Glass #ifdef CONFIG_SYS_PCI_64BIT
21976a8b6a5SSimon Glass 			pci_hose_write_config_dword(hose, dev,
22076a8b6a5SSimon Glass 					PCI_PREF_BASE_UPPER32,
22176a8b6a5SSimon Glass 					pci_prefetch->bus_lower >> 32);
22276a8b6a5SSimon Glass #else
22376a8b6a5SSimon Glass 			pci_hose_write_config_dword(hose, dev,
22476a8b6a5SSimon Glass 					PCI_PREF_BASE_UPPER32,
22576a8b6a5SSimon Glass 					0x0);
22676a8b6a5SSimon Glass #endif
22776a8b6a5SSimon Glass 
22876a8b6a5SSimon Glass 		cmdstat |= PCI_COMMAND_MEMORY;
22976a8b6a5SSimon Glass 	} else {
23076a8b6a5SSimon Glass 		/* We don't support prefetchable memory for now, so disable */
23176a8b6a5SSimon Glass 		pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_BASE, 0x1000);
23276a8b6a5SSimon Glass 		pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT, 0x0);
23376a8b6a5SSimon Glass 		if (prefechable_64 == PCI_PREF_RANGE_TYPE_64) {
23476a8b6a5SSimon Glass 			pci_hose_write_config_word(hose, dev, PCI_PREF_BASE_UPPER32, 0x0);
23576a8b6a5SSimon Glass 			pci_hose_write_config_word(hose, dev, PCI_PREF_LIMIT_UPPER32, 0x0);
23676a8b6a5SSimon Glass 		}
23776a8b6a5SSimon Glass 	}
23876a8b6a5SSimon Glass 
23976a8b6a5SSimon Glass 	if (pci_io) {
24076a8b6a5SSimon Glass 		/* Round I/O allocator to 4KB boundary */
24176a8b6a5SSimon Glass 		pciauto_region_align(pci_io, 0x1000);
24276a8b6a5SSimon Glass 
24376a8b6a5SSimon Glass 		pci_hose_write_config_byte(hose, dev, PCI_IO_BASE,
24476a8b6a5SSimon Glass 					(pci_io->bus_lower & 0x0000f000) >> 8);
24576a8b6a5SSimon Glass 		pci_hose_write_config_word(hose, dev, PCI_IO_BASE_UPPER16,
24676a8b6a5SSimon Glass 					(pci_io->bus_lower & 0xffff0000) >> 16);
24776a8b6a5SSimon Glass 
24876a8b6a5SSimon Glass 		cmdstat |= PCI_COMMAND_IO;
24976a8b6a5SSimon Glass 	}
25076a8b6a5SSimon Glass 
25176a8b6a5SSimon Glass 	/* Enable memory and I/O accesses, enable bus master */
25276a8b6a5SSimon Glass 	pci_hose_write_config_word(hose, dev, PCI_COMMAND,
25376a8b6a5SSimon Glass 					cmdstat | PCI_COMMAND_MASTER);
25476a8b6a5SSimon Glass }
25576a8b6a5SSimon Glass 
pciauto_postscan_setup_bridge(struct pci_controller * hose,pci_dev_t dev,int sub_bus)25676a8b6a5SSimon Glass void pciauto_postscan_setup_bridge(struct pci_controller *hose,
25776a8b6a5SSimon Glass 					  pci_dev_t dev, int sub_bus)
25876a8b6a5SSimon Glass {
25976a8b6a5SSimon Glass 	struct pci_region *pci_mem;
26076a8b6a5SSimon Glass 	struct pci_region *pci_prefetch;
26176a8b6a5SSimon Glass 	struct pci_region *pci_io;
26276a8b6a5SSimon Glass 
26376a8b6a5SSimon Glass 	pci_mem = hose->pci_mem;
26476a8b6a5SSimon Glass 	pci_prefetch = hose->pci_prefetch;
26576a8b6a5SSimon Glass 	pci_io = hose->pci_io;
26676a8b6a5SSimon Glass 
26776a8b6a5SSimon Glass 	/* Configure bus number registers */
26876a8b6a5SSimon Glass 	pci_hose_write_config_byte(hose, dev, PCI_SUBORDINATE_BUS,
26976a8b6a5SSimon Glass 				   sub_bus - hose->first_busno);
27076a8b6a5SSimon Glass 
27176a8b6a5SSimon Glass 	if (pci_mem) {
27276a8b6a5SSimon Glass 		/* Round memory allocator to 1MB boundary */
27376a8b6a5SSimon Glass 		pciauto_region_align(pci_mem, 0x100000);
27476a8b6a5SSimon Glass 
27576a8b6a5SSimon Glass 		pci_hose_write_config_word(hose, dev, PCI_MEMORY_LIMIT,
27676a8b6a5SSimon Glass 				(pci_mem->bus_lower - 1) >> 16);
27776a8b6a5SSimon Glass 	}
27876a8b6a5SSimon Glass 
27976a8b6a5SSimon Glass 	if (pci_prefetch) {
28076a8b6a5SSimon Glass 		u16 prefechable_64;
28176a8b6a5SSimon Glass 
28276a8b6a5SSimon Glass 		pci_hose_read_config_word(hose, dev,
28376a8b6a5SSimon Glass 					PCI_PREF_MEMORY_LIMIT,
28476a8b6a5SSimon Glass 					&prefechable_64);
28576a8b6a5SSimon Glass 		prefechable_64 &= PCI_PREF_RANGE_TYPE_MASK;
28676a8b6a5SSimon Glass 
28776a8b6a5SSimon Glass 		/* Round memory allocator to 1MB boundary */
28876a8b6a5SSimon Glass 		pciauto_region_align(pci_prefetch, 0x100000);
28976a8b6a5SSimon Glass 
29076a8b6a5SSimon Glass 		pci_hose_write_config_word(hose, dev, PCI_PREF_MEMORY_LIMIT,
29176a8b6a5SSimon Glass 				(pci_prefetch->bus_lower - 1) >> 16);
29276a8b6a5SSimon Glass 		if (prefechable_64 == PCI_PREF_RANGE_TYPE_64)
29376a8b6a5SSimon Glass #ifdef CONFIG_SYS_PCI_64BIT
29476a8b6a5SSimon Glass 			pci_hose_write_config_dword(hose, dev,
29576a8b6a5SSimon Glass 					PCI_PREF_LIMIT_UPPER32,
29676a8b6a5SSimon Glass 					(pci_prefetch->bus_lower - 1) >> 32);
29776a8b6a5SSimon Glass #else
29876a8b6a5SSimon Glass 			pci_hose_write_config_dword(hose, dev,
29976a8b6a5SSimon Glass 					PCI_PREF_LIMIT_UPPER32,
30076a8b6a5SSimon Glass 					0x0);
30176a8b6a5SSimon Glass #endif
30276a8b6a5SSimon Glass 	}
30376a8b6a5SSimon Glass 
30476a8b6a5SSimon Glass 	if (pci_io) {
30576a8b6a5SSimon Glass 		/* Round I/O allocator to 4KB boundary */
30676a8b6a5SSimon Glass 		pciauto_region_align(pci_io, 0x1000);
30776a8b6a5SSimon Glass 
30876a8b6a5SSimon Glass 		pci_hose_write_config_byte(hose, dev, PCI_IO_LIMIT,
30976a8b6a5SSimon Glass 				((pci_io->bus_lower - 1) & 0x0000f000) >> 8);
31076a8b6a5SSimon Glass 		pci_hose_write_config_word(hose, dev, PCI_IO_LIMIT_UPPER16,
31176a8b6a5SSimon Glass 				((pci_io->bus_lower - 1) & 0xffff0000) >> 16);
31276a8b6a5SSimon Glass 	}
31376a8b6a5SSimon Glass }
31476a8b6a5SSimon Glass 
31576a8b6a5SSimon Glass 
31676a8b6a5SSimon Glass /*
31776a8b6a5SSimon Glass  * HJF: Changed this to return int. I think this is required
31876a8b6a5SSimon Glass  * to get the correct result when scanning bridges
31976a8b6a5SSimon Glass  */
pciauto_config_device(struct pci_controller * hose,pci_dev_t dev)32076a8b6a5SSimon Glass int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
32176a8b6a5SSimon Glass {
32276a8b6a5SSimon Glass 	struct pci_region *pci_mem;
32376a8b6a5SSimon Glass 	struct pci_region *pci_prefetch;
32476a8b6a5SSimon Glass 	struct pci_region *pci_io;
32576a8b6a5SSimon Glass 	unsigned int sub_bus = PCI_BUS(dev);
32676a8b6a5SSimon Glass 	unsigned short class;
32776a8b6a5SSimon Glass 	int n;
32876a8b6a5SSimon Glass 
32976a8b6a5SSimon Glass 	pci_mem = hose->pci_mem;
33076a8b6a5SSimon Glass 	pci_prefetch = hose->pci_prefetch;
33176a8b6a5SSimon Glass 	pci_io = hose->pci_io;
33276a8b6a5SSimon Glass 
33376a8b6a5SSimon Glass 	pci_hose_read_config_word(hose, dev, PCI_CLASS_DEVICE, &class);
33476a8b6a5SSimon Glass 
33576a8b6a5SSimon Glass 	switch (class) {
33676a8b6a5SSimon Glass 	case PCI_CLASS_BRIDGE_PCI:
33776a8b6a5SSimon Glass 		debug("PCI Autoconfig: Found P2P bridge, device %d\n",
33876a8b6a5SSimon Glass 		      PCI_DEV(dev));
33976a8b6a5SSimon Glass 
34076a8b6a5SSimon Glass 		pciauto_setup_device(hose, dev, 2, pci_mem,
34176a8b6a5SSimon Glass 				     pci_prefetch, pci_io);
34276a8b6a5SSimon Glass 
34376a8b6a5SSimon Glass 		/* Passing in current_busno allows for sibling P2P bridges */
34476a8b6a5SSimon Glass 		hose->current_busno++;
34576a8b6a5SSimon Glass 		pciauto_prescan_setup_bridge(hose, dev, hose->current_busno);
34676a8b6a5SSimon Glass 		/*
34776a8b6a5SSimon Glass 		 * need to figure out if this is a subordinate bridge on the bus
34876a8b6a5SSimon Glass 		 * to be able to properly set the pri/sec/sub bridge registers.
34976a8b6a5SSimon Glass 		 */
35076a8b6a5SSimon Glass 		n = pci_hose_scan_bus(hose, hose->current_busno);
35176a8b6a5SSimon Glass 
35276a8b6a5SSimon Glass 		/* figure out the deepest we've gone for this leg */
35376a8b6a5SSimon Glass 		sub_bus = max((unsigned int)n, sub_bus);
35476a8b6a5SSimon Glass 		pciauto_postscan_setup_bridge(hose, dev, sub_bus);
35576a8b6a5SSimon Glass 
35676a8b6a5SSimon Glass 		sub_bus = hose->current_busno;
35776a8b6a5SSimon Glass 		break;
35876a8b6a5SSimon Glass 
35976a8b6a5SSimon Glass 	case PCI_CLASS_BRIDGE_CARDBUS:
36076a8b6a5SSimon Glass 		/*
36176a8b6a5SSimon Glass 		 * just do a minimal setup of the bridge,
36276a8b6a5SSimon Glass 		 * let the OS take care of the rest
36376a8b6a5SSimon Glass 		 */
36476a8b6a5SSimon Glass 		pciauto_setup_device(hose, dev, 0, pci_mem,
36576a8b6a5SSimon Glass 				     pci_prefetch, pci_io);
36676a8b6a5SSimon Glass 
36776a8b6a5SSimon Glass 		debug("PCI Autoconfig: Found P2CardBus bridge, device %d\n",
36876a8b6a5SSimon Glass 		      PCI_DEV(dev));
36976a8b6a5SSimon Glass 
37076a8b6a5SSimon Glass 		hose->current_busno++;
37176a8b6a5SSimon Glass 		break;
37276a8b6a5SSimon Glass 
37376a8b6a5SSimon Glass #if defined(CONFIG_PCIAUTO_SKIP_HOST_BRIDGE)
37476a8b6a5SSimon Glass 	case PCI_CLASS_BRIDGE_OTHER:
37576a8b6a5SSimon Glass 		debug("PCI Autoconfig: Skipping bridge device %d\n",
37676a8b6a5SSimon Glass 		      PCI_DEV(dev));
37776a8b6a5SSimon Glass 		break;
37876a8b6a5SSimon Glass #endif
37976a8b6a5SSimon Glass #if defined(CONFIG_MPC834x) && !defined(CONFIG_VME8349)
38076a8b6a5SSimon Glass 	case PCI_CLASS_BRIDGE_OTHER:
38176a8b6a5SSimon Glass 		/*
38276a8b6a5SSimon Glass 		 * The host/PCI bridge 1 seems broken in 8349 - it presents
38376a8b6a5SSimon Glass 		 * itself as 'PCI_CLASS_BRIDGE_OTHER' and appears as an _agent_
38476a8b6a5SSimon Glass 		 * device claiming resources io/mem/irq.. we only allow for
38576a8b6a5SSimon Glass 		 * the PIMMR window to be allocated (BAR0 - 1MB size)
38676a8b6a5SSimon Glass 		 */
38776a8b6a5SSimon Glass 		debug("PCI Autoconfig: Broken bridge found, only minimal config\n");
38876a8b6a5SSimon Glass 		pciauto_setup_device(hose, dev, 0, hose->pci_mem,
38976a8b6a5SSimon Glass 			hose->pci_prefetch, hose->pci_io);
39076a8b6a5SSimon Glass 		break;
39176a8b6a5SSimon Glass #endif
39276a8b6a5SSimon Glass 
39376a8b6a5SSimon Glass 	case PCI_CLASS_PROCESSOR_POWERPC: /* an agent or end-point */
39476a8b6a5SSimon Glass 		debug("PCI AutoConfig: Found PowerPC device\n");
39576a8b6a5SSimon Glass 
39676a8b6a5SSimon Glass 	default:
39776a8b6a5SSimon Glass 		pciauto_setup_device(hose, dev, 6, pci_mem,
39876a8b6a5SSimon Glass 				     pci_prefetch, pci_io);
39976a8b6a5SSimon Glass 		break;
40076a8b6a5SSimon Glass 	}
40176a8b6a5SSimon Glass 
40276a8b6a5SSimon Glass 	return sub_bus;
40376a8b6a5SSimon Glass }
404