[U-Boot] [PATCH 1/1] ppc/85xx/pci: fsl_pci_init: pcie agent mode support

Originally written by Jason Jin and Mingkai Hu for mpc8536.
When QorIQ based board is configured as a PCIe agent, then unlock the config and init a 4K inbound memory window; so that a PCIe host can request it.
* Supported in fsl_pci_init_port() after adding pcie_ep as a param * Revamped copyright in drivers/pci/fsl_pci_init.c * Mods in 85xx based board specific pci init after this change
Signed-off-by: Vivek Mahajan vivek.mahajan@freescale.com --- board/freescale/mpc8572ds/mpc8572ds.c | 6 +++--- board/freescale/p1_p2_rdb/pci.c | 4 ++-- board/freescale/p2020ds/p2020ds.c | 6 +++--- board/sbc8548/sbc8548.c | 4 ++-- drivers/pci/fsl_pci_init.c | 18 ++++++++++++++++-- include/asm-ppc/fsl_pci.h | 3 ++- 6 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/board/freescale/mpc8572ds/mpc8572ds.c b/board/freescale/mpc8572ds/mpc8572ds.c index 933dd12..2b32234 100644 --- a/board/freescale/mpc8572ds/mpc8572ds.c +++ b/board/freescale/mpc8572ds/mpc8572ds.c @@ -199,7 +199,7 @@ void pci_init_board(void) pcie_ep ? "End Point" : "Root Complex", pci_info[num].regs); first_free_busno = fsl_pci_init_port(&pci_info[num++], - &pcie3_hose, first_free_busno); + &pcie3_hose, first_free_busno, pcie_ep); /* * Activate ULI1575 legacy chip by performing a fake * memory access. Needed to make ULI RTC work. @@ -231,7 +231,7 @@ void pci_init_board(void) pcie_ep ? "End Point" : "Root Complex", pci_info[num].regs); first_free_busno = fsl_pci_init_port(&pci_info[num++], - &pcie2_hose, first_free_busno); + &pcie2_hose, first_free_busno, pcie_ep); } else { printf (" PCIE2: disabled\n"); } @@ -251,7 +251,7 @@ void pci_init_board(void) pcie_ep ? "End Point" : "Root Complex", pci_info[num].regs); first_free_busno = fsl_pci_init_port(&pci_info[num++], - &pcie1_hose, first_free_busno); + &pcie1_hose, first_free_busno, pcie_ep); } else { printf (" PCIE1: disabled\n"); } diff --git a/board/freescale/p1_p2_rdb/pci.c b/board/freescale/p1_p2_rdb/pci.c index 4c08f9e..7736596 100644 --- a/board/freescale/p1_p2_rdb/pci.c +++ b/board/freescale/p1_p2_rdb/pci.c @@ -71,7 +71,7 @@ void pci_init_board(void) pcie_ep ? "End Point" : "Root Complex", pci_info[num].regs); first_free_busno = fsl_pci_init_port(&pci_info[num++], - &pcie2_hose, first_free_busno); + &pcie2_hose, first_free_busno, pcie_ep); } else { printf (" PCIE2: disabled\n"); } @@ -90,7 +90,7 @@ void pci_init_board(void) pcie_ep ? "End Point" : "Root Complex", pci_info[num].regs); first_free_busno = fsl_pci_init_port(&pci_info[num++], - &pcie1_hose, first_free_busno); + &pcie1_hose, first_free_busno, pcie_ep); } else { printf (" PCIE1: disabled\n"); } diff --git a/board/freescale/p2020ds/p2020ds.c b/board/freescale/p2020ds/p2020ds.c index e38c014..9878fba 100644 --- a/board/freescale/p2020ds/p2020ds.c +++ b/board/freescale/p2020ds/p2020ds.c @@ -227,7 +227,7 @@ void pci_init_board(void) pcie_ep ? "End Point" : "Root Complex", pci_info[num].regs); first_free_busno = fsl_pci_init_port(&pci_info[num++], - &pcie2_hose, first_free_busno); + &pcie2_hose, first_free_busno, pcie_ep);
/* * The workaround doesn't work on p2020 because the location @@ -267,7 +267,7 @@ void pci_init_board(void) pcie_ep ? "End Point" : "Root Complex", pci_info[num].regs); first_free_busno = fsl_pci_init_port(&pci_info[num++], - &pcie3_hose, first_free_busno); + &pcie3_hose, first_free_busno, pcie_ep); } else { printf(" PCIE3: disabled\n"); } @@ -286,7 +286,7 @@ void pci_init_board(void) pcie_ep ? "End Point" : "Root Complex", pci_info[num].regs); first_free_busno = fsl_pci_init_port(&pci_info[num++], - &pcie1_hose, first_free_busno); + &pcie1_hose, first_free_busno, pcie_ep); } else { printf(" PCIE1: disabled\n"); } diff --git a/board/sbc8548/sbc8548.c b/board/sbc8548/sbc8548.c index 194f6ab..5e3e176 100644 --- a/board/sbc8548/sbc8548.c +++ b/board/sbc8548/sbc8548.c @@ -359,7 +359,7 @@ pci_init_board(void)
SET_STD_PCI_INFO(pci_info[num], 1); first_free_busno = fsl_pci_init_port(&pci_info[num++], - &pci1_hose, first_free_busno); + &pci1_hose, first_free_busno, 0); } else { printf (" PCI: disabled\n"); } @@ -378,7 +378,7 @@ pci_init_board(void) SET_STD_PCIE_INFO(pci_info[num], 1); printf (" PCIE at base address %lx\n", pci_info[num].regs); first_free_busno = fsl_pci_init_port(&pci_info[num++], - &pcie1_hose, first_free_busno); + &pcie1_hose, first_free_busno, 0); } else { printf (" PCIE: disabled\n"); } diff --git a/drivers/pci/fsl_pci_init.c b/drivers/pci/fsl_pci_init.c index 87944bf..289878a 100644 --- a/drivers/pci/fsl_pci_init.c +++ b/drivers/pci/fsl_pci_init.c @@ -1,5 +1,5 @@ /* - * Copyright 2007 Freescale Semiconductor, Inc. + * Copyright 2007-2009 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 @@ -413,13 +413,27 @@ void fsl_pci_init(struct pci_controller *hose, u32 cfg_addr, u32 cfg_data) }
int fsl_pci_init_port(struct fsl_pci_info *pci_info, - struct pci_controller *hose, int busno) + struct pci_controller *hose, int busno, int pcie_ep) { volatile ccsr_fsl_pci_t *pci; struct pci_region *r;
pci = (ccsr_fsl_pci_t *) pci_info->regs;
+ if (pcie_ep) { + pit_t *pi = &pci->pit[2]; + + pci_setup_indirect(hose, (u32) &pci->cfg_addr, + (u32) &pci->cfg_data); + out_be32(&pi->pitar, 0); + out_be32(&pi->piwbar, 0); + out_be32(&pi->piwar, PIWAR_EN | PIWAR_LOCAL | + PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_IWS_4K); + + fsl_pci_config_unlock(hose); + return 0; + } + /* on non-PCIe controllers we don't have pme_msg_det so this code * should do nothing since the read will return 0 */ diff --git a/include/asm-ppc/fsl_pci.h b/include/asm-ppc/fsl_pci.h index 2790da7..6b0c89b 100644 --- a/include/asm-ppc/fsl_pci.h +++ b/include/asm-ppc/fsl_pci.h @@ -62,6 +62,7 @@ typedef struct pci_inbound_window { #define PIWAR_LOCAL 0x00f00000 #define PIWAR_READ_SNOOP 0x00050000 #define PIWAR_WRITE_SNOOP 0x00005000 +#define PIWAR_IWS_4K 0x0000000b u32 res2[3]; } pit_t;
@@ -171,7 +172,7 @@ struct fsl_pci_info { };
int fsl_pci_init_port(struct fsl_pci_info *pci_info, - struct pci_controller *hose, int busno); + struct pci_controller *hose, int busno, int pcie_ep);
#define SET_STD_PCI_INFO(x, num) \ { \

On Oct 27, 2009, at 1:48 AM, Vivek Mahajan wrote:
Originally written by Jason Jin and Mingkai Hu for mpc8536.
When QorIQ based board is configured as a PCIe agent, then unlock the config and init a 4K inbound memory window; so that a PCIe host can request it.
- Supported in fsl_pci_init_port() after adding pcie_ep as a param
- Revamped copyright in drivers/pci/fsl_pci_init.c
- Mods in 85xx based board specific pci init after this change
Signed-off-by: Vivek Mahajan vivek.mahajan@freescale.com
board/freescale/mpc8572ds/mpc8572ds.c | 6 +++--- board/freescale/p1_p2_rdb/pci.c | 4 ++-- board/freescale/p2020ds/p2020ds.c | 6 +++--- board/sbc8548/sbc8548.c | 4 ++-- drivers/pci/fsl_pci_init.c | 18 ++++++++++++++++-- include/asm-ppc/fsl_pci.h | 3 ++- 6 files changed, 28 insertions(+), 13 deletions(-)
applied to 85xx
- k

Hi Vivek, Thanks for this change, we'll migrate our XES boards to use it in the near future.
On Tue, 2009-10-27 at 12:18 +0530, Vivek Mahajan wrote:
Originally written by Jason Jin and Mingkai Hu for mpc8536.
When QorIQ based board is configured as a PCIe agent, then unlock the config and init a 4K inbound memory window; so that a PCIe host can request it.
I'd replace "then unlock the config" with "unlock/enable inbound PCI configuration cycles" and "host can request it" with "host can access the PCIe agents SDRAM at address 0x0"
- Supported in fsl_pci_init_port() after adding pcie_ep as a param
- Revamped copyright in drivers/pci/fsl_pci_init.c
- Mods in 85xx based board specific pci init after this change
I personally think these bullets points are a bit overly verbose.
<snip>
- if (pcie_ep) {
pit_t *pi = &pci->pit[2];
A "volatile" needs to be added above to prevent compiler warnings.
pci_setup_indirect(hose, (u32) &pci->cfg_addr,
(u32) &pci->cfg_data);
out_be32(&pi->pitar, 0);
out_be32(&pi->piwbar, 0);
out_be32(&pi->piwar, PIWAR_EN | PIWAR_LOCAL |
PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_IWS_4K);
fsl_pci_config_unlock(hose);
return 0;
- }
Best, Peter

On Oct 27, 2009, at 9:30 AM, Peter Tyser wrote:
Hi Vivek, Thanks for this change, we'll migrate our XES boards to use it in the near future.
On Tue, 2009-10-27 at 12:18 +0530, Vivek Mahajan wrote:
Originally written by Jason Jin and Mingkai Hu for mpc8536.
When QorIQ based board is configured as a PCIe agent, then unlock the config and init a 4K inbound memory window; so that a PCIe host can request it.
I'd replace "then unlock the config" with "unlock/enable inbound PCI configuration cycles" and "host can request it" with "host can access the PCIe agents SDRAM at address 0x0"
updated the commit msg with these changes.
- Supported in fsl_pci_init_port() after adding pcie_ep as a param
- Revamped copyright in drivers/pci/fsl_pci_init.c
- Mods in 85xx based board specific pci init after this change
I personally think these bullets points are a bit overly verbose.
Its a commit message, verbosity isn't bad. ;)
<snip>
- if (pcie_ep) {
pit_t *pi = &pci->pit[2];
A "volatile" needs to be added above to prevent compiler warnings.
I fixed it when I committed.
pci_setup_indirect(hose, (u32) &pci->cfg_addr,
(u32) &pci->cfg_data);
out_be32(&pi->pitar, 0);
out_be32(&pi->piwbar, 0);
out_be32(&pi->piwar, PIWAR_EN | PIWAR_LOCAL |
PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_IWS_4K);
fsl_pci_config_unlock(hose);
return 0;
- }
Best, Peter

I'd replace "then unlock the config" with "unlock/enable inbound PCI configuration cycles" and "host can request it" with "host can access the PCIe agents SDRAM at address 0x0"
updated the commit msg with these changes.
<snip>
A "volatile" needs to be added above to prevent compiler warnings.
I fixed it when I committed.
Great! I just sent a follow-up patch to resolve the compiler warning, please ignore it.
Peter

Vivek Mahajan <vivek.mahajan <at> freescale.com> writes:
- Supported in fsl_pci_init_port() after adding pcie_ep as a param
- Mods in 85xx based board specific pci init after this change
Signed-off-by: Vivek Mahajan <vivek.mahajan <at> freescale.com>
board/freescale/mpc8572ds/mpc8572ds.c | 6 +++--- drivers/pci/fsl_pci_init.c | 18 ++++++++++++++++--
+++ b/board/freescale/mpc8572ds/mpc8572ds.c @@ -199,7 +199,7 @@ void pci_init_board(void) first_free_busno = fsl_pci_init_port(&pci_info[num++],
&pcie3_hose, first_free_busno);
&pcie3_hose, first_free_busno, pcie_ep);
Why pass this new parameter when the common code already determines it from the PI field?
...
+++ b/drivers/pci/fsl_pci_init.c
int fsl_pci_init_port(struct fsl_pci_info *pci_info,
struct pci_controller *hose, int busno)
struct pci_controller *hose, int busno, int pcie_ep)
- if (pcie_ep) {
pit_t *pi = &pci->pit[2];
pci_setup_indirect(hose, (u32) &pci->cfg_addr,
out_be32(&pi->pitar, 0);
out_be32(&pi->piwbar, 0);
out_be32(&pi->piwar, PIWAR_EN | PIWAR_LOCAL |
PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP | PIWAR_IWS_4K);
Why is this the right size for every board that calls this function?
fsl_pci_config_unlock(hose);
return 0;
This is wrong. It must return the first free busno.
But it shouldn't return here, because some of the initialization in fsl_pci_init() is still needed for an end-point.
And a busno needs to be allocated to an end-point for config transactions.
-EdS

[mailto:u-boot-bounces@lists.denx.de] On Behalf Of Ed Swarthout Sent: Thursday, October 29, 2009 12:59 PM
+++ b/board/freescale/mpc8572ds/mpc8572ds.c @@ -199,7 +199,7 @@ void pci_init_board(void) first_free_busno = fsl_pci_init_port(&pci_info[num++],
&pcie3_hose, first_free_busno);
&pcie3_hose, first_free_busno, pcie_ep);
Why pass this new parameter when the common code already determines it from the PI field?
pcie_ep does not represent the regular PCIe EP; rather this is a special case when the PCIe controller on the 85xx based board is configured as a PCIe EP.
...
+++ b/drivers/pci/fsl_pci_init.c
int fsl_pci_init_port(struct fsl_pci_info *pci_info,
struct pci_controller *hose, int busno)
struct pci_controller *hose, int busno,
int pcie_ep)
- if (pcie_ep) {
pit_t *pi = &pci->pit[2];
pci_setup_indirect(hose, (u32) &pci->cfg_addr,
out_be32(&pi->pitar, 0);
out_be32(&pi->piwbar, 0);
out_be32(&pi->piwar, PIWAR_EN | PIWAR_LOCAL |
PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP |
PIWAR_IWS_4K);
Why is this the right size for every board that calls this function?
Inbound memory window does support multiple sizes and we have to feed some size in it. May be we can have a board specifc config to drive this window size.
fsl_pci_config_unlock(hose);
return 0;
This is wrong. It must return the first free busno.
Correct.
But it shouldn't return here, because some of the initialization in fsl_pci_init() is still needed for an end-point.
And a busno needs to be allocated to an end-point for config transactions.
Isn't PCIe host bridge init will take care of allocation of bus nos for the config transaction to succceed.
-EdS
Thanks, Vivek
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
participants (5)
-
Ed Swarthout
-
Kumar Gala
-
Mahajan Vivek-B08308
-
Peter Tyser
-
Vivek Mahajan