Commit 63cec581 authored by Ed Swarthout's avatar Ed Swarthout Committed by Wolfgang Denk

Make MPC8641's PCI/PCI-E driver a common driver for many FSL parts.

All of the PCI/PCI-Express driver and initialization code that
was in the MPC8641HPCN port has now been moved into the common
drivers/fsl_pci_init.c.  In a subsequent patch, this will be
utilized by the 85xx ports as well.

Common PCI-E IMMAP register blocks for FSL 85xx/86xx are added.

Also enable the second PCI-Express controller on 8641
by getting its BATS and CFG_ setup right.

Fixed a u16 vendor compiler warning in AHCI driver too.
Signed-off-by: default avatarEd Swarthout <Ed.Swarthout@freescale.com>
Signed-off-by: default avatarZhang Wei <wei.zhang@freescale.com>
Signed-off-by: default avatarJon Loeliger <jdl@freescale.com>
parent 63e22764
......@@ -11,7 +11,7 @@
*
* 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
* 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
......@@ -24,6 +24,7 @@
#include <pci.h>
#include <asm/processor.h>
#include <asm/immap_86xx.h>
#include <asm/immap_fsl_pci.h>
#include <spd.h>
#include <asm/io.h>
......@@ -55,37 +56,6 @@ int checkboard(void)
{
puts("Board: MPC8641HPCN\n");
#ifdef CONFIG_PCI
volatile immap_t *immap = (immap_t *) CFG_CCSRBAR;
volatile ccsr_gur_t *gur = &immap->im_gur;
volatile ccsr_pex_t *pex1 = &immap->im_pex1;
uint devdisr = gur->devdisr;
uint io_sel = (gur->pordevsr & MPC86xx_PORDEVSR_IO_SEL) >> 16;
#ifdef DEBUG
uint host1_agent = (gur->porbmsr & MPC86xx_PORBMSR_HA) >> 17;
uint pex1_agent = (host1_agent == 0) || (host1_agent == 1);
#endif
if ((io_sel == 2 || io_sel == 3 || io_sel == 5
|| io_sel == 6 || io_sel == 7 || io_sel == 0xF)
&& !(devdisr & MPC86xx_DEVDISR_PCIEX1)) {
debug("PCI-EXPRESS 1: %s \n", pex1_agent ? "Agent" : "Host");
debug("0x%08x=0x%08x ", &pex1->pme_msg_det, pex1->pme_msg_det);
if (pex1->pme_msg_det) {
pex1->pme_msg_det = 0xffffffff;
debug(" with errors. Clearing. Now 0x%08x",
pex1->pme_msg_det);
}
debug("\n");
} else {
puts("PCI-EXPRESS 1: Disabled\n");
}
#else
puts("PCI-EXPRESS1: Disabled\n");
#endif
return 0;
}
......@@ -220,21 +190,138 @@ static struct pci_config_table pci_fsl86xxads_config_table[] = {
#endif
static struct pci_controller hose = {
static struct pci_controller pci1_hose = {
#ifndef CONFIG_PCI_PNP
config_table:pci_mpc86xxcts_config_table,
config_table:pci_mpc86xxcts_config_table
#endif
};
#endif /* CONFIG_PCI */
#ifdef CONFIG_PCI2
static struct pci_controller pci2_hose;
#endif /* CONFIG_PCI2 */
int first_free_busno = 0;
void pci_init_board(void)
{
#ifdef CONFIG_PCI
extern void pci_mpc86xx_init(struct pci_controller *hose);
volatile immap_t *immap = (immap_t *) CFG_CCSRBAR;
volatile ccsr_gur_t *gur = &immap->im_gur;
uint devdisr = gur->devdisr;
uint io_sel = (gur->pordevsr & MPC86xx_PORDEVSR_IO_SEL) >> 16;
#ifdef CONFIG_PCI1
{
volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CFG_PCI1_ADDR;
extern void fsl_pci_init(struct pci_controller *hose);
struct pci_controller *hose = &pci1_hose;
#ifdef DEBUG
uint host1_agent = (gur->porbmsr & MPC86xx_PORBMSR_HA) >> 17;
uint pex1_agent = (host1_agent == 0) || (host1_agent == 1);
#endif
if ((io_sel == 2 || io_sel == 3 || io_sel == 5
|| io_sel == 6 || io_sel == 7 || io_sel == 0xF)
&& !(devdisr & MPC86xx_DEVDISR_PCIEX1)) {
debug("PCI-EXPRESS 1: %s \n", pex1_agent ? "Agent" : "Host");
debug("0x%08x=0x%08x ", &pci->pme_msg_det, pci->pme_msg_det);
if (pci->pme_msg_det) {
pci->pme_msg_det = 0xffffffff;
debug(" with errors. Clearing. Now 0x%08x",
pci->pme_msg_det);
}
debug("\n");
/* inbound */
pci_set_region(hose->regions + 0,
CFG_PCI_MEMORY_BUS,
CFG_PCI_MEMORY_PHYS,
CFG_PCI_MEMORY_SIZE,
PCI_REGION_MEM | PCI_REGION_MEMORY);
/* outbound memory */
pci_set_region(hose->regions + 1,
CFG_PCI1_MEM_BASE,
CFG_PCI1_MEM_PHYS,
CFG_PCI1_MEM_SIZE,
PCI_REGION_MEM);
/* outbound io */
pci_set_region(hose->regions + 2,
CFG_PCI1_IO_BASE,
CFG_PCI1_IO_PHYS,
CFG_PCI1_IO_SIZE,
PCI_REGION_IO);
hose->region_count = 3;
hose->first_busno=first_free_busno;
pci_setup_indirect(hose, (int) &pci->cfg_addr, (int) &pci->cfg_data);
fsl_pci_init(hose);
first_free_busno=hose->last_busno+1;
printf (" PCI-EXPRESS 1 on bus %02x - %02x\n",
hose->first_busno,hose->last_busno);
/*
* Activate ULI1575 legacy chip by performing a fake
* memory access. Needed to make ULI RTC work.
*/
in_be32((unsigned *) CFG_PCI1_MEM_BASE
+ CFG_PCI1_MEM_SIZE - 0x1000000);
} else {
puts("PCI-EXPRESS 1: Disabled\n");
}
}
#else
puts("PCI-EXPRESS1: Disabled\n");
#endif /* CONFIG_PCI1 */
#ifdef CONFIG_PCI2
{
volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) CFG_PCI2_ADDR;
extern void fsl_pci_init(struct pci_controller *hose);
struct pci_controller *hose = &pci2_hose;
/* inbound */
pci_set_region(hose->regions + 0,
CFG_PCI_MEMORY_BUS,
CFG_PCI_MEMORY_PHYS,
CFG_PCI_MEMORY_SIZE,
PCI_REGION_MEM | PCI_REGION_MEMORY);
/* outbound memory */
pci_set_region(hose->regions + 1,
CFG_PCI2_MEM_BASE,
CFG_PCI2_MEM_PHYS,
CFG_PCI2_MEM_SIZE,
PCI_REGION_MEM);
/* outbound io */
pci_set_region(hose->regions + 2,
CFG_PCI2_IO_BASE,
CFG_PCI2_IO_PHYS,
CFG_PCI2_IO_SIZE,
PCI_REGION_IO);
hose->region_count = 3;
hose->first_busno=first_free_busno;
pci_setup_indirect(hose, (int) &pci->cfg_addr, (int) &pci->cfg_data);
fsl_pci_init(hose);
first_free_busno=hose->last_busno+1;
printf (" PCI-EXPRESS 2 on bus %02x - %02x\n",
hose->first_busno,hose->last_busno);
}
#else
puts("PCI-EXPRESS 2: Disabled\n");
#endif /* CONFIG_PCI2 */
pci_mpc86xx_init(&hose);
#endif /* CONFIG_PCI */
}
#if defined(CONFIG_OF_FLAT_TREE) && defined(CONFIG_OF_BOARD_SETUP)
......
......@@ -57,7 +57,6 @@ SECTIONS
cpu/mpc86xx/cpu_init.o (.text)
cpu/mpc86xx/cpu.o (.text)
cpu/mpc86xx/speed.o (.text)
cpu/mpc86xx/pci.o (.text)
common/dlmalloc.o (.text)
lib_generic/crc32.o (.text)
lib_ppc/extable.o (.text)
......
#
# Copyright 2007 Freescale Semiconductor, Inc.
# (C) Copyright 2002,2003 Motorola Inc.
# Xianghua Xiao,X.Xiao@motorola.com
#
......@@ -30,7 +31,7 @@ LIB = $(obj)lib$(CPU).a
START = start.o #resetvec.o
SOBJS = cache.o
COBJS = traps.o cpu.o cpu_init.o speed.o interrupts.o \
pci.o pcie_indirect.o spd_sdram.o
spd_sdram.o
SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
......
/*
* Copyright (C) Freescale Semiconductor,Inc.
* 2005, 2006. All rights reserved.
*
* Ed Swarthout (ed.swarthout@freescale.com)
* Jason Jin (Jason.jin@freescale.com)
*
* 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
*/
/*
* PCIE Configuration space access support for PCIE Bridge
*/
#include <common.h>
#include <pci.h>
#if defined(CONFIG_PCI)
void
pci_mpc86xx_init(struct pci_controller *hose)
{
volatile immap_t *immap = (immap_t *) CFG_CCSRBAR;
volatile ccsr_pex_t *pcie1 = &immap->im_pex1;
u16 temp16;
u32 temp32;
volatile ccsr_gur_t *gur = &immap->im_gur;
uint host1_agent = (gur->porbmsr & MPC86xx_PORBMSR_HA) >> 17;
uint pcie1_host = (host1_agent == 2) || (host1_agent == 3);
uint pcie1_agent = (host1_agent == 0) || (host1_agent == 1);
uint devdisr = gur->devdisr;
uint io_sel = (gur->pordevsr & MPC86xx_PORDEVSR_IO_SEL) >> 16;
if ((io_sel == 2 || io_sel == 3 || io_sel == 5 || io_sel == 6 ||
io_sel == 7 || io_sel == 0xf)
&& !(devdisr & MPC86xx_DEVDISR_PCIEX1)) {
printf("PCI-EXPRESS 1: Configured as %s \n",
pcie1_agent ? "Agent" : "Host");
if (pcie1_agent)
return; /*Don't scan bus when configured as agent */
printf(" Scanning PCIE bus");
debug("0x%08x=0x%08x ",
&pcie1->pme_msg_det,
pcie1->pme_msg_det);
if (pcie1->pme_msg_det) {
pcie1->pme_msg_det = 0xffffffff;
debug(" with errors. Clearing. Now 0x%08x",
pcie1->pme_msg_det);
}
debug("\n");
} else {
printf("PCI-EXPRESS 1 disabled!\n");
return;
}
/*
* Set first_bus=0 only skipped B0:D0:F0 which is
* a reserved device in M1575, but make it easy for
* most of the scan process.
*/
hose->first_busno = 0x00;
hose->last_busno = 0xfe;
pcie_setup_indirect(hose, (CFG_IMMR + 0x8000), (CFG_IMMR + 0x8004));
pci_hose_read_config_word(hose,
PCI_BDF(0, 0, 0), PCI_COMMAND, &temp16);
temp16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER |
PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
pci_hose_write_config_word(hose,
PCI_BDF(0, 0, 0), PCI_COMMAND, temp16);
pci_hose_write_config_word(hose, PCI_BDF(0, 0, 0), PCI_STATUS, 0xffff);
pci_hose_write_config_byte(hose,
PCI_BDF(0, 0, 0), PCI_LATENCY_TIMER, 0x80);
pci_hose_read_config_dword(hose, PCI_BDF(0, 0, 0), PCI_PRIMARY_BUS,
&temp32);
temp32 = (temp32 & 0xff000000) | (0xff) | (0x0 << 8) | (0xfe << 16);
pci_hose_write_config_dword(hose, PCI_BDF(0, 0, 0), PCI_PRIMARY_BUS,
temp32);
pcie1->powar1 = 0;
pcie1->powar2 = 0;
pcie1->piwar1 = 0;
pcie1->piwar1 = 0;
pcie1->powbar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
pcie1->powar1 = 0x8004401c; /* 512M MEM space */
pcie1->potar1 = (CFG_PCI1_MEM_BASE >> 12) & 0x000fffff;
pcie1->potear1 = 0x00000000;
pcie1->powbar2 = (CFG_PCI1_IO_BASE >> 12) & 0x000fffff;
pcie1->powar2 = 0x80088017; /* 16M IO space */
pcie1->potar2 = 0x00000000;
pcie1->potear2 = 0x00000000;
pcie1->pitar1 = 0x00000000;
pcie1->piwbar1 = 0x00000000;
/* Enable, Prefetch, Local Mem, * Snoop R/W, 2G */
pcie1->piwar1 = 0xa0f5501e;
pci_set_region(hose->regions + 0,
CFG_PCI_MEMORY_BUS,
CFG_PCI_MEMORY_PHYS,
CFG_PCI_MEMORY_SIZE,
PCI_REGION_MEM | PCI_REGION_MEMORY);
pci_set_region(hose->regions + 1,
CFG_PCI1_MEM_BASE,
CFG_PCI1_MEM_PHYS,
CFG_PCI1_MEM_SIZE,
PCI_REGION_MEM);
pci_set_region(hose->regions + 2,
CFG_PCI1_IO_BASE,
CFG_PCI1_IO_PHYS,
CFG_PCI1_IO_SIZE,
PCI_REGION_IO);
hose->region_count = 3;
pci_register_hose(hose);
hose->last_busno = pci_hose_scan(hose);
debug("pcie_mpc86xx_init: last_busno %x\n", hose->last_busno);
debug("pcie_mpc86xx init: current_busno %x\n ", hose->current_busno);
printf("....PCIE1 scan & enumeration done\n");
}
#endif /* CONFIG_PCI */
/*
* Support for indirect PCI bridges.
*
* Copyright (c) Freescale Semiconductor, Inc.
* 2006. All rights reserved.
*
* Jason Jin <Jason.jin@freescale.com>
*
* 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.
*
* partly derived from
* arch/powerpc/platforms/86xx/mpc86xx_pcie.c
*/
#include <common.h>
#ifdef CONFIG_PCI
#include <asm/processor.h>
#include <asm/io.h>
#include <pci.h>
#define PCI_CFG_OUT out_be32
#define PEX_FIX out_be32(hose->cfg_addr+0x4, 0x0400ffff)
static int
indirect_read_config_pcie(struct pci_controller *hose,
pci_dev_t dev,
int offset,
int len,
u32 *val)
{
int bus = PCI_BUS(dev);
volatile unsigned char *cfg_data;
u32 temp;
PEX_FIX;
if (bus == 0xff) {
PCI_CFG_OUT(hose->cfg_addr,
dev | (offset & 0xfc) | 0x80000001);
} else {
PCI_CFG_OUT(hose->cfg_addr,
dev | (offset & 0xfc) | 0x80000000);
}
/*
* Note: the caller has already checked that offset is
* suitably aligned and that len is 1, 2 or 4.
*/
/* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */
cfg_data = hose->cfg_data;
PEX_FIX;
temp = in_le32((u32 *) cfg_data);
switch (len) {
case 1:
*val = (temp >> (((offset & 3)) * 8)) & 0xff;
break;
case 2:
*val = (temp >> (((offset & 3)) * 8)) & 0xffff;
break;
default:
*val = temp;
break;
}
return 0;
}
static int
indirect_write_config_pcie(struct pci_controller *hose,
pci_dev_t dev,
int offset,
int len,
u32 val)
{
int bus = PCI_BUS(dev);
volatile unsigned char *cfg_data;
u32 temp;
PEX_FIX;
if (bus == 0xff) {
PCI_CFG_OUT(hose->cfg_addr,
dev | (offset & 0xfc) | 0x80000001);
} else {
PCI_CFG_OUT(hose->cfg_addr,
dev | (offset & 0xfc) | 0x80000000);
}
/*
* Note: the caller has already checked that offset is
* suitably aligned and that len is 1, 2 or 4.
*/
/* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */
cfg_data = hose->cfg_data;
switch (len) {
case 1:
PEX_FIX;
temp = in_le32((u32 *) cfg_data);
temp = (temp & ~(0xff << ((offset & 3) * 8))) |
(val << ((offset & 3) * 8));
PEX_FIX;
out_le32((u32 *) cfg_data, temp);
break;
case 2:
PEX_FIX;
temp = in_le32((u32 *) cfg_data);
temp = (temp & ~(0xffff << ((offset & 3) * 8)));
temp |= (val << ((offset & 3) * 8));
PEX_FIX;
out_le32((u32 *) cfg_data, temp);
break;
default:
PEX_FIX;
out_le32((u32 *) cfg_data, val);
break;
}
PEX_FIX;
return 0;
}
static int
indirect_read_config_byte_pcie(struct pci_controller *hose,
pci_dev_t dev,
int offset,
u8 *val)
{
u32 val32;
indirect_read_config_pcie(hose, dev, offset, 1, &val32);
*val = (u8) val32;
return 0;
}
static int
indirect_read_config_word_pcie(struct pci_controller *hose,
pci_dev_t dev,
int offset,
u16 *val)
{
u32 val32;
indirect_read_config_pcie(hose, dev, offset, 2, &val32);
*val = (u16) val32;
return 0;
}
static int
indirect_read_config_dword_pcie(struct pci_controller *hose,
pci_dev_t dev,
int offset,
u32 *val)
{
return indirect_read_config_pcie(hose, dev, offset, 4, val);
}
static int
indirect_write_config_byte_pcie(struct pci_controller *hose,
pci_dev_t dev,
int offset,
u8 val)
{
return indirect_write_config_pcie(hose, dev, offset, 1, (u32) val);
}
static int
indirect_write_config_word_pcie(struct pci_controller *hose,
pci_dev_t dev,
int offset,
unsigned short val)
{
return indirect_write_config_pcie(hose, dev, offset, 2, (u32) val);
}
static int
indirect_write_config_dword_pcie(struct pci_controller *hose,
pci_dev_t dev,
int offset,
u32 val)
{
return indirect_write_config_pcie(hose, dev, offset, 4, val);
}
void
pcie_setup_indirect(struct pci_controller *hose, u32 cfg_addr, u32 cfg_data)
{
pci_set_ops(hose,
indirect_read_config_byte_pcie,
indirect_read_config_word_pcie,
indirect_read_config_dword_pcie,
indirect_write_config_byte_pcie,
indirect_write_config_word_pcie,
indirect_write_config_dword_pcie);
hose->cfg_addr = (unsigned int *)cfg_addr;
hose->cfg_data = (unsigned char *)cfg_data;
}
#endif /* CONFIG_PCI */
......@@ -52,7 +52,7 @@ COBJS = 3c589.o 5701rls.o ali512x.o ata_piix.o atmel_usart.o \
ks8695eth.o \
pxa_pcmcia.o mpc8xx_pcmcia.o tqm8xx_pcmcia.o \
rpx_pcmcia.o \
fsl_i2c.o
fsl_i2c.o fsl_pci_init.o
SRCS := $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
......
......@@ -253,7 +253,8 @@ static void ahci_print_info(struct ahci_probe_ent *probe_ent)
static int ahci_init_one(pci_dev_t pdev)
{
u32 iobase, vendor;
u32 iobase;
u16 vendor;
int rc;
memset((void *)ataid, 0, sizeof(hd_driveid_t *) * AHCI_MAX_PORTS);
......
/*
* Copyright 2007 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* Version 2 as published by the Free Software Foundation.
*
* 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
*/
#define DEBUG
#include <common.h>
#ifdef CONFIG_FSL_PCI_INIT
/*
* PCI/PCIE Controller initialization for mpc85xx/mpc86xx soc's
*
* Initialize controller and call the common driver/pci pci_hose_scan to
* scan for bridges and devices.
*
* Hose fields which need to be pre-initialized by board specific code:
* regions[]
* first_busno
*
* Fields updated:
* last_busno
*/
#include <pci.h>
#include <asm/immap_fsl_pci.h>
void pciauto_prescan_setup_bridge(struct pci_controller *hose,
pci_dev_t dev, int sub_bus);
void pciauto_postscan_setup_bridge(struct pci_controller *hose,
pci_dev_t dev, int sub_bus);
void pciauto_config_init(struct pci_controller *hose);
void
fsl_pci_init(struct pci_controller *hose)
{
u16 temp16;
u32 temp32;
int busno = hose->first_busno;
int enabled;
u16 ltssm;
u8 temp8;
int r;
int bridge;
volatile ccsr_fsl_pci_t *pci = (ccsr_fsl_pci_t *) hose->cfg_addr;
pci_dev_t dev = PCI_BDF(busno,0,0);
/* Initialize ATMU registers based on hose regions and flags */
volatile pot_t *po=&pci->pot[1]; /* skip 0 */
volatile pit_t *pi=&pci->pit[0]; /* ranges from: 3 to 1 */
#ifdef DEBUG
int neg_link_w;
#endif
for (r=0; r<hose->region_count; r++) {
if (hose->regions[r].flags & PCI_REGION_MEMORY) { /* inbound */
pi->pitar = (hose->regions[r].bus_start >> 12) & 0x000fffff;
pi->piwbar = (hose->regions[r].phys_start >> 12) & 0x000fffff;
pi->piwbear = 0;
pi->piwar = PIWAR_EN | PIWAR_PF | PIWAR_LOCAL |
PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP |
(__ilog2(hose->regions[r].size) - 1);
pi++;
} else { /* Outbound */
po->powbar = (hose->regions[r].phys_start >> 12) & 0x000fffff;
po->potar = (hose->regions[r].bus_start >> 12) & 0x000fffff;
po->potear = 0;
if (hose->regions[r].flags & PCI_REGION_IO)
po->powar = POWAR_EN | POWAR_IO_READ | POWAR_IO_WRITE |
(__ilog2(hose->regions[r].size) - 1);
else
po->powar = POWAR_EN | POWAR_MEM_READ | POWAR_MEM_WRITE |
(__ilog2(hose->regions[r].size) - 1);
po++;
}
}
pci_register_hose(hose);
pciauto_config_init(hose); /* grab pci_{mem,prefetch,io} */
hose->current_busno = hose->first_busno;
pci->pedr = 0xffffffff; /* Clear any errors */
pci->peer = 0xffffffff; /* Enable Error Interupts */
pci_hose_read_config_dword (hose, dev, PCI_DCR, &temp32);
temp32 |= 0xf000e; /* set URR, FER, NFER (but not CER) */
pci_hose_write_config_dword(hose, dev, PCI_DCR, temp32);
pci_hose_read_config_byte (hose, dev, PCI_HEADER_TYPE, &temp8);
bridge = temp8 & PCI_HEADER_TYPE_BRIDGE; /* Bridge, such as pcie */
if ( bridge ) {
pci_hose_read_config_word(hose, dev, PCI_LTSSM, &ltssm);
enabled = ltssm >= PCI_LTSSM_L0;
if (!enabled) {
debug("....PCIE link error. Skipping scan."
"LTSSM=0x%02x\n", temp16);
hose->last_busno = hose->first_busno;
return;
}
pci->pme_msg_det = 0xffffffff;
pci->pme_msg_int_en = 0xffffffff;
#ifdef DEBUG
pci_hose_read_config_word(hose, dev, PCI_LSR, &temp16);
neg_link_w = (temp16 & 0x3f0 ) >> 4;
debug("...PCIE LTSSM=0x%x, Negotiated link width=%d\n",
ltssm, neg_link_w);
#endif
hose->current_busno++; /* Start scan with secondary */
pciauto_prescan_setup_bridge(hose, dev, hose->current_busno);
} else {
#if 0
/* done in pci_hose_config_device() */
pci_hose_read_config_word(hose, dev, PCI_COMMAND, &temp16);
temp16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER |
PCI_COMMAND_MEMORY | PCI_COMMAND_IO;