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 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 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 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 */ 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