summaryrefslogtreecommitdiff
path: root/drivers/pci/controller/mobiveil/pcie-mobiveil.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/controller/mobiveil/pcie-mobiveil.c')
-rw-r--r--drivers/pci/controller/mobiveil/pcie-mobiveil.c101
1 files changed, 92 insertions, 9 deletions
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.c b/drivers/pci/controller/mobiveil/pcie-mobiveil.c
index 62ecbaeb0a60..1570464360ed 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.c
@@ -170,18 +170,12 @@ void program_ib_windows(struct mobiveil_pcie *pcie, int win_num,
/*
* routine to program the outbound windows
*/
-void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
- u64 cpu_addr, u64 pci_addr, u32 type, u64 size)
+void __program_ob_windows(struct mobiveil_pcie *pcie, u8 func_no, int win_num,
+ u64 cpu_addr, u64 pci_addr, u32 type, u64 size)
{
u32 value;
u64 size64 = ~(size - 1);
- if (win_num >= pcie->apio_wins) {
- dev_err(&pcie->pdev->dev,
- "ERROR: max outbound windows reached !\n");
- return;
- }
-
/*
* program Enable Bit to 1, Type Bit to (00) base 2, AXI Window Size Bit
* to 4 KB in PAB_AXI_AMAP_CTRL register
@@ -195,6 +189,7 @@ void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
mobiveil_csr_writel(pcie, upper_32_bits(size64),
PAB_EXT_AXI_AMAP_SIZE(win_num));
+ mobiveil_csr_writel(pcie, func_no, PAB_AXI_AMAP_PCI_HDR_PARAM(win_num));
/*
* program AXI window base with appropriate value in
* PAB_AXI_AMAP_AXI_WIN0 register
@@ -209,10 +204,98 @@ void program_ob_windows(struct mobiveil_pcie *pcie, int win_num,
PAB_AXI_AMAP_PEX_WIN_L(win_num));
mobiveil_csr_writel(pcie, upper_32_bits(pci_addr),
PAB_AXI_AMAP_PEX_WIN_H(win_num));
+}
+
+void program_ob_windows(struct mobiveil_pcie *pcie, int win_num, u64 cpu_addr,
+ u64 pci_addr, u32 type, u64 size)
+{
+ if (win_num >= pcie->apio_wins) {
+ dev_err(&pcie->pdev->dev,
+ "ERROR: max outbound windows reached !\n");
+ return;
+ }
+
+ __program_ob_windows(pcie, 0, win_num, cpu_addr,
+ pci_addr, type, size);
pcie->ob_wins_configured++;
}
+void program_ob_windows_ep(struct mobiveil_pcie *pcie, u8 func_no, int win_num,
+ u64 cpu_addr, u64 pci_addr, u32 type, u64 size)
+{
+ if (size & (size - 1))
+ size = 1 << (1 + ilog2(size));
+
+ __program_ob_windows(pcie, func_no, win_num, cpu_addr,
+ pci_addr, type, size);
+}
+
+void program_ib_windows_ep(struct mobiveil_pcie *pcie, u8 func_no,
+ int bar, u64 phys)
+{
+ mobiveil_csr_writel(pcie, upper_32_bits(phys),
+ PAB_EXT_PEX_BAR_AMAP(func_no, bar));
+ mobiveil_csr_writel(pcie, lower_32_bits(phys) | PEX_BAR_AMAP_EN,
+ PAB_PEX_BAR_AMAP(func_no, bar));
+}
+
+void mobiveil_pcie_disable_ib_win_ep(struct mobiveil_pcie *pcie,
+ u8 func_no, u8 bar)
+{
+ u32 val;
+
+ val = mobiveil_csr_readl(pcie, PAB_PEX_BAR_AMAP(func_no, bar));
+ val &= ~(1 << 0);
+ mobiveil_csr_writel(pcie, val, PAB_PEX_BAR_AMAP(func_no, bar));
+}
+
+void mobiveil_pcie_disable_ob_win(struct mobiveil_pcie *pcie, int win_num)
+{
+ u32 val;
+
+ val = mobiveil_csr_readl(pcie, PAB_AXI_AMAP_CTRL(win_num));
+ val &= ~(1 << WIN_ENABLE_SHIFT);
+ mobiveil_csr_writel(pcie, val, PAB_AXI_AMAP_CTRL(win_num));
+}
+
+void mobiveil_pcie_enable_bridge_pio(struct mobiveil_pcie *pcie)
+{
+ u32 val;
+
+ val = mobiveil_csr_readl(pcie, PAB_CTRL);
+ val |= 1 << AMBA_PIO_ENABLE_SHIFT;
+ val |= 1 << PEX_PIO_ENABLE_SHIFT;
+ mobiveil_csr_writel(pcie, val, PAB_CTRL);
+}
+
+void mobiveil_pcie_enable_engine_apio(struct mobiveil_pcie *pcie)
+{
+ u32 val;
+
+ val = mobiveil_csr_readl(pcie, PAB_AXI_PIO_CTRL);
+ val |= APIO_EN_MASK;
+ mobiveil_csr_writel(pcie, val, PAB_AXI_PIO_CTRL);
+}
+
+void mobiveil_pcie_enable_engine_ppio(struct mobiveil_pcie *pcie)
+{
+ u32 val;
+
+ val = mobiveil_csr_readl(pcie, PAB_PEX_PIO_CTRL);
+ val |= 1 << PIO_ENABLE_SHIFT;
+ mobiveil_csr_writel(pcie, val, PAB_PEX_PIO_CTRL);
+}
+
+void mobiveil_pcie_enable_msi_ep(struct mobiveil_pcie *pcie)
+{
+ u32 val;
+
+ val = mobiveil_csr_readl(pcie, PAB_INTP_AMBA_MISC_ENB);
+ val |= PAB_INTP_PAMR;
+ mobiveil_csr_writel(pcie, val, PAB_INTP_AMBA_MISC_ENB);
+}
+
int mobiveil_bringup_link(struct mobiveil_pcie *pcie)
{
int retries;
@@ -225,7 +308,7 @@ int mobiveil_bringup_link(struct mobiveil_pcie *pcie)
usleep_range(LINK_WAIT_MIN, LINK_WAIT_MAX);
}
- dev_err(&pcie->pdev->dev, "link never came up\n");
+ dev_info(&pcie->pdev->dev, "link never came up\n");
return -ETIMEDOUT;
}