summaryrefslogtreecommitdiff
path: root/drivers/iommu/fsl_pamu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iommu/fsl_pamu.c')
-rw-r--r--drivers/iommu/fsl_pamu.c59
1 files changed, 50 insertions, 9 deletions
diff --git a/drivers/iommu/fsl_pamu.c b/drivers/iommu/fsl_pamu.c
index 2ce410b..1de02ca 100644
--- a/drivers/iommu/fsl_pamu.c
+++ b/drivers/iommu/fsl_pamu.c
@@ -253,6 +253,22 @@ static unsigned long pamu_get_fspi_and_allocate(u32 subwin_cnt)
return (spaace_addr - (unsigned long)spaact) / (sizeof(struct paace));
}
+/*
+ * Default PPAACE settings for an LIODN.
+ */
+static void setup_default_ppaace(struct paace *ppaace)
+{
+ pamu_init_ppaace(ppaace);
+ /* window size is 2^(WSE+1) bytes */
+ set_bf(ppaace->addr_bitfields, PPAACE_AF_WSE, 35);
+ ppaace->wbah = 0;
+ set_bf(ppaace->addr_bitfields, PPAACE_AF_WBAL, 0);
+ set_bf(ppaace->impl_attr, PAACE_IA_ATM,
+ PAACE_ATM_NO_XLATE);
+ set_bf(ppaace->addr_bitfields, PAACE_AF_AP,
+ PAACE_AP_PERMS_ALL);
+}
+
/* Release the subwindows reserved for a particular LIODN */
void pamu_free_subwins(int liodn)
{
@@ -733,6 +749,28 @@ int setup_one_pamu(unsigned long pamu_reg_base, unsigned long pamu_reg_size,
return 0;
}
+/*
+ * Primarily to Enable LIODNs which u-boot didn't update in the device tree.
+ */
+static void __init enable_remaining_liodns(void)
+{
+ int liodn;
+ struct paace *ppaace;
+
+ for (liodn = 0; liodn < PAACE_NUMBER_ENTRIES; liodn++) {
+ ppaace = pamu_get_ppaace(liodn);
+ if (!get_bf(ppaace->addr_bitfields, PAACE_AF_V)) {
+ setup_default_ppaace(ppaace);
+ /*
+ * Ensure that all stores to the ppaace
+ * complete first.
+ */
+ mb();
+ pamu_enable_liodn(liodn);
+ }
+ }
+}
+
/* Enable all device LIODNS */
static void __init setup_liodns(void)
{
@@ -752,15 +790,8 @@ static void __init setup_liodns(void)
continue;
}
ppaace = pamu_get_ppaace(liodn);
- pamu_init_ppaace(ppaace);
- /* window size is 2^(WSE+1) bytes */
- set_bf(ppaace->addr_bitfields, PPAACE_AF_WSE, 35);
- ppaace->wbah = 0;
- set_bf(ppaace->addr_bitfields, PPAACE_AF_WBAL, 0);
- set_bf(ppaace->impl_attr, PAACE_IA_ATM,
- PAACE_ATM_NO_XLATE);
- set_bf(ppaace->addr_bitfields, PAACE_AF_AP,
- PAACE_AP_PERMS_ALL);
+ setup_default_ppaace(ppaace);
+
if (of_device_is_compatible(node, "fsl,qman-portal"))
setup_qbman_paace(ppaace, QMAN_PORTAL_PAACE);
if (of_device_is_compatible(node, "fsl,qman"))
@@ -771,6 +802,16 @@ static void __init setup_liodns(void)
pamu_enable_liodn(liodn);
}
}
+
+ /*
+ * Currently u-boot doesn't fixup LIODNs for cases
+ * where a frame is passed to a hardware block from
+ * another hardware block. For example, frame can
+ * be passed from FMAN rx port to SEC or RMAN. So,
+ * as a work around we enable all the possible LIODN
+ * values.
+ */
+ enable_remaining_liodns();
}
irqreturn_t pamu_av_isr(int irq, void *arg)