/* * (C) Copyright 2000 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * */ /******************************************************************************* Copyright (C) Marvell International Ltd. and its affiliates ******************************************************************************** Marvell GPL License Option If you received this File from Marvell, you may opt to use, redistribute and/or modify this File in accordance with the terms and conditions of the General Public License Version 2, June 1991 (the "GPL License"), a copy of which is available along with the File in the license.txt file or by writing to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 or on the worldwide web at http://www.gnu.org/licenses/gpl.txt. THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY DISCLAIMED. The GPL License provides additional details about this warranty disclaimer. *******************************************************************************/ /* PCI.c - PCI functions */ #include #include #include #if (CONFIG_COMMANDS & CFG_CMD_PCI) #include #include "pci-if/mvPciIf.h" #include "mvCpuIf.h" #include "pci-if/pci_util/mvPciUtils.h" #ifdef DEBUG #define DB(x) x #else #define DB(x) #endif /* DEBUG */ /* global definetion */ #define REG_NUM_MASK (0x3F << 2) /* global indicate wether we are in the scan process */ unsigned int bus_scan = 0; #if CONFIG_COMMANDS & CFG_CMD_BSP /****************************************************************************** * Category - PCI0 * Functionality- Scans PCI0 for devices and prints relevant information * Need modifications (Yes/No) - No *****************************************************************************/ MV_BOOL scanPci(MV_U32 host) { MV_U32 index,numOfElements=4*8,barIndex; MV_PCI_DEVICE pciDevices[4*8]; //3 slots and us,Max 8 functions per slot memset (&pciDevices,0,12*sizeof(MV_PCI_DEVICE)); if (mvPciScan(host, pciDevices , &numOfElements) != MV_OK ) { printf("scanPci:mvPciScan failed for host %d \n",host); return MV_FALSE; } for(index = 0; index < numOfElements ; index++) { printf("\nBus: %x Device: %x Func: %x Vendor ID: %x Device ID: %x\n", pciDevices[index].busNumber, pciDevices[index].deviceNum, pciDevices[index].function, pciDevices[index].venID, pciDevices[index].deviceID); printf("-------------------------------------------------------------------\n"); printf("Class: %s\n",pciDevices[index].type); /* check if we are bridge*/ if ((pciDevices[index].baseClassCode == PCI_BRIDGE_CLASS)&& (pciDevices[index].subClassCode == P2P_BRIDGE_SUB_CLASS_CODE)) { printf("Primary Bus:0x%x \tSecondary Bus:0x%x \tSubordinate Bus:0x%x\n", pciDevices[index].p2pPrimBusNum, pciDevices[index].p2pSecBusNum, pciDevices[index].p2pSubBusNum); printf("IO Base:0x%x \t\tIO Limit:0x%x",pciDevices[index].p2pIObase, pciDevices[index].p2pIOLimit); (pciDevices[index].bIO32)? (printf(" (32Bit IO)\n")): (printf(" (16Bit IO)\n")); printf("Memory Base:0x%x \tMemory Limit:0x%x\n",pciDevices[index].p2pMemBase, pciDevices[index].p2pMemLimit); printf("Pref Memory Base:0x%x \tPref Memory Limit:0x%x", pciDevices[index].p2pPrefMemBase, pciDevices[index].p2pPrefMemLimit); (pciDevices[index].bPrefMem64)? (printf(" (64Bit PrefMem)\n")): (printf(" (32Bit PrefMem)\n")); if (pciDevices[index].bPrefMem64) { printf("Pref Base Upper 32bit:0x%x \tPref Limit Base Upper32 bit:0x%x\n", pciDevices[index].p2pPrefBaseUpper32Bits, pciDevices[index].p2pPrefLimitUpper32Bits); } } for (barIndex = 0 ; barIndex < pciDevices[index].barsNum ; barIndex++) { if (pciDevices[index].pciBar[barIndex].barType == PCI_64BIT_BAR) { printf("PCI_BAR%d (%s-%s) base: %x%08x%s",barIndex, (pciDevices[index].pciBar[barIndex].barMapping == PCI_MEMORY_BAR)?"Mem":"I/O", "64bit", pciDevices[index].pciBar[barIndex].barBaseHigh, pciDevices[index].pciBar[barIndex].barBaseLow, (pciDevices[index].pciBar[barIndex].barBaseLow == 0)?"\t\t":"\t"); } else if (pciDevices[index].pciBar[barIndex].barType == PCI_32BIT_BAR) { printf("PCI_BAR%d (%s-%s) base: %x%s",barIndex, (pciDevices[index].pciBar[barIndex].barMapping == PCI_MEMORY_BAR)?"Mem":"I/O", "32bit", pciDevices[index].pciBar[barIndex].barBaseLow, (pciDevices[index].pciBar[barIndex].barBaseLow == 0)?"\t\t\t":"\t\t"); } if(pciDevices[index].pciBar[barIndex].barSizeHigh != 0) printf("size: %d%08d bytes\n",pciDevices[index].pciBar[barIndex].barSizeHigh, pciDevices[index].pciBar[barIndex].barSizeLow); else printf("size: %d bytes\n", pciDevices[index].pciBar[barIndex].barSizeLow); } } return MV_TRUE; } int sp_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { MV_U32 host = 0; if (argc > 1) { host = simple_strtoul (argv[1], NULL, 10); } if(host >= mvCtrlPciIfMaxIfGet()){ printf("PCI %d doesn't exist\n",host); return 1; } if( scanPci(host) == MV_FALSE) printf("PCI %d Scan - FAILED!!.\n",host); return 1; } U_BOOT_CMD( sp, 2, 1, sp_cmd, "sp - Scan PCI bus.\n", " [0/1] \n" "\tScan and detecect all devices on mvPCI bus 0/1 \n" "\t(This command can be used only if enaMonExt is set!)\n" ); int me_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { MV_U32 host = 0; if (argc > 1) { host = simple_strtoul (argv[1], NULL, 10); } if(host >= mvCtrlPciIfMaxIfGet()) { printf("Master %d doesn't exist\n",host); return 1; } if(mvPciIfMasterEnable(host,MV_TRUE) == MV_OK) printf("PCI %d Master enabled.\n",host); else printf("PCI %d Master enabled -FAILED!!\n",host); return 1; } U_BOOT_CMD( me, 2, 1, me_cmd, "me - PCI master enable\n", " [0/1] \n" "\tEnable the MV device as Master on PCI 0/1. \n" ); int se_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { MV_U32 host=0,dev = 0,bus=0; if(argc != 4) { printf ("Usage:\n%s\n", cmdtp->usage); return 1; } host = simple_strtoul (argv[1], NULL, 10); bus = simple_strtoul (argv[2], NULL, 16); dev = simple_strtoul (argv[3], NULL, 16); if(host >= mvCtrlPciIfMaxIfGet()) { printf("PCI %d doesn't exist\n",host); return 1; } if(mvPciIfSlaveEnable(host,bus,dev,MV_TRUE) == MV_OK ) printf("PCI %d Bus %d Slave 0x%x enabled.\n",host,bus,dev); else printf("PCI %d Bus %d Slave 0x%x enabled - FAILED!!.\n",host,bus,dev); return 1; } U_BOOT_CMD( se, 4, 1, se_cmd, "se - PCI Slave enable\n", " [0/1] bus dev \n" "\tEnable the PCI device as Slave on PCI 0/1. \n" ); /****************************************************************************** * Functionality- The commands changes the pci remap register and displays the * address to be used in order to access PCI 0. *****************************************************************************/ int mapPci_cmd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { MV_ADDR_WIN pciWin; MV_TARGET target=0; MV_U32 host=0,effectiveBaseAddress=0; pciWin.baseLow=0; pciWin.baseHigh=0; if (argc > 1) { host = simple_strtoul(argv[1], NULL, 10); } if(argc > 2) { pciWin.baseLow = simple_strtoul(argv[2], NULL, 16); } if(host >= mvCtrlPciIfMaxIfGet()){ printf("PCI %d doesn't exist\n",host); return 1; } target = PCI0_MEM0 + (2 * host); printf("mapping pci %x to address 0x%x\n",host,pciWin.baseLow); #if defined(MV_INCLUDE_PEX) || defined(MV_INCLUDE_PCI) effectiveBaseAddress = mvCpuIfPciIfRemap(target,&pciWin); #endif if ( effectiveBaseAddress == 0xffffffff) { printf("Error remapping\n"); return 1; } printf("PCI %x Access base address : %x\n",host,effectiveBaseAddress); return 1; } U_BOOT_CMD( mp, 3, 1, mapPci_cmd, "mp - map PCI BAR\n", " [0/1] address \n" "\tChange the remap of PCI 0/1 window 0 to address 'addrress'.\n" "\tIt also displays the new access address, since the remap is not always\n" "\tthe same as requested. \n" ); #endif MV_U32 mv_mem_ctrl_dev(MV_U32 pciIf, MV_U32 bus,MV_U32 dev) { MV_U32 ven, class; ven = mvPciIfConfigRead(pciIf,bus,dev,0,PCI_VENDOR_ID) & 0xffff; class = (mvPciIfConfigRead(pciIf,bus,dev,0,PCI_REVISION_ID) >> 16 ) & 0xffff; /* if we got any other Marvell PCI cards ignore it. */ if(((ven == 0x11ab) && (class == PCI_CLASS_MEMORY_OTHER))|| ((ven == 0x11ab) && (class == PCI_CLASS_BRIDGE_HOST))) { return 1; } return 0; } static int mv_read_config_dword(struct pci_controller *hose, pci_dev_t dev, int offset, u32* value) { MV_U32 bus,func,regOff,dev_no; char *env; bus = PCI_BUS(dev); dev_no = PCI_DEV(dev); func = (MV_U32)PCI_FUNC(dev); regOff = (MV_U32)offset & REG_NUM_MASK; /* We will scan only ourselves and the PCI slots that exist on the board, because we may have a case that we have one slot that has a Cardbus connector, and because CardBus answers all IDsels we want to scan only this slot and ourseleves. */ #if defined(MV_INCLUDE_PCI) env = getenv("pciMode"); if ((PCI_IF_TYPE_CONVEN_PCIX == mvPciIfTypeGet((MV_U32)hose->cfg_addr)) && ((strcmp(env,"host") == 0) || (strcmp(env,"Host") == 0))) { if ( !mvBoardIsOurPciSlot(bus, dev_no) && (mvBoardIdGet() != DB_88F5181_DDR1_MNG) && (DB_88F5181_DDR1_PRPMC != mvBoardIdGet()) && (DB_88F5181_DDR1_PEXPCI != mvBoardIdGet())) { *value = 0xffffffff; return 0; } } #endif /* defined(MV_INCLUDE_PCI) */ if( bus_scan == 1 ) { env = getenv("disaMvPnp"); if(env && ( (strcmp(env,"yes") == 0) || (strcmp(env,"Yes") == 0) ) ) { if( mv_mem_ctrl_dev((MV_U32)hose->cfg_addr, bus, dev_no) ) { *value = 0xffffffff; return 0; } } } DB(printf("mv_read_config_dword hose->cfg_addr %x\n",hose->cfg_addr);) DB(printf("mv_read_config_dword bus %x\n",bus);) DB(printf("mv_read_config_dword dev_no %x\n",dev_no);) DB(printf("mv_read_config_dword func %x\n",func);) DB(printf("mv_read_config_dword regOff %x\n",regOff);) *value = (u32) mvPciIfConfigRead((MV_U32)hose->cfg_addr,bus,dev_no,func,regOff); DB(printf("mv_read_config_dword value %x\n",*value);) return 0; } static int mv_write_config_dword(struct pci_controller *hose, pci_dev_t dev, int offset, u32 value) { MV_U32 bus,func,regOff,dev_no; bus = PCI_BUS(dev); dev_no = PCI_DEV(dev); func = (MV_U32)PCI_FUNC(dev); regOff = offset & REG_NUM_MASK; mvPciIfConfigWrite((MV_U32)hose->cfg_addr,bus,dev_no,func,regOff,value); return 0; } static void mv_setup_ide(struct pci_controller *hose, pci_dev_t dev, struct pci_config_table *entry) { static const int ide_bar[]={8,4,8,4,16,1024}; u32 bar_response, bar_value; int bar; for (bar=0; bar<6; bar++) { /*ronen different function for 3rd bank.*/ unsigned int offset = (bar < 2)? bar*8: 0x100 + (bar-2)*8; pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + offset, 0x0); pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + offset, &bar_response); pciauto_region_allocate(bar_response & PCI_BASE_ADDRESS_SPACE_IO ? hose->pci_io : hose->pci_mem, ide_bar[bar], &bar_value); pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + bar*4, bar_value); } } static void mv_setup_host(struct pci_controller *hose, pci_dev_t dev, struct pci_config_table *entry) { //skip our host DB(printf("skipping :bus=%x dev=%x fun=%x\n", (unsigned int)PCI_BUS(dev), (unsigned int)PCI_DEV(dev), (unsigned int)PCI_FUNC(dev))); return; } static void mv_pci_bus_mode_display(MV_U32 host) { if (PCI_IF_TYPE_PEX == mvPciIfTypeGet(host)) { #if defined(MV_INCLUDE_PEX) MV_PEX_MODE pexMode; if (mvPexModeGet(mvPciRealIfNumGet(host),&pexMode) != MV_OK) { printf("mv_pci_bus_mode_display: mvPexModeGet failed\n"); } switch (pexMode.pexType) { case MV_PEX_ROOT_COMPLEX: printf("PCI %d: PCI Express Root Complex Interface\n",host); break; case MV_PEX_END_POINT: printf("PCI %d: PCI Express End Point Interface\n",host); break; } if (!(pexMode.pexLinkUp)) { printf("PEX interface detected no Link.\n"); } else { if (MV_PEX_WITDH_X1 == pexMode.pexWidth) { printf("PEX interface detected Link X1\n"); } else { printf("PEX interface detected Link X4\n"); } } return ; #endif /* MV_INCLUDE_PEX */ } if (PCI_IF_TYPE_CONVEN_PCIX == mvPciIfTypeGet(host)) { #if defined(MV_INCLUDE_PCI) MV_PCI_MODE pciMode; if (mvPciModeGet(mvPciRealIfNumGet(host),&pciMode) != MV_OK) { printf("mv_pci_bus_mode_display: mvPciIfModeGet failed\n"); } switch (pciMode.pciType) { case MV_PCI_CONV: printf("PCI %d: Conventional PCI",host); break; case MV_PCIX: printf("PCI %d: PCI-X",host); break; default: printf("PCI %d: Unknown",host); return; break; } printf(", speed = %d\n",pciMode.pciSpeed); #endif /* #if defined(MV_INCLUDE_PCI) */ } } struct pci_config_table mv_config_table[] = { { PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, mv_setup_ide}, { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, mv_setup_host}, //PCI host {} }; /* Defines for more modularity of the pci_init_board function */ struct pci_controller pci_hose[8]; #if (MV_PCI_IF_MAX_IF == 2) #define PCI_IF_MEM(pciIf) ((pciIf==0)?PCI_IF0_MEM0:PCI_IF1_MEM0) #define PCI_IF_REMAPED_MEM_BASE(pciIf) ((pciIf==0)?PCI_IF0_REMAPED_MEM_BASE:PCI_IF1_REMAPED_MEM_BASE) #define PCI_IF_MEM_BASE(pciIf) ((pciIf==0)?PCI_IF0_MEM0_BASE:PCI_IF1_MEM0_BASE) #define PCI_IF_MEM_SIZE(pciIf) ((pciIf==0)?PCI_IF0_MEM0_SIZE:PCI_IF1_MEM0_SIZE) #define PCI_IF_IO_BASE(pciIf) ((pciIf==0)?PCI_IF0_IO_BASE:PCI_IF1_IO_BASE) #define PCI_IF_IO_SIZE(pciIf) ((pciIf==0)?PCI_IF0_IO_SIZE:PCI_IF1_IO_SIZE) #else #define PCI_IF_MEM(pciIf) (PCI_IF0_MEM0) #define PCI_IF_REMAPED_MEM_BASE(pciIf) (PCI_IF0_REMAPED_MEM_BASE) #define PCI_IF_MEM_BASE(pciIf) (PCI_IF0_MEM0_BASE) #define PCI_IF_MEM_SIZE(pciIf) (PCI_IF0_MEM0_SIZE) #define PCI_IF_IO_BASE(pciIf) (PCI_IF0_IO_BASE) #define PCI_IF_IO_SIZE(pciIf) (PCI_IF0_IO_SIZE) #endif /* because of CIV tem needs we are gonna do a remap to PCI memory */ #define PCI_IF0_REMAPED_MEM_BASE 0x40000000 #define PCI_IF1_REMAPED_MEM_BASE 0x40000000 void pci_init_board(void) { MV_U32 pciIfNum = mvCtrlPciIfMaxIfGet(); MV_U32 pciIf=0; MV_U32 regVal=0; MV_ADDR_WIN rempWin; char *env; int first_busno=0; int status; MV_CPU_DEC_WIN cpuAddrDecWin; PCI_IF_MODE pciIfMode = PCI_IF_MODE_HOST; env = getenv("disaMvPnp"); if(env && ( (strcmp(env,"yes") == 0) || (strcmp(env,"Yes") == 0) ) ) printf("Warning: skip configuration of Marvell devices!!!\n"); #if defined(MV_INCLUDE_PEX) && defined(MV78XX0) /* Power down the none lanes 0.1, 0.2, and 0.3 if PEX0 is X4 */ if ( !(PCI0_IS_QUAD_X1) ) { for (pciIf = 1; pciIf < 4; pciIf++) mvCtrlPwrClckSet(PEX_UNIT_ID, mvPciRealIfNumGet(pciIf),MV_FALSE); } /* Power down the none lanes 1.1, 1.2, and 1.3 if PEX1 is X4 */ if ( !(PCI1_IS_QUAD_X1) ) { for (pciIf = 5; pciIf < 8; pciIf++) mvCtrlPwrClckSet(PEX_UNIT_ID, mvPciRealIfNumGet(pciIf),MV_FALSE); } #endif for (pciIf = 0; pciIf < pciIfNum; pciIf++) { pci_hose[pciIf].config_table = mv_config_table; if (PCI_IF_TYPE_PEX == mvPciIfTypeGet(pciIf)) { if (MV_FALSE == mvCtrlPwrClckGet(PEX_UNIT_ID, mvPciRealIfNumGet(pciIf))) { continue; } } #if defined(MV_INCLUDE_PCI) else { if (MV_FALSE == mvCtrlPwrClckGet(PCI_UNIT_ID, mvPciRealIfNumGet(pciIf))) { continue; } } #endif /* device or host ? */ if (PCI_IF_TYPE_PEX == mvPciIfTypeGet(pciIf)) { #if defined(MV_INCLUDE_PEX) #if !defined(MV_88F6183) && !defined(MV_88F6183L) && !defined(MV_88F6082) && !defined(MV88F6281) && \ !defined(MV88F6192) && !defined(MV88F6180) && !defined(MV88F6190) MV_PEX_MODE pexMode; if (mvPexModeGet(mvPciRealIfNumGet(pciIf),&pexMode) != MV_OK) { printf("pci_init_board: mvPexModeGet failed\n"); } if (MV_PEX_ROOT_COMPLEX == pexMode.pexType) pciIfMode = PCI_IF_MODE_HOST; else pciIfMode = PCI_IF_MODE_DEVICE; #else /* Set pex mode incase S@R not exist */ env = getenv("pexMode"); if( env && ( ((strcmp(env,"EP") == 0) || (strcmp(env,"ep") == 0) ))) { pciIfMode = PCI_IF_MODE_DEVICE; } else { pciIfMode = PCI_IF_MODE_HOST; } #endif #endif } else /* PCI */ { #if defined(MV_INCLUDE_PCI) char *env; env = getenv("pciMode"); if((!env) || (strcmp(env,"host") == 0) || (strcmp(env,"Host") == 0) ) { pciIfMode = PCI_IF_MODE_HOST; } else { pciIfMode = PCI_IF_MODE_DEVICE; } #endif } if ((status = mvPciIfInit(pciIf, pciIfMode)) == MV_ERROR) { printf("pci_init_board:Error calling mvPciIfInit for pciIf %d\n",pciIf); } else { if (status == MV_OK) mv_pci_bus_mode_display(pciIf); else { /* Interface with no link */ printf("PEX %d: interface detected no Link.\n", pciIf); return; } } if (PCI_IF_TYPE_CONVEN_PCIX == mvPciIfTypeGet(pciIf)) { #if defined(MV_INCLUDE_PCI) if(enaMonExt()) { /* WA for first PCI interface */ /* mvPciWaFix(mvPciRealIfNumGet(pciIf)); */ } #endif /* MV_INCLUDE_PCI */ if (pciIfMode == PCI_IF_MODE_DEVICE) { mvPciIfLocalDevNumSet(pciIf, 0x1f); } } #if defined(DB_PRPMC) mvPciIfLocalDevNumSet(pciIf, 0x1f); #endif /* start Uboot PCI scan */ if (pciIf == 0) pci_hose[pciIf].first_busno = 0; else pci_hose[pciIf].first_busno = pci_hose[pciIf-1].last_busno + 1; /* start Uboot PCI scan */ pci_hose[pciIf].current_busno = pci_hose[pciIf].first_busno; pci_hose[pciIf].last_busno = 0xff; if (mvPciIfLocalBusNumSet(pciIf,pci_hose[pciIf].first_busno) != MV_OK) { printf("pci_init_board:Error calling mvPciIfLocalBusNumSet for pciIf %d\n",pciIf); } /* If no link on the interface it will not be scan */ if (status == MV_NO_SUCH) { pci_hose[pciIf].last_busno =pci_hose[pciIf].first_busno; continue; } #ifdef PCI_DIS_INTERFACE /* The disable interface will not be scan */ if (pciIf == PCI_DIS_INTERFACE) { printf("***Interface is disable***\n"); pci_hose[pciIf].last_busno =pci_hose[pciIf].first_busno; continue; } #endif if (MV_OK != mvCpuIfTargetWinGet(PCI_MEM(pciIf, 0), &cpuAddrDecWin)) { mvOsPrintf("%s: ERR. mvCpuIfTargetWinGet failed\n", __FUNCTION__); return ; } rempWin.baseLow = ((cpuAddrDecWin.addrWin.baseLow & 0x0fffffff) | PCI_IF_REMAPED_MEM_BASE(pciIf)); rempWin.baseHigh = 0; /* perform a remap for the PEX0 interface*/ if (0xffffffff == mvCpuIfPciIfRemap(PCI_MEM(pciIf, 0),&rempWin)) { printf("%s:mvCpuIfPciIfRemap failed\n",__FUNCTION__); return; } /* PCI memory space */ pci_set_region(pci_hose[pciIf].regions + 0, rempWin.baseLow, /* bus address */ cpuAddrDecWin.addrWin.baseLow, cpuAddrDecWin.addrWin.size, PCI_REGION_MEM); if (MV_OK != mvCpuIfTargetWinGet(PCI_IO(pciIf), &cpuAddrDecWin)) { /* No I/O space */ pci_hose[pciIf].region_count = 1; } else { /* PCI I/O space */ pci_set_region(pci_hose[pciIf].regions + 1, cpuAddrDecWin.addrWin.baseLow, cpuAddrDecWin.addrWin.baseLow, cpuAddrDecWin.addrWin.size, PCI_REGION_IO); pci_hose[pciIf].region_count = 2; } pci_set_ops(&pci_hose[pciIf], pci_hose_read_config_byte_via_dword, pci_hose_read_config_word_via_dword, mv_read_config_dword, pci_hose_write_config_byte_via_dword, pci_hose_write_config_word_via_dword, mv_write_config_dword); pci_hose[pciIf].cfg_addr = (unsigned int*) pciIf; pci_hose[pciIf].config_table[1].bus = mvPciIfLocalBusNumGet(pciIf); pci_hose[pciIf].config_table[1].dev = mvPciIfLocalDevNumGet(pciIf); pci_register_hose(&pci_hose[pciIf]); if (pciIfMode == PCI_IF_MODE_HOST) { MV_U32 pciData=0,baseClassCode=0,subClassCode; bus_scan = 1; pci_hose[pciIf].last_busno = pci_hose_scan(&pci_hose[pciIf]); bus_scan = 0; pciData = mvPciIfConfigRead(pciIf,pci_hose[pciIf].first_busno,1,0, PCI_CLASS_CODE_AND_REVISION_ID); baseClassCode = (pciData & PCCRIR_BASE_CLASS_MASK) >> PCCRIR_BASE_CLASS_OFFS; subClassCode = (pciData & PCCRIR_SUB_CLASS_MASK) >> PCCRIR_SUB_CLASS_OFFS; if ((baseClassCode == PCI_BRIDGE_CLASS) && (subClassCode == P2P_BRIDGE_SUB_CLASS_CODE)) { /* In rthe bridge : We want to open its memory and IO to the maximum ! after the u-boot Scan */ /* first the IO */ pciData = mvPciIfConfigRead(pciIf,pci_hose[pciIf].first_busno,1,0,P2P_IO_BASE_LIMIT_SEC_STATUS); /* keep the secondary status */ pciData &= PIBLSS_SEC_STATUS_MASK; /* set to the maximum - 0 - 0xffff */ pciData |= 0xff00; mvPciIfConfigWrite(pciIf,pci_hose[pciIf].first_busno,1,0,P2P_IO_BASE_LIMIT_SEC_STATUS,pciData); /* the the Memory */ pciData = mvPciIfConfigRead(pciIf,pci_hose[pciIf].first_busno,1,0,P2P_MEM_BASE_LIMIT); /* set to the maximum - PCI_IF_REMAPED_MEM_BASE(pciIf) - 0xf000000 */ pciData = 0xEFF00000 | (PCI_IF_REMAPED_MEM_BASE(pciIf) >> 16); mvPciIfConfigWrite(pciIf,pci_hose[pciIf].first_busno,1,0,P2P_MEM_BASE_LIMIT,pciData); } } else /* PCI_IF_MODE_HOST */ { pci_hose[pciIf].last_busno = pci_hose[pciIf].first_busno; } first_busno = pci_hose[pciIf].last_busno + 1; } #ifdef DB_FPGA MV_REG_BIT_RESET(PCI_BASE_ADDR_ENABLE_REG(0), BIT10); #endif } #endif /* CONFIG_PCI */