mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-21 06:31:31 +00:00
drivers/pci/layerscape: Add EP mode support
The patch will initialize PCIe controller on EP mode 1. Setup bar: bar0 32bit 4K for specific configuration bar1 32bit 8K for MSIX bar2 64bit 4K for descriptor of memory bar4 64bit 1M for DMA memory test 2. Setup iATU: iATU inbound 0-3 to map bar transaction to memory address started at CONFIG_SYS_PCI_EP_MEMORY_BASE iATU outbound 0 to map 4G memory space Signed-off-by: Minghuan Lian <Minghuan.Lian@freescale.com> Reviewed-by: York Sun <yorksun@freescale.com>
This commit is contained in:
parent
ed5b580b38
commit
01cafcedbf
1 changed files with 135 additions and 2 deletions
|
@ -25,6 +25,10 @@
|
|||
#define CONFIG_SYS_PCI_MEMORY_SIZE (2 * 1024 * 1024 * 1024UL) /* 2G */
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SYS_PCI_EP_MEMORY_BASE
|
||||
#define CONFIG_SYS_PCI_EP_MEMORY_BASE CONFIG_SYS_LOAD_ADDR
|
||||
#endif
|
||||
|
||||
/* iATU registers */
|
||||
#define PCIE_ATU_VIEWPORT 0x900
|
||||
#define PCIE_ATU_REGION_INBOUND (0x1 << 31)
|
||||
|
@ -41,6 +45,7 @@
|
|||
#define PCIE_ATU_CR2 0x908
|
||||
#define PCIE_ATU_ENABLE (0x1 << 31)
|
||||
#define PCIE_ATU_BAR_MODE_ENABLE (0x1 << 30)
|
||||
#define PCIE_ATU_BAR_NUM(bar) ((bar) << 8)
|
||||
#define PCIE_ATU_LOWER_BASE 0x90C
|
||||
#define PCIE_ATU_UPPER_BASE 0x910
|
||||
#define PCIE_ATU_LIMIT 0x914
|
||||
|
@ -52,6 +57,7 @@
|
|||
|
||||
/* LUT registers */
|
||||
#define PCIE_LUT_BASE 0x80000
|
||||
#define PCIE_LUT_LCTRL0 0x7F8
|
||||
#define PCIE_LUT_DBG 0x7FC
|
||||
|
||||
#define PCIE_DBI_RO_WR_EN 0x8bc
|
||||
|
@ -65,6 +71,25 @@
|
|||
|
||||
#define PCIE_DBI_SIZE 0x100000 /* 1M */
|
||||
|
||||
#define PCIE_LCTRL0_CFG2_ENABLE (1 << 31)
|
||||
#define PCIE_LCTRL0_VF(vf) ((vf) << 22)
|
||||
#define PCIE_LCTRL0_PF(pf) ((pf) << 16)
|
||||
#define PCIE_LCTRL0_VF_ACTIVE (1 << 21)
|
||||
#define PCIE_LCTRL0_VAL(pf, vf) (PCIE_LCTRL0_PF(pf) | \
|
||||
PCIE_LCTRL0_VF(vf) | \
|
||||
((vf) == 0 ? 0 : PCIE_LCTRL0_VF_ACTIVE) | \
|
||||
PCIE_LCTRL0_CFG2_ENABLE)
|
||||
|
||||
#define PCIE_NO_SRIOV_BAR_BASE 0x1000
|
||||
|
||||
#define PCIE_PF_NUM 2
|
||||
#define PCIE_VF_NUM 64
|
||||
|
||||
#define PCIE_BAR0_SIZE (4 * 1024) /* 4K */
|
||||
#define PCIE_BAR1_SIZE (8 * 1024) /* 8K for MSIX */
|
||||
#define PCIE_BAR2_SIZE (4 * 1024) /* 4K */
|
||||
#define PCIE_BAR4_SIZE (1 * 1024 * 1024) /* 1M */
|
||||
|
||||
struct ls_pcie {
|
||||
int idx;
|
||||
void __iomem *dbi;
|
||||
|
@ -76,6 +101,7 @@ struct ls_pcie {
|
|||
struct ls_pcie_info {
|
||||
unsigned long regs;
|
||||
int pci_num;
|
||||
u64 phys_base;
|
||||
u64 cfg0_phys;
|
||||
u64 cfg0_size;
|
||||
u64 cfg1_phys;
|
||||
|
@ -91,6 +117,7 @@ struct ls_pcie_info {
|
|||
#define SET_LS_PCIE_INFO(x, num) \
|
||||
{ \
|
||||
x.regs = CONFIG_SYS_PCIE##num##_ADDR; \
|
||||
x.phys_base = CONFIG_SYS_PCIE##num##_PHYS_ADDR; \
|
||||
x.cfg0_phys = CONFIG_SYS_PCIE_CFG0_PHYS_OFF + \
|
||||
CONFIG_SYS_PCIE##num##_PHYS_ADDR; \
|
||||
x.cfg0_size = CONFIG_SYS_PCIE_CFG0_SIZE; \
|
||||
|
@ -197,6 +224,18 @@ static void ls_pcie_iatu_outbound_set(struct ls_pcie *pcie, int idx, int type,
|
|||
writel(PCIE_ATU_ENABLE, pcie->dbi + PCIE_ATU_CR2);
|
||||
}
|
||||
|
||||
/* Use bar match mode and MEM type as default */
|
||||
static void ls_pcie_iatu_inbound_set(struct ls_pcie *pcie, int idx,
|
||||
int bar, u64 phys)
|
||||
{
|
||||
writel(PCIE_ATU_REGION_INBOUND | idx, pcie->dbi + PCIE_ATU_VIEWPORT);
|
||||
writel((u32)phys, pcie->dbi + PCIE_ATU_LOWER_TARGET);
|
||||
writel(phys >> 32, pcie->dbi + PCIE_ATU_UPPER_TARGET);
|
||||
writel(PCIE_ATU_TYPE_MEM, pcie->dbi + PCIE_ATU_CR1);
|
||||
writel(PCIE_ATU_ENABLE | PCIE_ATU_BAR_MODE_ENABLE |
|
||||
PCIE_ATU_BAR_NUM(bar), pcie->dbi + PCIE_ATU_CR2);
|
||||
}
|
||||
|
||||
static void ls_pcie_setup_atu(struct ls_pcie *pcie, struct ls_pcie_info *info)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
|
@ -350,6 +389,97 @@ static void ls_pcie_setup_ctrl(struct ls_pcie *pcie,
|
|||
#endif
|
||||
}
|
||||
|
||||
static void ls_pcie_ep_setup_atu(struct ls_pcie *pcie,
|
||||
struct ls_pcie_info *info)
|
||||
{
|
||||
u64 phys = CONFIG_SYS_PCI_EP_MEMORY_BASE;
|
||||
|
||||
/* ATU 0 : INBOUND : map BAR0 */
|
||||
ls_pcie_iatu_inbound_set(pcie, PCIE_ATU_REGION_INDEX0, 0, phys);
|
||||
/* ATU 1 : INBOUND : map BAR1 */
|
||||
phys += PCIE_BAR1_SIZE;
|
||||
ls_pcie_iatu_inbound_set(pcie, PCIE_ATU_REGION_INDEX1, 1, phys);
|
||||
/* ATU 2 : INBOUND : map BAR2 */
|
||||
phys += PCIE_BAR2_SIZE;
|
||||
ls_pcie_iatu_inbound_set(pcie, PCIE_ATU_REGION_INDEX2, 2, phys);
|
||||
/* ATU 3 : INBOUND : map BAR4 */
|
||||
phys = CONFIG_SYS_PCI_EP_MEMORY_BASE + PCIE_BAR4_SIZE;
|
||||
ls_pcie_iatu_inbound_set(pcie, PCIE_ATU_REGION_INDEX3, 4, phys);
|
||||
|
||||
/* ATU 0 : OUTBOUND : map 4G MEM */
|
||||
ls_pcie_iatu_outbound_set(pcie, PCIE_ATU_REGION_INDEX0,
|
||||
PCIE_ATU_TYPE_MEM,
|
||||
info->phys_base,
|
||||
0,
|
||||
4 * 1024 * 1024 * 1024ULL);
|
||||
}
|
||||
|
||||
/* BAR0 and BAR1 are 32bit BAR2 and BAR4 are 64bit */
|
||||
static void ls_pcie_ep_setup_bar(void *bar_base, int bar, u32 size)
|
||||
{
|
||||
if (size < 4 * 1024)
|
||||
return;
|
||||
|
||||
switch (bar) {
|
||||
case 0:
|
||||
writel(size - 1, bar_base + PCI_BASE_ADDRESS_0);
|
||||
break;
|
||||
case 1:
|
||||
writel(size - 1, bar_base + PCI_BASE_ADDRESS_1);
|
||||
break;
|
||||
case 2:
|
||||
writel(size - 1, bar_base + PCI_BASE_ADDRESS_2);
|
||||
writel(0, bar_base + PCI_BASE_ADDRESS_3);
|
||||
break;
|
||||
case 4:
|
||||
writel(size - 1, bar_base + PCI_BASE_ADDRESS_4);
|
||||
writel(0, bar_base + PCI_BASE_ADDRESS_5);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ls_pcie_ep_setup_bars(void *bar_base)
|
||||
{
|
||||
/* BAR0 - 32bit - 4K configuration */
|
||||
ls_pcie_ep_setup_bar(bar_base, 0, PCIE_BAR0_SIZE);
|
||||
/* BAR1 - 32bit - 8K MSIX*/
|
||||
ls_pcie_ep_setup_bar(bar_base, 1, PCIE_BAR1_SIZE);
|
||||
/* BAR2 - 64bit - 4K MEM desciptor */
|
||||
ls_pcie_ep_setup_bar(bar_base, 2, PCIE_BAR2_SIZE);
|
||||
/* BAR4 - 64bit - 1M MEM*/
|
||||
ls_pcie_ep_setup_bar(bar_base, 4, PCIE_BAR4_SIZE);
|
||||
}
|
||||
|
||||
static void ls_pcie_setup_ep(struct ls_pcie *pcie, struct ls_pcie_info *info)
|
||||
{
|
||||
struct pci_controller *hose = &pcie->hose;
|
||||
pci_dev_t dev = PCI_BDF(hose->first_busno, 0, 0);
|
||||
int sriov;
|
||||
|
||||
sriov = pci_hose_find_ext_capability(hose, dev, PCI_EXT_CAP_ID_SRIOV);
|
||||
if (sriov) {
|
||||
int pf, vf;
|
||||
|
||||
for (pf = 0; pf < PCIE_PF_NUM; pf++) {
|
||||
for (vf = 0; vf <= PCIE_VF_NUM; vf++) {
|
||||
writel(PCIE_LCTRL0_VAL(pf, vf),
|
||||
pcie->dbi + PCIE_LUT_BASE +
|
||||
PCIE_LUT_LCTRL0);
|
||||
ls_pcie_ep_setup_bars(pcie->dbi);
|
||||
ls_pcie_ep_setup_atu(pcie, info);
|
||||
}
|
||||
}
|
||||
|
||||
/* Disable CFG2 */
|
||||
writel(0, pcie->dbi + PCIE_LUT_BASE + PCIE_LUT_LCTRL0);
|
||||
} else {
|
||||
ls_pcie_ep_setup_bars(pcie->dbi + PCIE_NO_SRIOV_BAR_BASE);
|
||||
ls_pcie_ep_setup_atu(pcie, info);
|
||||
}
|
||||
}
|
||||
|
||||
int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
|
||||
{
|
||||
struct ls_pcie *pcie;
|
||||
|
@ -426,6 +556,11 @@ int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
|
|||
printf("PCIe%u: %s ", info->pci_num,
|
||||
ep_mode ? "Endpoint" : "Root Complex");
|
||||
|
||||
if (ep_mode)
|
||||
ls_pcie_setup_ep(pcie, info);
|
||||
else
|
||||
ls_pcie_setup_ctrl(pcie, info);
|
||||
|
||||
linkup = ls_pcie_link_up(pcie);
|
||||
|
||||
if (!linkup) {
|
||||
|
@ -443,8 +578,6 @@ int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
|
|||
if (ep_mode)
|
||||
return busno;
|
||||
|
||||
ls_pcie_setup_ctrl(pcie, info);
|
||||
|
||||
pci_register_hose(hose);
|
||||
|
||||
hose->last_busno = pci_hose_scan(hose);
|
||||
|
|
Loading…
Add table
Reference in a new issue