@ -16,7 +16,9 @@
# include <mpc83xx.h>
# include <pci.h>
# include <i2c.h>
# include <fdt_support.h>
# include <asm/fsl_i2c.h>
# include <asm/fsl_serdes.h>
# if defined(CONFIG_PCI)
static struct pci_region pci_regions [ ] = {
@ -40,15 +42,59 @@ static struct pci_region pci_regions[] = {
}
} ;
static struct pci_region pcie_regions_0 [ ] = {
{
. bus_start = CONFIG_SYS_PCIE1_MEM_BASE ,
. phys_start = CONFIG_SYS_PCIE1_MEM_PHYS ,
. size = CONFIG_SYS_PCIE1_MEM_SIZE ,
. flags = PCI_REGION_MEM ,
} ,
{
. bus_start = CONFIG_SYS_PCIE1_IO_BASE ,
. phys_start = CONFIG_SYS_PCIE1_IO_PHYS ,
. size = CONFIG_SYS_PCIE1_IO_SIZE ,
. flags = PCI_REGION_IO ,
} ,
} ;
static struct pci_region pcie_regions_1 [ ] = {
{
. bus_start = CONFIG_SYS_PCIE2_MEM_BASE ,
. phys_start = CONFIG_SYS_PCIE2_MEM_PHYS ,
. size = CONFIG_SYS_PCIE2_MEM_SIZE ,
. flags = PCI_REGION_MEM ,
} ,
{
. bus_start = CONFIG_SYS_PCIE2_IO_BASE ,
. phys_start = CONFIG_SYS_PCIE2_IO_PHYS ,
. size = CONFIG_SYS_PCIE2_IO_SIZE ,
. flags = PCI_REGION_IO ,
} ,
} ;
static int is_pex_x2 ( void )
{
const char * pex_x2 = getenv ( " pex_x2 " ) ;
if ( pex_x2 & & ! strcmp ( pex_x2 , " yes " ) )
return 1 ;
return 0 ;
}
void pci_init_board ( void )
{
volatile immap_t * immr = ( volatile immap_t * ) CONFIG_SYS_IMMR ;
volatile sysconf83xx_t * sysconf = & immr - > sysconf ;
volatile clk83xx_t * clk = ( volatile clk83xx_t * ) & immr - > clk ;
volatile law83xx_t * pci_law = immr - > sysconf . pcilaw ;
volatile law83xx_t * pcie_law = sysconf - > pcielaw ;
struct pci_region * reg [ ] = { pci_regions } ;
struct pci_region * pcie_reg [ ] = { pcie_regions_0 , pcie_regions_1 , } ;
u32 spridr = in_be32 ( & immr - > sysconf . spridr ) ;
int pex2 = is_pex_x2 ( ) ;
if ( board_pci_host_broken ( ) )
return ;
goto skip_pci ;
/* Enable all 5 PCI_CLK_OUTPUTS */
clk - > occr | = 0xf8000000 ;
@ -64,5 +110,46 @@ void pci_init_board(void)
udelay ( 2000 ) ;
mpc83xx_pci_init ( 1 , reg , 0 ) ;
skip_pci :
/* There is no PEX in MPC8379 parts. */
if ( PARTID_NO_E ( spridr ) = = SPR_8379 )
return ;
/* Configure the clock for PCIE controller */
clrsetbits_be32 ( & clk - > sccr , SCCR_PCIEXP1CM | SCCR_PCIEXP2CM ,
SCCR_PCIEXP1CM_1 | SCCR_PCIEXP2CM_1 ) ;
/* Deassert the resets in the control register */
out_be32 ( & sysconf - > pecr1 , 0xE0008000 ) ;
if ( ! pex2 )
out_be32 ( & sysconf - > pecr2 , 0xE0008000 ) ;
udelay ( 2000 ) ;
/* Configure PCI Express Local Access Windows */
out_be32 ( & pcie_law [ 0 ] . bar , CONFIG_SYS_PCIE1_BASE & LAWBAR_BAR ) ;
out_be32 ( & pcie_law [ 0 ] . ar , LBLAWAR_EN | LBLAWAR_512MB ) ;
out_be32 ( & pcie_law [ 1 ] . bar , CONFIG_SYS_PCIE2_BASE & LAWBAR_BAR ) ;
out_be32 ( & pcie_law [ 1 ] . ar , LBLAWAR_EN | LBLAWAR_512MB ) ;
if ( pex2 )
fsl_setup_serdes ( CONFIG_FSL_SERDES2 , FSL_SERDES_PROTO_PEX_X2 ,
FSL_SERDES_CLK_100 , FSL_SERDES_VDD_1V ) ;
else
fsl_setup_serdes ( CONFIG_FSL_SERDES2 , FSL_SERDES_PROTO_PEX ,
FSL_SERDES_CLK_100 , FSL_SERDES_VDD_1V ) ;
mpc83xx_pcie_init ( pex2 ? 1 : 2 , pcie_reg , 0 ) ;
}
void ft_pcie_fixup ( void * blob , bd_t * bd )
{
const char * status = " disabled (PCIE1 is x2) " ;
if ( ! is_pex_x2 ( ) )
return ;
do_fixup_by_path ( blob , " pci2 " , " status " , status ,
strlen ( status ) + 1 , 1 ) ;
}
# endif /* CONFIG_PCI */