|
@@ -118,6 +118,29 @@ static const struct iproc_pcie_ob_map paxb_ob_map[] = {
|
|
|
},
|
|
|
};
|
|
|
|
|
|
+static const struct iproc_pcie_ob_map paxb_v2_ob_map[] = {
|
|
|
+ {
|
|
|
+ /* OARR0/OMAP0 */
|
|
|
+ .window_sizes = { 128, 256 },
|
|
|
+ .nr_sizes = 2,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ /* OARR1/OMAP1 */
|
|
|
+ .window_sizes = { 128, 256 },
|
|
|
+ .nr_sizes = 2,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ /* OARR2/OMAP2 */
|
|
|
+ .window_sizes = { 128, 256, 512, 1024 },
|
|
|
+ .nr_sizes = 4,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ /* OARR3/OMAP3 */
|
|
|
+ .window_sizes = { 128, 256, 512, 1024 },
|
|
|
+ .nr_sizes = 4,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
/**
|
|
|
* iProc PCIe inbound mapping type
|
|
|
*/
|
|
@@ -156,6 +179,54 @@ struct iproc_pcie_ib_map {
|
|
|
u16 imap_window_offset;
|
|
|
};
|
|
|
|
|
|
+static const struct iproc_pcie_ib_map paxb_v2_ib_map[] = {
|
|
|
+ {
|
|
|
+ /* IARR0/IMAP0 */
|
|
|
+ .type = IPROC_PCIE_IB_MAP_IO,
|
|
|
+ .size_unit = SZ_1K,
|
|
|
+ .region_sizes = { 32 },
|
|
|
+ .nr_sizes = 1,
|
|
|
+ .nr_windows = 8,
|
|
|
+ .imap_addr_offset = 0x40,
|
|
|
+ .imap_window_offset = 0x4,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ /* IARR1/IMAP1 (currently unused) */
|
|
|
+ .type = IPROC_PCIE_IB_MAP_INVALID,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ /* IARR2/IMAP2 */
|
|
|
+ .type = IPROC_PCIE_IB_MAP_MEM,
|
|
|
+ .size_unit = SZ_1M,
|
|
|
+ .region_sizes = { 64, 128, 256, 512, 1024, 2048, 4096, 8192,
|
|
|
+ 16384 },
|
|
|
+ .nr_sizes = 9,
|
|
|
+ .nr_windows = 1,
|
|
|
+ .imap_addr_offset = 0x4,
|
|
|
+ .imap_window_offset = 0x8,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ /* IARR3/IMAP3 */
|
|
|
+ .type = IPROC_PCIE_IB_MAP_MEM,
|
|
|
+ .size_unit = SZ_1G,
|
|
|
+ .region_sizes = { 1, 2, 4, 8, 16, 32 },
|
|
|
+ .nr_sizes = 6,
|
|
|
+ .nr_windows = 8,
|
|
|
+ .imap_addr_offset = 0x4,
|
|
|
+ .imap_window_offset = 0x8,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ /* IARR4/IMAP4 */
|
|
|
+ .type = IPROC_PCIE_IB_MAP_MEM,
|
|
|
+ .size_unit = SZ_1G,
|
|
|
+ .region_sizes = { 32, 64, 128, 256, 512 },
|
|
|
+ .nr_sizes = 5,
|
|
|
+ .nr_windows = 8,
|
|
|
+ .imap_addr_offset = 0x4,
|
|
|
+ .imap_window_offset = 0x8,
|
|
|
+ },
|
|
|
+};
|
|
|
+
|
|
|
/*
|
|
|
* iProc PCIe host registers
|
|
|
*/
|
|
@@ -258,6 +329,34 @@ static const u16 iproc_pcie_reg_paxb[] = {
|
|
|
[IPROC_PCIE_APB_ERR_EN] = 0xf40,
|
|
|
};
|
|
|
|
|
|
+/* iProc PCIe PAXB v2 registers */
|
|
|
+static const u16 iproc_pcie_reg_paxb_v2[] = {
|
|
|
+ [IPROC_PCIE_CLK_CTRL] = 0x000,
|
|
|
+ [IPROC_PCIE_CFG_IND_ADDR] = 0x120,
|
|
|
+ [IPROC_PCIE_CFG_IND_DATA] = 0x124,
|
|
|
+ [IPROC_PCIE_CFG_ADDR] = 0x1f8,
|
|
|
+ [IPROC_PCIE_CFG_DATA] = 0x1fc,
|
|
|
+ [IPROC_PCIE_INTX_EN] = 0x330,
|
|
|
+ [IPROC_PCIE_OARR0] = 0xd20,
|
|
|
+ [IPROC_PCIE_OMAP0] = 0xd40,
|
|
|
+ [IPROC_PCIE_OARR1] = 0xd28,
|
|
|
+ [IPROC_PCIE_OMAP1] = 0xd48,
|
|
|
+ [IPROC_PCIE_OARR2] = 0xd60,
|
|
|
+ [IPROC_PCIE_OMAP2] = 0xd68,
|
|
|
+ [IPROC_PCIE_OARR3] = 0xdf0,
|
|
|
+ [IPROC_PCIE_OMAP3] = 0xdf8,
|
|
|
+ [IPROC_PCIE_IARR0] = 0xd00,
|
|
|
+ [IPROC_PCIE_IMAP0] = 0xc00,
|
|
|
+ [IPROC_PCIE_IARR2] = 0xd10,
|
|
|
+ [IPROC_PCIE_IMAP2] = 0xcc0,
|
|
|
+ [IPROC_PCIE_IARR3] = 0xe00,
|
|
|
+ [IPROC_PCIE_IMAP3] = 0xe08,
|
|
|
+ [IPROC_PCIE_IARR4] = 0xe68,
|
|
|
+ [IPROC_PCIE_IMAP4] = 0xe70,
|
|
|
+ [IPROC_PCIE_LINK_STATUS] = 0xf0c,
|
|
|
+ [IPROC_PCIE_APB_ERR_EN] = 0xf40,
|
|
|
+};
|
|
|
+
|
|
|
/* iProc PCIe PAXC v1 registers */
|
|
|
static const u16 iproc_pcie_reg_paxc[] = {
|
|
|
[IPROC_PCIE_CLK_CTRL] = 0x000,
|
|
@@ -914,6 +1013,19 @@ static int iproce_pcie_get_msi(struct iproc_pcie *pcie,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int iproc_pcie_paxb_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr)
|
|
|
+{
|
|
|
+ int ret;
|
|
|
+ struct of_pci_range range;
|
|
|
+
|
|
|
+ memset(&range, 0, sizeof(range));
|
|
|
+ range.size = SZ_32K;
|
|
|
+ range.pci_addr = range.cpu_addr = ALIGN(msi_addr, range.size);
|
|
|
+
|
|
|
+ ret = iproc_pcie_setup_ib(pcie, &range, IPROC_PCIE_IB_MAP_IO);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
static void iproc_pcie_paxc_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr)
|
|
|
{
|
|
|
u32 val;
|
|
@@ -965,6 +1077,11 @@ static int iproc_pcie_msi_steer(struct iproc_pcie *pcie,
|
|
|
}
|
|
|
|
|
|
switch (pcie->type) {
|
|
|
+ case IPROC_PCIE_PAXB_V2:
|
|
|
+ ret = iproc_pcie_paxb_v2_msi_steer(pcie, msi_addr);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ break;
|
|
|
case IPROC_PCIE_PAXC_V2:
|
|
|
iproc_pcie_paxc_v2_msi_steer(pcie, msi_addr);
|
|
|
break;
|
|
@@ -1042,6 +1159,17 @@ static int iproc_pcie_rev_init(struct iproc_pcie *pcie)
|
|
|
pcie->ob.nr_windows = ARRAY_SIZE(paxb_ob_map);
|
|
|
}
|
|
|
break;
|
|
|
+ case IPROC_PCIE_PAXB_V2:
|
|
|
+ regs = iproc_pcie_reg_paxb_v2;
|
|
|
+ pcie->has_apb_err_disable = true;
|
|
|
+ if (pcie->need_ob_cfg) {
|
|
|
+ pcie->ob_map = paxb_v2_ob_map;
|
|
|
+ pcie->ob.nr_windows = ARRAY_SIZE(paxb_v2_ob_map);
|
|
|
+ }
|
|
|
+ pcie->ib.nr_regions = ARRAY_SIZE(paxb_v2_ib_map);
|
|
|
+ pcie->ib_map = paxb_v2_ib_map;
|
|
|
+ pcie->need_msi_steer = true;
|
|
|
+ break;
|
|
|
case IPROC_PCIE_PAXC:
|
|
|
regs = iproc_pcie_reg_paxc;
|
|
|
pcie->ep_is_internal = true;
|