X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=cpu%2Fmpc85xx%2Fpci.c;h=3c1a323aad2f625c6fa8f5b853de808de5e49953;hb=f3679aa13d9f483adb38245a87ecd5c84f57a5d3;hp=5732c29eb68be91377315d3129e748c3b4bfafbe;hpb=42d1f0394bef0624fc9664714d54bb137931d6a6;p=oweals%2Fu-boot.git diff --git a/cpu/mpc85xx/pci.c b/cpu/mpc85xx/pci.c index 5732c29eb6..3c1a323aad 100644 --- a/cpu/mpc85xx/pci.c +++ b/cpu/mpc85xx/pci.c @@ -1,4 +1,5 @@ /* + * Copyright 2004 Freescale Semiconductor. * Copyright (C) 2003 Motorola Inc. * Xianghua Xiao (x.xiao@motorola.com) * @@ -28,80 +29,214 @@ #include #include +#if defined(CONFIG_OF_FLAT_TREE) +#include +#endif + #if defined(CONFIG_PCI) -/* - * Initialize PCI Devices, report devices found. - */ -#ifndef CONFIG_PCI_PNP -static struct pci_config_table pci_mpc85xxads_config_table[] = { - { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_IDSEL_NUMBER, PCI_ANY_ID, - pci_cfgfunc_config_device, { PCI_ENET0_IOADDR, - PCI_ENET0_MEMADDR, - PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }}, - { } -}; + +static struct pci_controller *pci_hose; + +void +pci_mpc85xx_init(struct pci_controller *board_hose) +{ + u16 reg16; + u32 dev; + + volatile immap_t *immap = (immap_t *)CFG_CCSRBAR; + volatile ccsr_pcix_t *pcix = &immap->im_pcix; +#ifdef CONFIG_MPC85XX_PCI2 + volatile ccsr_pcix_t *pcix2 = &immap->im_pcix2; +#endif + volatile ccsr_gur_t *gur = &immap->im_gur; + struct pci_controller * hose; + + pci_hose = board_hose; + + hose = &pci_hose[0]; + + hose->first_busno = 0; + hose->last_busno = 0xff; + + pci_setup_indirect(hose, + (CFG_IMMR+0x8000), + (CFG_IMMR+0x8004)); + + /* + * Hose scan. + */ + dev = PCI_BDF(hose->first_busno, 0, 0); + pci_hose_read_config_word (hose, dev, PCI_COMMAND, ®16); + reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16); + + /* + * Clear non-reserved bits in status register. + */ + pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff); + + if (!(gur->pordevsr & PORDEVSR_PCI)) { + /* PCI-X init */ + if (CONFIG_SYS_CLK_FREQ < 66000000) + printf("PCI-X will only work at 66 MHz\n"); + + reg16 = PCI_X_CMD_MAX_SPLIT | PCI_X_CMD_MAX_READ + | PCI_X_CMD_ERO | PCI_X_CMD_DPERR_E; + pci_hose_write_config_word(hose, dev, PCIX_COMMAND, reg16); + } + + pcix->potar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff; + pcix->potear1 = 0x00000000; + pcix->powbar1 = (CFG_PCI1_MEM_PHYS >> 12) & 0x000fffff; + pcix->powbear1 = 0x00000000; + pcix->powar1 = (POWAR_EN | POWAR_MEM_READ | + POWAR_MEM_WRITE | (__ilog2(CFG_PCI1_MEM_SIZE) - 1)); + + pcix->potar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff; + pcix->potear2 = 0x00000000; + pcix->powbar2 = (CFG_PCI1_IO_PHYS >> 12) & 0x000fffff; + pcix->powbear2 = 0x00000000; + pcix->powar2 = (POWAR_EN | POWAR_IO_READ | + POWAR_IO_WRITE | (__ilog2(CFG_PCI1_IO_SIZE) - 1)); + + pcix->pitar1 = 0x00000000; + pcix->piwbar1 = 0x00000000; + pcix->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL | + PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G); + + pcix->powar3 = 0; + pcix->powar4 = 0; + pcix->piwar2 = 0; + pcix->piwar3 = 0; + + pci_set_region(hose->regions + 0, + CFG_PCI1_MEM_BASE, + CFG_PCI1_MEM_PHYS, + CFG_PCI1_MEM_SIZE, + PCI_REGION_MEM); + + pci_set_region(hose->regions + 1, + CFG_PCI1_IO_BASE, + CFG_PCI1_IO_PHYS, + CFG_PCI1_IO_SIZE, + PCI_REGION_IO); + + hose->region_count = 2; + + pci_register_hose(hose); + +#if defined(CONFIG_MPC8555CDS) || defined(CONFIG_MPC8541CDS) + /* + * This is a SW workaround for an apparent HW problem + * in the PCI controller on the MPC85555/41 CDS boards. + * The first config cycle must be to a valid, known + * device on the PCI bus in order to trick the PCI + * controller state machine into a known valid state. + * Without this, the first config cycle has the chance + * of hanging the controller permanently, just leaving + * it in a semi-working state, or leaving it working. + * + * Pick on the Tundra, Device 17, to get it right. + */ + { + u8 header_type; + + pci_hose_read_config_byte(hose, + PCI_BDF(0,17,0), + PCI_HEADER_TYPE, + &header_type); + } #endif -struct pci_controller local_hose = { -#ifndef CONFIG_PCI_PNP - config_table: pci_mpc85xxads_config_table, + hose->last_busno = pci_hose_scan(hose); + +#ifdef CONFIG_MPC85XX_PCI2 + hose = &pci_hose[1]; + + hose->first_busno = pci_hose[0].last_busno + 1; + hose->last_busno = 0xff; + + pci_setup_indirect(hose, + (CFG_IMMR+0x9000), + (CFG_IMMR+0x9004)); + + dev = PCI_BDF(hose->first_busno, 0, 0); + pci_hose_read_config_word (hose, dev, PCI_COMMAND, ®16); + reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; + pci_hose_write_config_word(hose, dev, PCI_COMMAND, reg16); + + /* + * Clear non-reserved bits in status register. + */ + pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff); + + pcix2->potar1 = (CFG_PCI2_MEM_BASE >> 12) & 0x000fffff; + pcix2->potear1 = 0x00000000; + pcix2->powbar1 = (CFG_PCI2_MEM_PHYS >> 12) & 0x000fffff; + pcix2->powbear1 = 0x00000000; + pcix2->powar1 = (POWAR_EN | POWAR_MEM_READ | + POWAR_MEM_WRITE | (__ilog2(CFG_PCI2_MEM_SIZE) - 1)); + + pcix2->potar2 = (CFG_PCI2_IO_BASE >> 12) & 0x000fffff; + pcix2->potear2 = 0x00000000; + pcix2->powbar2 = (CFG_PCI2_IO_PHYS >> 12) & 0x000fffff; + pcix2->powbear2 = 0x00000000; + pcix2->powar2 = (POWAR_EN | POWAR_IO_READ | + POWAR_IO_WRITE | (__ilog2(CFG_PCI2_IO_SIZE) - 1)); + + pcix2->pitar1 = 0x00000000; + pcix2->piwbar1 = 0x00000000; + pcix2->piwar1 = (PIWAR_EN | PIWAR_PF | PIWAR_LOCAL | + PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_MEM_2G); + + pcix2->powar3 = 0; + pcix2->powar4 = 0; + pcix2->piwar2 = 0; + pcix2->piwar3 = 0; + + pci_set_region(hose->regions + 0, + CFG_PCI2_MEM_BASE, + CFG_PCI2_MEM_PHYS, + CFG_PCI2_MEM_SIZE, + PCI_REGION_MEM); + + pci_set_region(hose->regions + 1, + CFG_PCI2_IO_BASE, + CFG_PCI2_IO_PHYS, + CFG_PCI2_IO_SIZE, + PCI_REGION_IO); + + hose->region_count = 2; + + /* + * Hose scan. + */ + pci_register_hose(hose); + + hose->last_busno = pci_hose_scan(hose); #endif -}; +} -void pci_init_board(void) +#ifdef CONFIG_OF_FLAT_TREE +void +ft_pci_setup(void *blob, bd_t *bd) { - struct pci_controller* hose = (struct pci_controller *)&local_hose; - volatile immap_t *immap = (immap_t *)CFG_CCSRBAR; - volatile ccsr_pcix_t *pcix = &immap->im_pcix; - - u16 reg16; - - hose->first_busno = 0; - hose->last_busno = 0xff; - - pci_set_region(hose->regions + 0, - CFG_PCI_MEM_BASE, - CFG_PCI_MEM_PHYS, - (CFG_PCI_MEM_SIZE/2), - PCI_REGION_MEM); - - pci_set_region(hose->regions + 1, - (CFG_PCI_MEM_BASE+0x08000000), - (CFG_PCI_MEM_PHYS+0x08000000), - 0x1000000, /* 16M */ - PCI_REGION_IO); - - hose->region_count = 2; - - pci_setup_indirect(hose, - (CFG_IMMR+0x8000), - (CFG_IMMR+0x8004)); - - pci_register_hose(hose); - - hose->last_busno = pci_hose_scan(hose); - - pci_read_config_word (PCI_BDF(0,0,0), PCI_COMMAND, ®16); - reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY; - pci_write_config_word(PCI_BDF(0,0,0), PCI_COMMAND, reg16); - - /* Clear non-reserved bits in status register */ - pci_write_config_word(PCI_BDF(0,0,0), PCI_STATUS, 0xffff); - pci_write_config_byte(PCI_BDF(0,0,0), PCI_LATENCY_TIMER,0x80); - - pcix->potar1 = (CFG_PCI_MEM_BASE >> 12) & 0x000fffff; - pcix->potear1 = 0x00000000; - pcix->powbar1 = (CFG_PCI_MEM_BASE >> 12) & 0x000fffff; - pcix->powbear1 = 0x00000000; - pcix->powar1 = 0x8004401a; /* 128M MEM space */ - pcix->potar2 = ((CFG_PCI_MEM_BASE + 0x08000000) >> 12) & 0x000fffff; - pcix->potear2 = 0x00000000; - pcix->powbar2 = ((CFG_PCI_MEM_BASE + 0x08000000) >> 12) && 0x000fffff; - pcix->powbear2 = 0x00000000; - pcix->powar2 = 0x80088017; /* 16M IO space */ - pcix->pitar1 = 0x00000000; - pcix->piwbar1 = 0x00000000; - pcix->piwar1 = 0xa0F5501f; - + u32 *p; + int len; + + p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@8000/bus-range", &len); + if (p != NULL) { + p[0] = pci_hose[0].first_busno; + p[1] = pci_hose[0].last_busno; + } + +#ifdef CONFIG_MPC85XX_PCI2 + p = (u32 *)ft_get_prop(blob, "/" OF_SOC "/pci@9000/bus-range", &len); + if (p != NULL) { + p[0] = pci_hose[1].first_busno; + p[1] = pci_hose[1].last_busno; + } +#endif } +#endif /* CONFIG_OF_FLAT_TREE */ #endif /* CONFIG_PCI */