ppc4xx: Consolidate 4xx PCIe board specific configuration
This patch consolidates the PPC4xx board specific PCIe configuration code. This way the duplicated code is removed. Boards can implement a special, non standard behaviour (e.g. number of PCIe slots, etc) by overriding the weak default functions. Signed-off-by: Stefan Roese <sr@denx.de>
This commit is contained in:
parent
2cd95a25cb
commit
b0b867462c
@ -383,84 +383,16 @@ int is_pci_host(struct pci_controller *hose)
|
||||
return (1);
|
||||
}
|
||||
|
||||
static struct pci_controller pcie_hose[2] = {{0},{0}};
|
||||
|
||||
void pcie_setup_hoses(int busno)
|
||||
int board_pcie_first(void)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
int i, bus;
|
||||
int ret = 0;
|
||||
char *env;
|
||||
unsigned int delay;
|
||||
int start;
|
||||
|
||||
/*
|
||||
* assume we're called after the PCIX hose is initialized, which takes
|
||||
* bus ID 0 and therefore start numbering PCIe's from 1.
|
||||
*/
|
||||
bus = busno;
|
||||
|
||||
/*
|
||||
* Canyonlands with SATA enabled has only one PCIe slot
|
||||
* (2nd one).
|
||||
*/
|
||||
if (gd->board_type == BOARD_CANYONLANDS_SATA)
|
||||
start = 1;
|
||||
else
|
||||
start = 0;
|
||||
return 1;
|
||||
|
||||
for (i = start; i <= 1; i++) {
|
||||
|
||||
if (is_end_point(i))
|
||||
ret = ppc4xx_init_pcie_endport(i);
|
||||
else
|
||||
ret = ppc4xx_init_pcie_rootport(i);
|
||||
if (ret == -ENODEV)
|
||||
continue;
|
||||
if (ret) {
|
||||
printf("PCIE%d: initialization as %s failed\n", i,
|
||||
is_end_point(i) ? "endpoint" : "root-complex");
|
||||
continue;
|
||||
}
|
||||
|
||||
hose = &pcie_hose[i];
|
||||
hose->first_busno = bus;
|
||||
hose->last_busno = bus;
|
||||
hose->current_busno = bus;
|
||||
|
||||
/* setup mem resource */
|
||||
pci_set_region(hose->regions + 0,
|
||||
CONFIG_SYS_PCIE_MEMBASE + i * CONFIG_SYS_PCIE_MEMSIZE,
|
||||
CONFIG_SYS_PCIE_MEMBASE + i * CONFIG_SYS_PCIE_MEMSIZE,
|
||||
CONFIG_SYS_PCIE_MEMSIZE,
|
||||
PCI_REGION_MEM);
|
||||
hose->region_count = 1;
|
||||
pci_register_hose(hose);
|
||||
|
||||
if (is_end_point(i)) {
|
||||
ppc4xx_setup_pcie_endpoint(hose, i);
|
||||
/*
|
||||
* Reson for no scanning is endpoint can not generate
|
||||
* upstream configuration accesses.
|
||||
*/
|
||||
} else {
|
||||
ppc4xx_setup_pcie_rootpoint(hose, i);
|
||||
env = getenv ("pciscandelay");
|
||||
if (env != NULL) {
|
||||
delay = simple_strtoul(env, NULL, 10);
|
||||
if (delay > 5)
|
||||
printf("Warning, expect noticable delay before "
|
||||
"PCIe scan due to 'pciscandelay' value!\n");
|
||||
mdelay(delay * 1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* Config access can only go down stream
|
||||
*/
|
||||
hose->last_busno = pci_hose_scan(hose);
|
||||
bus = hose->last_busno + 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
|
@ -351,7 +351,7 @@ int is_pci_host(struct pci_controller *hose)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int katmai_pcie_card_present(int port)
|
||||
int board_pcie_card_present(int port)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
@ -367,78 +367,6 @@ static int katmai_pcie_card_present(int port)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static struct pci_controller pcie_hose[3] = {{0},{0},{0}};
|
||||
|
||||
void pcie_setup_hoses(int busno)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
int i, bus;
|
||||
int ret = 0;
|
||||
char *env;
|
||||
unsigned int delay;
|
||||
|
||||
/*
|
||||
* assume we're called after the PCIX hose is initialized, which takes
|
||||
* bus ID 0 and therefore start numbering PCIe's from 1.
|
||||
*/
|
||||
bus = busno;
|
||||
for (i = 0; i <= 2; i++) {
|
||||
/* Check for katmai card presence */
|
||||
if (!katmai_pcie_card_present(i))
|
||||
continue;
|
||||
|
||||
if (is_end_point(i))
|
||||
ret = ppc4xx_init_pcie_endport(i);
|
||||
else
|
||||
ret = ppc4xx_init_pcie_rootport(i);
|
||||
if (ret == -ENODEV)
|
||||
continue;
|
||||
if (ret) {
|
||||
printf("PCIE%d: initialization as %s failed\n", i,
|
||||
is_end_point(i) ? "endpoint" : "root-complex");
|
||||
continue;
|
||||
}
|
||||
|
||||
hose = &pcie_hose[i];
|
||||
hose->first_busno = bus;
|
||||
hose->last_busno = bus;
|
||||
hose->current_busno = bus;
|
||||
|
||||
/* setup mem resource */
|
||||
pci_set_region(hose->regions + 0,
|
||||
CONFIG_SYS_PCIE_MEMBASE + i * CONFIG_SYS_PCIE_MEMSIZE,
|
||||
CONFIG_SYS_PCIE_MEMBASE + i * CONFIG_SYS_PCIE_MEMSIZE,
|
||||
CONFIG_SYS_PCIE_MEMSIZE,
|
||||
PCI_REGION_MEM);
|
||||
hose->region_count = 1;
|
||||
pci_register_hose(hose);
|
||||
|
||||
if (is_end_point(i)) {
|
||||
ppc4xx_setup_pcie_endpoint(hose, i);
|
||||
/*
|
||||
* Reson for no scanning is endpoint can not generate
|
||||
* upstream configuration accesses.
|
||||
*/
|
||||
} else {
|
||||
ppc4xx_setup_pcie_rootpoint(hose, i);
|
||||
env = getenv ("pciscandelay");
|
||||
if (env != NULL) {
|
||||
delay = simple_strtoul(env, NULL, 10);
|
||||
if (delay > 5)
|
||||
printf("Warning, expect noticable delay before "
|
||||
"PCIe scan due to 'pciscandelay' value!\n");
|
||||
mdelay(delay * 1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* Config access can only go down stream
|
||||
*/
|
||||
hose->last_busno = pci_hose_scan(hose);
|
||||
bus = hose->last_busno + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* defined(CONFIG_PCI) */
|
||||
|
||||
#ifdef CONFIG_POST
|
||||
|
@ -252,15 +252,19 @@ int board_emac_count(void)
|
||||
return 2;
|
||||
}
|
||||
|
||||
static int board_pcie_count(void)
|
||||
/*
|
||||
* Override the weak default implementation and return the
|
||||
* last PCIe slot number (max number - 1).
|
||||
*/
|
||||
int board_pcie_last(void)
|
||||
{
|
||||
/*
|
||||
* 405EXr only has one EMAC interface, 405EX has two
|
||||
*/
|
||||
if (is_405exr())
|
||||
return 1;
|
||||
return 1 - 1;
|
||||
else
|
||||
return 2;
|
||||
return 2 - 1;
|
||||
}
|
||||
|
||||
int checkboard (void)
|
||||
@ -300,73 +304,6 @@ int pci_pre_init(struct pci_controller * hose )
|
||||
}
|
||||
#endif /* defined(CONFIG_PCI) */
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static struct pci_controller pcie_hose[2] = {{0},{0}};
|
||||
|
||||
void pcie_setup_hoses(int busno)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
int i, bus;
|
||||
int ret = 0;
|
||||
bus = busno;
|
||||
char *env;
|
||||
unsigned int delay;
|
||||
|
||||
for (i = 0; i < board_pcie_count(); i++) {
|
||||
|
||||
if (is_end_point(i))
|
||||
ret = ppc4xx_init_pcie_endport(i);
|
||||
else
|
||||
ret = ppc4xx_init_pcie_rootport(i);
|
||||
if (ret == -ENODEV)
|
||||
continue;
|
||||
if (ret) {
|
||||
printf("PCIE%d: initialization as %s failed\n", i,
|
||||
is_end_point(i) ? "endpoint" : "root-complex");
|
||||
continue;
|
||||
}
|
||||
|
||||
hose = &pcie_hose[i];
|
||||
hose->first_busno = bus;
|
||||
hose->last_busno = bus;
|
||||
hose->current_busno = bus;
|
||||
|
||||
/* setup mem resource */
|
||||
pci_set_region(hose->regions + 0,
|
||||
CONFIG_SYS_PCIE_MEMBASE + i * CONFIG_SYS_PCIE_MEMSIZE,
|
||||
CONFIG_SYS_PCIE_MEMBASE + i * CONFIG_SYS_PCIE_MEMSIZE,
|
||||
CONFIG_SYS_PCIE_MEMSIZE,
|
||||
PCI_REGION_MEM);
|
||||
hose->region_count = 1;
|
||||
pci_register_hose(hose);
|
||||
|
||||
if (is_end_point(i)) {
|
||||
ppc4xx_setup_pcie_endpoint(hose, i);
|
||||
/*
|
||||
* Reson for no scanning is endpoint can not generate
|
||||
* upstream configuration accesses.
|
||||
*/
|
||||
} else {
|
||||
ppc4xx_setup_pcie_rootpoint(hose, i);
|
||||
env = getenv ("pciscandelay");
|
||||
if (env != NULL) {
|
||||
delay = simple_strtoul(env, NULL, 10);
|
||||
if (delay > 5)
|
||||
printf("Warning, expect noticable delay before "
|
||||
"PCIe scan due to 'pciscandelay' value!\n");
|
||||
mdelay(delay * 1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* Config access can only go down stream
|
||||
*/
|
||||
hose->last_busno = pci_hose_scan(hose);
|
||||
bus = hose->last_busno + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_POST)
|
||||
/*
|
||||
* Returns 1 if keys pressed to start the power-on long-running tests
|
||||
|
@ -256,73 +256,6 @@ int pci_pre_init(struct pci_controller * hose )
|
||||
}
|
||||
#endif /* defined(CONFIG_PCI) */
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
static struct pci_controller pcie_hose[2] = {{0},{0}};
|
||||
|
||||
void pcie_setup_hoses(int busno)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
int i, bus;
|
||||
int ret = 0;
|
||||
bus = busno;
|
||||
char *env;
|
||||
unsigned int delay;
|
||||
|
||||
for (i = 0; i < 2; i++) {
|
||||
|
||||
if (is_end_point(i))
|
||||
ret = ppc4xx_init_pcie_endport(i);
|
||||
else
|
||||
ret = ppc4xx_init_pcie_rootport(i);
|
||||
if (ret == -ENODEV)
|
||||
continue;
|
||||
if (ret) {
|
||||
printf("PCIE%d: initialization as %s failed\n", i,
|
||||
is_end_point(i) ? "endpoint" : "root-complex");
|
||||
continue;
|
||||
}
|
||||
|
||||
hose = &pcie_hose[i];
|
||||
hose->first_busno = bus;
|
||||
hose->last_busno = bus;
|
||||
hose->current_busno = bus;
|
||||
|
||||
/* setup mem resource */
|
||||
pci_set_region(hose->regions + 0,
|
||||
CONFIG_SYS_PCIE_MEMBASE + i * CONFIG_SYS_PCIE_MEMSIZE,
|
||||
CONFIG_SYS_PCIE_MEMBASE + i * CONFIG_SYS_PCIE_MEMSIZE,
|
||||
CONFIG_SYS_PCIE_MEMSIZE,
|
||||
PCI_REGION_MEM);
|
||||
hose->region_count = 1;
|
||||
pci_register_hose(hose);
|
||||
|
||||
if (is_end_point(i)) {
|
||||
ppc4xx_setup_pcie_endpoint(hose, i);
|
||||
/*
|
||||
* Reson for no scanning is endpoint can not generate
|
||||
* upstream configuration accesses.
|
||||
*/
|
||||
} else {
|
||||
ppc4xx_setup_pcie_rootpoint(hose, i);
|
||||
env = getenv ("pciscandelay");
|
||||
if (env != NULL) {
|
||||
delay = simple_strtoul(env, NULL, 10);
|
||||
if (delay > 5)
|
||||
printf("Warning, expect noticable delay before "
|
||||
"PCIe scan due to 'pciscandelay' value!\n");
|
||||
mdelay(delay * 1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* Config access can only go down stream
|
||||
*/
|
||||
hose->last_busno = pci_hose_scan(hose);
|
||||
bus = hose->last_busno + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_POST)
|
||||
/*
|
||||
* Returns 1 if keys pressed to start the power-on long-running tests
|
||||
|
@ -679,7 +679,7 @@ int is_pci_host(struct pci_controller *hose)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int yucca_pcie_card_present(int port)
|
||||
int board_pcie_card_present(int port)
|
||||
{
|
||||
u16 reg;
|
||||
|
||||
@ -696,186 +696,55 @@ static int yucca_pcie_card_present(int port)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* For the given slot, set rootpoint mode, send power to the slot,
|
||||
* turn on the green LED and turn off the yellow LED, enable the clock
|
||||
* and turn off reset.
|
||||
*/
|
||||
void yucca_setup_pcie_fpga_rootpoint(int port)
|
||||
{
|
||||
u16 power, clock, green_led, yellow_led, reset_off, rootpoint, endpoint;
|
||||
|
||||
switch(port) {
|
||||
case 0:
|
||||
rootpoint = FPGA_REG1C_PE0_ROOTPOINT;
|
||||
endpoint = 0;
|
||||
power = FPGA_REG1A_PE0_PWRON;
|
||||
green_led = FPGA_REG1A_PE0_GLED;
|
||||
clock = FPGA_REG1A_PE0_REFCLK_ENABLE;
|
||||
yellow_led = FPGA_REG1A_PE0_YLED;
|
||||
reset_off = FPGA_REG1C_PE0_PERST;
|
||||
break;
|
||||
case 1:
|
||||
rootpoint = 0;
|
||||
endpoint = FPGA_REG1C_PE1_ENDPOINT;
|
||||
power = FPGA_REG1A_PE1_PWRON;
|
||||
green_led = FPGA_REG1A_PE1_GLED;
|
||||
clock = FPGA_REG1A_PE1_REFCLK_ENABLE;
|
||||
yellow_led = FPGA_REG1A_PE1_YLED;
|
||||
reset_off = FPGA_REG1C_PE1_PERST;
|
||||
break;
|
||||
case 2:
|
||||
rootpoint = 0;
|
||||
endpoint = FPGA_REG1C_PE2_ENDPOINT;
|
||||
power = FPGA_REG1A_PE2_PWRON;
|
||||
green_led = FPGA_REG1A_PE2_GLED;
|
||||
clock = FPGA_REG1A_PE2_REFCLK_ENABLE;
|
||||
yellow_led = FPGA_REG1A_PE2_YLED;
|
||||
reset_off = FPGA_REG1C_PE2_PERST;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
out_be16((u16 *)FPGA_REG1A,
|
||||
~(power | clock | green_led) &
|
||||
(yellow_led | in_be16((u16 *)FPGA_REG1A)));
|
||||
|
||||
out_be16((u16 *)FPGA_REG1C,
|
||||
~(endpoint | reset_off) &
|
||||
(rootpoint | in_be16((u16 *)FPGA_REG1C)));
|
||||
/*
|
||||
* Leave device in reset for a while after powering on the
|
||||
* slot to give it a chance to initialize.
|
||||
*/
|
||||
udelay(250 * 1000);
|
||||
|
||||
out_be16((u16 *)FPGA_REG1C, reset_off | in_be16((u16 *)FPGA_REG1C));
|
||||
}
|
||||
/*
|
||||
* For the given slot, set endpoint mode, send power to the slot,
|
||||
* turn on the green LED and turn off the yellow LED, enable the clock
|
||||
* .In end point mode reset bit is read only.
|
||||
* turn on the green LED and turn off the yellow LED, enable the
|
||||
* clock. In end point mode reset bit is read only.
|
||||
*/
|
||||
void yucca_setup_pcie_fpga_endpoint(int port)
|
||||
void board_pcie_setup_port(int port, int rootpoint)
|
||||
{
|
||||
u16 power, clock, green_led, yellow_led, reset_off, rootpoint, endpoint;
|
||||
u16 power, clock, green_led, yellow_led,
|
||||
reset_off, rp, ep;
|
||||
|
||||
switch(port) {
|
||||
switch (port) {
|
||||
case 0:
|
||||
rootpoint = FPGA_REG1C_PE0_ROOTPOINT;
|
||||
endpoint = 0;
|
||||
power = FPGA_REG1A_PE0_PWRON;
|
||||
green_led = FPGA_REG1A_PE0_GLED;
|
||||
clock = FPGA_REG1A_PE0_REFCLK_ENABLE;
|
||||
yellow_led = FPGA_REG1A_PE0_YLED;
|
||||
reset_off = FPGA_REG1C_PE0_PERST;
|
||||
rp = FPGA_REG1C_PE0_ROOTPOINT;
|
||||
ep = 0;
|
||||
break;
|
||||
case 1:
|
||||
rootpoint = 0;
|
||||
endpoint = FPGA_REG1C_PE1_ENDPOINT;
|
||||
power = FPGA_REG1A_PE1_PWRON;
|
||||
green_led = FPGA_REG1A_PE1_GLED;
|
||||
clock = FPGA_REG1A_PE1_REFCLK_ENABLE;
|
||||
yellow_led = FPGA_REG1A_PE1_YLED;
|
||||
reset_off = FPGA_REG1C_PE1_PERST;
|
||||
rp = 0;
|
||||
ep = FPGA_REG1C_PE1_ENDPOINT;
|
||||
break;
|
||||
case 2:
|
||||
rootpoint = 0;
|
||||
endpoint = FPGA_REG1C_PE2_ENDPOINT;
|
||||
power = FPGA_REG1A_PE2_PWRON;
|
||||
green_led = FPGA_REG1A_PE2_GLED;
|
||||
clock = FPGA_REG1A_PE2_REFCLK_ENABLE;
|
||||
yellow_led = FPGA_REG1A_PE2_YLED;
|
||||
reset_off = FPGA_REG1C_PE2_PERST;
|
||||
rp = 0;
|
||||
ep = FPGA_REG1C_PE2_ENDPOINT;
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
out_be16((u16 *)FPGA_REG1A,
|
||||
~(power | clock | green_led) &
|
||||
power = FPGA_REG1A_PWRON_ENCODE(port);
|
||||
green_led = FPGA_REG1A_GLED_ENCODE(port);
|
||||
clock = FPGA_REG1A_REFCLK_ENCODE(port);
|
||||
yellow_led = FPGA_REG1A_YLED_ENCODE(port);
|
||||
reset_off = FPGA_REG1C_PERST_ENCODE(port);
|
||||
|
||||
out_be16((u16 *)FPGA_REG1A, ~(power | clock | green_led) &
|
||||
(yellow_led | in_be16((u16 *)FPGA_REG1A)));
|
||||
|
||||
out_be16((u16 *)FPGA_REG1C,
|
||||
~(rootpoint | reset_off) &
|
||||
(endpoint | in_be16((u16 *)FPGA_REG1C)));
|
||||
}
|
||||
out_be16((u16 *)FPGA_REG1C, ~(ep | reset_off) &
|
||||
(rp | in_be16((u16 *)FPGA_REG1C)));
|
||||
|
||||
static struct pci_controller pcie_hose[3] = {{0},{0},{0}};
|
||||
if (rootpoint) {
|
||||
/*
|
||||
* Leave device in reset for a while after powering on the
|
||||
* slot to give it a chance to initialize.
|
||||
*/
|
||||
udelay(250 * 1000);
|
||||
|
||||
void pcie_setup_hoses(int busno)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
int i, bus;
|
||||
int ret = 0;
|
||||
char *env;
|
||||
unsigned int delay;
|
||||
|
||||
/*
|
||||
* assume we're called after the PCIX hose is initialized, which takes
|
||||
* bus ID 0 and therefore start numbering PCIe's from 1.
|
||||
*/
|
||||
bus = busno;
|
||||
for (i = 0; i <= 2; i++) {
|
||||
/* Check for yucca card presence */
|
||||
if (!yucca_pcie_card_present(i))
|
||||
continue;
|
||||
|
||||
if (is_end_point(i)) {
|
||||
yucca_setup_pcie_fpga_endpoint(i);
|
||||
ret = ppc4xx_init_pcie_endport(i);
|
||||
} else {
|
||||
yucca_setup_pcie_fpga_rootpoint(i);
|
||||
ret = ppc4xx_init_pcie_rootport(i);
|
||||
}
|
||||
if (ret == -ENODEV)
|
||||
continue;
|
||||
if (ret) {
|
||||
printf("PCIE%d: initialization as %s failed\n", i,
|
||||
is_end_point(i) ? "endpoint" : "root-complex");
|
||||
continue;
|
||||
}
|
||||
|
||||
hose = &pcie_hose[i];
|
||||
hose->first_busno = bus;
|
||||
hose->last_busno = bus;
|
||||
hose->current_busno = bus;
|
||||
|
||||
/* setup mem resource */
|
||||
pci_set_region(hose->regions + 0,
|
||||
CONFIG_SYS_PCIE_MEMBASE + i * CONFIG_SYS_PCIE_MEMSIZE,
|
||||
CONFIG_SYS_PCIE_MEMBASE + i * CONFIG_SYS_PCIE_MEMSIZE,
|
||||
CONFIG_SYS_PCIE_MEMSIZE,
|
||||
PCI_REGION_MEM);
|
||||
hose->region_count = 1;
|
||||
pci_register_hose(hose);
|
||||
|
||||
if (is_end_point(i)) {
|
||||
ppc4xx_setup_pcie_endpoint(hose, i);
|
||||
/*
|
||||
* Reson for no scanning is endpoint can not generate
|
||||
* upstream configuration accesses.
|
||||
*/
|
||||
} else {
|
||||
ppc4xx_setup_pcie_rootpoint(hose, i);
|
||||
env = getenv("pciscandelay");
|
||||
if (env != NULL) {
|
||||
delay = simple_strtoul(env, NULL, 10);
|
||||
if (delay > 5)
|
||||
printf("Warning, expect noticable delay before "
|
||||
"PCIe scan due to 'pciscandelay' value!\n");
|
||||
mdelay(delay * 1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* Config access can only go down stream
|
||||
*/
|
||||
hose->last_busno = pci_hose_scan(hose);
|
||||
bus = hose->last_busno + 1;
|
||||
}
|
||||
out_be16((u16 *)FPGA_REG1C,
|
||||
reset_off | in_be16((u16 *)FPGA_REG1C));
|
||||
}
|
||||
}
|
||||
#endif /* defined(CONFIG_PCI) */
|
||||
|
@ -48,6 +48,129 @@ enum {
|
||||
LNKW_X8 = 0x8
|
||||
};
|
||||
|
||||
#if 1 // test-only
|
||||
int board_pcie_first(void);
|
||||
int board_pcie_last(void);
|
||||
static struct pci_controller pcie_hose[CONFIG_SYS_PCIE_NR_PORTS];
|
||||
|
||||
/*
|
||||
* Per default, all cards are present, so we need to check if the
|
||||
* link comes up.
|
||||
*/
|
||||
int __board_pcie_card_present(int port)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
int board_pcie_card_present(int port)
|
||||
__attribute__((weak, alias("__board_pcie_card_present")));
|
||||
|
||||
/*
|
||||
* Some boards have runtime detection of the first and last PCIe
|
||||
* slot used, so let's provide weak default functions for the
|
||||
* common version.
|
||||
*/
|
||||
int __board_pcie_first(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int board_pcie_first(void)
|
||||
__attribute__((weak, alias("__board_pcie_first")));
|
||||
|
||||
int __board_pcie_last(void)
|
||||
{
|
||||
return CONFIG_SYS_PCIE_NR_PORTS - 1;
|
||||
}
|
||||
int board_pcie_last(void)
|
||||
__attribute__((weak, alias("__board_pcie_last")));
|
||||
|
||||
void __board_pcie_setup_port(int port, int rootpoint)
|
||||
{
|
||||
/* noting in this weak default implementation */
|
||||
}
|
||||
void board_pcie_setup_port(int port, int rootpoint)
|
||||
__attribute__((weak, alias("__board_pcie_setup_port")));
|
||||
|
||||
void pcie_setup_hoses(int busno)
|
||||
{
|
||||
struct pci_controller *hose;
|
||||
int i, bus;
|
||||
int ret = 0;
|
||||
char *env;
|
||||
unsigned int delay;
|
||||
int first = board_pcie_first();
|
||||
int last = board_pcie_last();
|
||||
|
||||
/*
|
||||
* Assume we're called after the PCI(X) hose(s) are initialized,
|
||||
* which takes bus ID 0... and therefore start numbering PCIe's
|
||||
* from the next number.
|
||||
*/
|
||||
bus = busno;
|
||||
|
||||
for (i = first; i <= last; i++) {
|
||||
/*
|
||||
* Some boards (e.g. Katmai) can detects via hardware
|
||||
* if a PCIe card is plugged, so let's check this.
|
||||
*/
|
||||
if (!board_pcie_card_present(i))
|
||||
continue;
|
||||
|
||||
if (is_end_point(i)) {
|
||||
board_pcie_setup_port(i, 0);
|
||||
ret = ppc4xx_init_pcie_endport(i);
|
||||
} else {
|
||||
board_pcie_setup_port(i, 1);
|
||||
ret = ppc4xx_init_pcie_rootport(i);
|
||||
}
|
||||
if (ret == -ENODEV)
|
||||
continue;
|
||||
if (ret) {
|
||||
printf("PCIE%d: initialization as %s failed\n", i,
|
||||
is_end_point(i) ? "endpoint" : "root-complex");
|
||||
continue;
|
||||
}
|
||||
|
||||
hose = &pcie_hose[i];
|
||||
hose->first_busno = bus;
|
||||
hose->last_busno = bus;
|
||||
hose->current_busno = bus;
|
||||
|
||||
/* setup mem resource */
|
||||
pci_set_region(hose->regions + 0,
|
||||
CONFIG_SYS_PCIE_MEMBASE + i * CONFIG_SYS_PCIE_MEMSIZE,
|
||||
CONFIG_SYS_PCIE_MEMBASE + i * CONFIG_SYS_PCIE_MEMSIZE,
|
||||
CONFIG_SYS_PCIE_MEMSIZE,
|
||||
PCI_REGION_MEM);
|
||||
hose->region_count = 1;
|
||||
pci_register_hose(hose);
|
||||
|
||||
if (is_end_point(i)) {
|
||||
ppc4xx_setup_pcie_endpoint(hose, i);
|
||||
/*
|
||||
* Reson for no scanning is endpoint can not generate
|
||||
* upstream configuration accesses.
|
||||
*/
|
||||
} else {
|
||||
ppc4xx_setup_pcie_rootpoint(hose, i);
|
||||
env = getenv ("pciscandelay");
|
||||
if (env != NULL) {
|
||||
delay = simple_strtoul(env, NULL, 10);
|
||||
if (delay > 5)
|
||||
printf("Warning, expect noticable delay before "
|
||||
"PCIe scan due to 'pciscandelay' value!\n");
|
||||
mdelay(delay * 1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* Config access can only go down stream
|
||||
*/
|
||||
hose->last_busno = pci_hose_scan(hose);
|
||||
bus = hose->last_busno + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int validate_endpoint(struct pci_controller *hose)
|
||||
{
|
||||
if (hose->cfg_data == (u8 *)CONFIG_SYS_PCIE0_CFGBASE)
|
||||
|
@ -389,6 +389,11 @@
|
||||
#define FPGA_REG1A_PE_SELSOURCE_0 0x0002
|
||||
#define FPGA_REG1A_PE_SELSOURCE_1 0x0001
|
||||
|
||||
#define FPGA_REG1A_GLED_ENCODE(n) (FPGA_REG1A_PE0_GLED >> (n))
|
||||
#define FPGA_REG1A_YLED_ENCODE(n) (FPGA_REG1A_PE0_YLED >> (n))
|
||||
#define FPGA_REG1A_PWRON_ENCODE(n) (FPGA_REG1A_PE0_PWRON >> (n))
|
||||
#define FPGA_REG1A_REFCLK_ENCODE(n) (FPGA_REG1A_PE0_REFCLK_ENABLE >> (n))
|
||||
|
||||
/*----------------------------------------------------------------------------+
|
||||
| PCIe Miscellaneous
|
||||
+----------------------------------------------------------------------------*/
|
||||
@ -407,6 +412,9 @@
|
||||
#define FPGA_REG1C_PE1_PERST 0x0008
|
||||
#define FPGA_REG1C_PE2_PERST 0x0004
|
||||
|
||||
#define FPGA_REG1C_ROOTPOINT_ENCODE(n) (FPGA_REG1C_PE0_ROOTPOINT >> (n))
|
||||
#define FPGA_REG1C_PERST_ENCODE(n) (FPGA_REG1C_PE0_PERST >> (n))
|
||||
|
||||
/*----------------------------------------------------------------------------+
|
||||
| Defines
|
||||
+----------------------------------------------------------------------------*/
|
||||
|
Loading…
Reference in New Issue
Block a user