@@ -698,6 +698,16 @@ config FSL_GTM
help
Freescale General-purpose Timers support
+config HAS_FSL_PAMU
+ bool
+ default n
+
+config FSL_PAMU
+ bool "PAMU/IOMMU support"
+ depends on HAS_FSL_PAMU
+ help
+ Freescale PAMU/IOMMU support
+
# Yes MCA RS/6000s exist but Linux-PPC does not currently support any
config MCA
bool
@@ -206,6 +206,7 @@ config P2041_RDB
select GPIO_MPC8XXX
select HAS_RAPIDIO
select PPC_EPAPR_HV_PIC
+ select HAS_FSL_PAMU
help
This option enables support for the P2041 RDB board
@@ -219,6 +220,7 @@ config P3041_DS
select GPIO_MPC8XXX
select HAS_RAPIDIO
select PPC_EPAPR_HV_PIC
+ select HAS_FSL_PAMU
help
This option enables support for the P3041 DS board
@@ -231,6 +233,7 @@ config P3060_QDS
select GPIO_MPC8XXX
select HAS_RAPIDIO
select PPC_EPAPR_HV_PIC
+ select HAS_FSL_PAMU
help
This option enables support for the P3060 QDS board
@@ -244,6 +247,7 @@ config P4080_DS
select GPIO_MPC8XXX
select HAS_RAPIDIO
select PPC_EPAPR_HV_PIC
+ select HAS_FSL_PAMU
help
This option enables support for the P4080 DS board
@@ -260,6 +264,7 @@ config P5020_DS
select GPIO_MPC8XXX
select HAS_RAPIDIO
select PPC_EPAPR_HV_PIC
+ select HAS_FSL_PAMU
help
This option enables support for the P5020 DS board
@@ -21,6 +21,7 @@ obj-$(CONFIG_FSL_PMC) += fsl_pmc.o
obj-$(CONFIG_FSL_LBC) += fsl_lbc.o
obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
obj-$(CONFIG_FSL_GTM) += fsl_gtm.o
+obj-$(CONFIG_FSL_PAMU) += fsl_pamu.o
obj-$(CONFIG_FSL_85XX_CACHE_SRAM) += fsl_85xx_l2ctlr.o fsl_85xx_cache_sram.o
obj-$(CONFIG_SIMPLE_GPIO) += simple_gpio.o
obj-$(CONFIG_FSL_RIO) += fsl_rio.o fsl_rmu.o
new file mode 100644
@@ -0,0 +1,426 @@
+/* Copyright (c) 2008-2011 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+#include <linux/of_platform.h>
+#include <linux/bootmem.h>
+#include <asm/io.h>
+#include <asm/bitops.h>
+
+#include "fsl_pamu.h"
+
+#define PAMUBYPENR 0x604
+
+/* define indexes for each operation mapping scenario */
+#define OMI_QMAN 0x00
+#define OMI_FMAN 0x01
+#define OMI_QMAN_PRIV 0x02
+#define OMI_CAAM 0x03
+
+void setup_omt(struct ome *omt)
+{
+ struct ome *ome;
+
+ /* Configure OMI_QMAN */
+ ome = &omt[OMI_QMAN];
+
+ ome->moe[IOE_READ_IDX] = EOE_VALID | EOE_READ;
+ ome->moe[IOE_EREAD0_IDX] = EOE_VALID | EOE_RSA;
+ ome->moe[IOE_WRITE_IDX] = EOE_VALID | EOE_WRITE;
+ ome->moe[IOE_EWRITE0_IDX] = EOE_VALID | EOE_WWSAO;
+
+ /*
+ * When it comes to stashing DIRECTIVEs, the QMan BG says
+ * (1.5.6.7.1: FQD Context_A field used for dequeued etc.
+ * etc. stashing control):
+ * - AE/DE/CE == 0: don't stash exclusive. Use DIRECT0,
+ * which should be a non-PE LOADEC.
+ * - AE/DE/CE == 1: stash exclusive via DIRECT1, i.e.
+ * LOADEC-PE
+ * If one desires to alter how the three different types of
+ * stashing are done, please alter rx_conf.exclusive in
+ * ipfwd_a.c (that specifies the 3-bit AE/DE/CE field), and
+ * do not alter the settings here. - bgrayson
+ */
+ ome->moe[IOE_DIRECT0_IDX] = EOE_VALID | EOE_LDEC;
+ ome->moe[IOE_DIRECT1_IDX] = EOE_VALID | EOE_LDECPE;
+
+ /* Configure OMI_FMAN */
+ ome = &omt[OMI_FMAN];
+ ome->moe[IOE_READ_IDX] = EOE_VALID | EOE_READI;
+ ome->moe[IOE_WRITE_IDX] = EOE_VALID | EOE_WRITE;
+
+ /* Configure OMI_QMAN private */
+ ome = &omt[OMI_QMAN_PRIV];
+ ome->moe[IOE_READ_IDX] = EOE_VALID | EOE_READ;
+ ome->moe[IOE_WRITE_IDX] = EOE_VALID | EOE_WRITE;
+ ome->moe[IOE_EREAD0_IDX] = EOE_VALID | EOE_RSA;
+ ome->moe[IOE_EWRITE0_IDX] = EOE_VALID | EOE_WWSA;
+
+ /* Configure OMI_CAAM */
+ ome = &omt[OMI_CAAM];
+ ome->moe[IOE_READ_IDX] = EOE_VALID | EOE_READI;
+ ome->moe[IOE_WRITE_IDX] = EOE_VALID | EOE_WRITE;
+}
+
+#define L1 1
+#define L2 2
+#define L3 3
+
+u32 get_stash_id(u32 stash_dest_hint, struct device_node *portal_dn)
+{
+ const u32 *prop;
+ struct device_node *node;
+ u32 cache_level;
+
+ /* Fastpath, exit early if L3/CPC cache is target for stashing */
+ if (stash_dest_hint == L3) {
+ node = of_find_compatible_node(NULL, NULL,
+ "fsl,p4080-l3-cache-controller");
+ if (node) {
+ prop = of_get_property(node, "cache-stash-id", 0);
+ if (!prop) {
+ printk(KERN_ERR "missing cache-stash-id at %s\n", node->full_name);
+ of_node_put(node);
+ return ~(u32)0;
+ }
+ of_node_put(node);
+ return *prop;
+ }
+ return ~(u32)0;
+ }
+
+ prop = of_get_property(portal_dn, "cpu-handle", 0);
+ /* if no cpu-phandle assume that this is not a per-cpu portal */
+ if (!prop)
+ return ~(u32)0;
+
+ node = of_find_node_by_phandle(*prop);
+ if (!node) {
+ printk(KERN_ERR "bad cpu phandle reference in %s\n",
+ portal_dn->full_name);
+ return ~(u32)0;
+ }
+
+ /* find the hwnode that represents the cache */
+ for (cache_level = L1; cache_level <= L3; cache_level++) {
+ if (stash_dest_hint == cache_level) {
+ prop = of_get_property(node, "cache-stash-id", 0);
+ if (!prop) {
+ printk(KERN_ERR "missing cache-stash-id at %s\n", node->full_name);
+ of_node_put(node);
+ return ~(u32)0;
+ }
+ of_node_put(node);
+ return *prop;
+ }
+
+ prop = of_get_property(node, "next-level-cache", 0);
+ if (!prop) {
+ printk(KERN_ERR "can't find next-level-cache at %s\n",
+ node->full_name);
+ of_node_put(node);
+ return ~(u32)0; /* can't traverse any further */
+ }
+ of_node_put(node);
+
+ /* advance to next node in cache hierarchy */
+ node = of_find_node_by_phandle(*prop);
+ if (!node) {
+ printk(KERN_ERR "bad cpu phandle reference in %s\n",
+ portal_dn->full_name);
+ return ~(u32)0;
+ }
+ }
+
+ printk(KERN_ERR "stash dest not found for %d on %s\n",
+ stash_dest_hint, portal_dn->full_name);
+ return ~(u32)0;
+}
+
+void setup_liodns(struct ppaace *ppaact)
+{
+ int i, len;
+ struct ppaace *ppaace;
+ struct device_node *qman_portal_dn = NULL;
+ struct device_node *qman_dn = NULL;
+ const u32 *prop;
+ u32 cache_id, prop_cnt;
+
+ for (i = 0; i < PAACE_NUMBER_ENTRIES; i++) {
+ ppaace = &ppaact[i];
+ ppaace->pt = PAACE_PT_PRIMARY;
+ ppaace->domain_attr.to_host.coherency_required =
+ PAACE_M_COHERENCE_REQ;
+ /* window size is 2^(WSE+1) bytes */
+ ppaace->wse = 35; /* 36-bit phys. addr space */
+ ppaace->wbah = ppaace->wbal = 0;
+ ppaace->atm = PAACE_ATM_NO_XLATE;
+ ppaace->ap = PAACE_AP_PERMS_ALL;
+ mb();
+ ppaace->v = 1;
+ }
+
+ /*
+ * Now, do specific stashing setup for qman portals.
+ * We need stashing setup for LIODNs for qman portal(s) dqrr stashing
+ * (DLIODNs), qman portal(s) data stashing (FLIODNs)
+ */
+
+ for_each_compatible_node(qman_portal_dn, NULL, "fsl,qman-portal") {
+
+ pr_debug("qman portal found, name = %s\n",
+ qman_portal_dn->full_name);
+ prop = of_get_property(qman_portal_dn, "fsl,liodn", &len);
+ if (prop) {
+ prop_cnt = len / sizeof(u32);
+ do {
+ pr_debug("liodn = %d\n", *prop);
+ ppaace = &ppaact[*prop++];
+ ppaace->otm = PAACE_OTM_INDEXED;
+ ppaace->op_encode.index_ot.omi = OMI_QMAN;
+ cache_id = get_stash_id(L1, qman_portal_dn);
+ pr_debug("cache_stash_id = %d\n", cache_id);
+ if (~cache_id != 0)
+ ppaace->impl_attr.cid = cache_id;
+ } while(--prop_cnt);
+ } else {
+ printk (KERN_ERR "missing fsl,liodn property at %s\n",
+ qman_portal_dn->full_name);
+ }
+ }
+
+ /*
+ * Next, do stashing setups for qman private memory access
+ */
+
+ qman_dn = of_find_compatible_node(NULL, NULL, "fsl,qman");
+ if (qman_dn) {
+ prop = of_get_property(qman_dn, "fsl,liodn", NULL);
+ if (prop) {
+ ppaace = &ppaact[*prop];
+ ppaace->otm = PAACE_OTM_INDEXED;
+ ppaace->op_encode.index_ot.omi = OMI_QMAN_PRIV;
+ cache_id = get_stash_id(L3, qman_dn);
+ pr_debug("cache_stash_id = %d\n", cache_id);
+ if (~cache_id != 0)
+ ppaace->impl_attr.cid = cache_id;
+ } else {
+ printk (KERN_ERR "missing fsl,liodn property at %s\n",
+ qman_dn->full_name);
+ }
+ of_node_put(qman_dn);
+ }
+}
+
+int setup_one_pamu(unsigned long pamu_reg_base, unsigned long pamu_reg_size,
+ struct ppaace *ppaact, struct ome *omt)
+{
+ u32 *pc;
+ phys_addr_t phys;
+ struct pamu_mmap_regs *pamu_regs;
+
+ pc = (u32 *) (pamu_reg_base + PAMU_PC);
+ pamu_regs = (struct pamu_mmap_regs *)
+ (pamu_reg_base + PAMU_MMAP_REGS_BASE);
+
+ /* set up pointers to corenet control blocks */
+
+ phys = virt_to_phys(ppaact);
+ out_be32(&pamu_regs->ppbah, ((u64)phys) >> 32);
+ out_be32(&pamu_regs->ppbal, phys);
+ phys = virt_to_phys(ppaact + PAACE_NUMBER_ENTRIES);
+ out_be32(&pamu_regs->pplah, ((u64)phys) >> 32);
+ out_be32(&pamu_regs->pplal, phys);
+
+ phys = virt_to_phys(omt);
+ out_be32(&pamu_regs->obah, ((u64)phys) >> 32);
+ out_be32(&pamu_regs->obal, phys);
+ phys = virt_to_phys(omt + OME_NUMBER_ENTRIES);
+ out_be32(&pamu_regs->olah, ((u64)phys) >> 32);
+ out_be32(&pamu_regs->olal, phys);
+
+ /*
+ * set PAMU enable bit,
+ * allow ppaact & omt to be cached
+ * & enable PAMU access violation interrupts.
+ */
+
+ out_be32((u32 *)(pamu_reg_base + PAMU_PICS),
+ PAMU_ACCESS_VIOLATION_ENABLE);
+ out_be32(pc, PAMU_PC_PE | PAMU_PC_OCE | PAMU_PC_SPCC | PAMU_PC_PPCC);
+ return 0;
+}
+
+irqreturn_t pamu_av_isr(int irq, void *arg)
+{
+ panic("FSL_PAMU: access violation interrupt\n");
+ /* NOTREACHED */
+}
+
+static int __devinit fsl_of_pamu_probe(struct platform_device *dev)
+{
+ void __iomem *pamu_regs, *guts_regs;
+ u32 pamubypenr, pamu_counter;
+ unsigned long pamu_reg_base, pamu_reg_off;
+ struct device_node *guts_node;
+ u64 size;
+ struct ppaace *ppaact = NULL;
+ struct ome *omt = NULL;
+ int irq;
+ struct page *p;
+
+ printk(KERN_INFO "Setting Freescale static PAMU/IOMMU configuration\n");
+
+ /*
+ * enumerate all PAMUs and allocate and setup PAMU tables
+ * for each of them,
+ * NOTE : All PAMUs share the same LIODN tables.
+ */
+
+ pamu_regs = of_iomap(dev->dev.of_node, 0);
+ if (!pamu_regs) {
+ dev_err(&dev->dev, "ioremap failed\n");
+ return -ENOMEM;
+ }
+ of_get_address(dev->dev.of_node, 0, &size, NULL);
+
+ guts_node = of_find_compatible_node(NULL, NULL,
+ "fsl,qoriq-device-config-1.0");
+ if (!guts_node) {
+ dev_err(&dev->dev, "%s guts devnode not found!\n",
+ dev->dev.of_node->full_name);
+ iounmap(pamu_regs);
+ return -ENODEV;
+ }
+
+ guts_regs = of_iomap(guts_node, 0);
+ if (!guts_regs) {
+ dev_err(&dev->dev, "guts ioremap failed\n");
+ iounmap(pamu_regs);
+ return -ENOMEM;
+ }
+ of_node_put(guts_node);
+
+ p = alloc_pages(GFP_KERNEL, get_order(PAACT_SIZE));
+ if (!p) {
+ printk(KERN_ERR "Unable to allocate space for PAACT table\n");
+ iounmap(pamu_regs);
+ iounmap(guts_regs);
+ return -ENOMEM;
+ }
+ ppaact = page_address(p);
+ memset(ppaact, 0, PAACT_SIZE);
+
+ pr_debug("fsl_pamu, paact_mem, v : %p, p : 0x%lx\n",
+ ppaact, virt_to_phys(ppaact));
+
+ p = alloc_pages(GFP_KERNEL, get_order(OMT_SIZE));
+ if (!p) {
+ printk(KERN_ERR "Unable to allocate space for OMT table\n");
+ iounmap(pamu_regs);
+ iounmap(guts_regs);
+ free_pages((unsigned long)ppaact, get_order(PAACT_SIZE));
+ return -ENOMEM;
+ }
+ omt = page_address(p);
+ memset(omt, 0, OMT_SIZE);
+
+ pr_debug("fsl_pamu, omt_mem, v : %p, p : 0x%lx\n",
+ omt, virt_to_phys(omt));
+
+ pamubypenr = in_be32(guts_regs + PAMUBYPENR);
+
+ for (pamu_reg_off = 0, pamu_counter = 0x80000000; pamu_reg_off < size;
+ pamu_reg_off += PAMU_OFFSET, pamu_counter >>= 1) {
+
+ pamu_reg_base = (unsigned long) pamu_regs + pamu_reg_off;
+ setup_one_pamu(pamu_reg_base, pamu_reg_off, ppaact, omt);
+
+ /* Disable PAMU bypass for this PAMU */
+ pamubypenr &= ~pamu_counter;
+ }
+
+ setup_omt(omt);
+
+ irq = irq_of_parse_and_map(dev->dev.of_node, 0);
+ if (request_irq(irq, pamu_av_isr, IRQF_DISABLED, "pamu", 0) < 0) {
+ printk(KERN_ERR "Cannot request PAMU AV interrupt\n");
+ iounmap(pamu_regs);
+ iounmap(guts_regs);
+ free_pages((unsigned long)ppaact, get_order(PAACT_SIZE));
+ free_pages((unsigned long)omt, get_order(OMT_SIZE));
+ return -ENODEV;
+ }
+
+ /*
+ * setup all LIODNS(s) to define a 1:1 mapping for the entire
+ * 36-bit physical address space
+ */
+ setup_liodns(ppaact);
+ mb();
+
+ /* Enable all relevant PAMU(s) */
+ out_be32(guts_regs + PAMUBYPENR, pamubypenr);
+
+ return 0;
+}
+
+static const struct of_device_id fsl_of_pamu_ids[] = {
+ {
+ .compatible = "fsl,p4080-pamu",
+ },
+ {
+ .compatible = "fsl,pamu",
+ },
+ {},
+};
+
+static struct platform_driver fsl_of_pamu_driver = {
+ .driver = {
+ .name = "fsl-of-pamu",
+ .of_match_table = fsl_of_pamu_ids,
+ },
+ .probe = fsl_of_pamu_probe,
+};
+
+static __init int fsl_of_pamu_init(void)
+{
+ return platform_driver_register(&fsl_of_pamu_driver);
+}
+
+arch_initcall(fsl_of_pamu_init);
new file mode 100644
@@ -0,0 +1,382 @@
+/* Copyright (c) 2008-2010 Freescale Semiconductor, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Freescale Semiconductor nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __PAMU_H
+#define __PAMU_H
+
+/* PAMU CCSR space */
+#define PAMU_PGC 0x00000000 /* Allows all peripheral accesses */
+#define PAMU_PE 0x40000000 /* enable PAMU */
+
+/* PAMU_OFFSET to the next pamu space in ccsr */
+#define PAMU_OFFSET 0x1000
+
+#define PAMU_MMAP_REGS_BASE 0
+
+struct pamu_mmap_regs {
+ u32 ppbah;
+ u32 ppbal;
+ u32 pplah;
+ u32 pplal;
+ u32 spbah;
+ u32 spbal;
+ u32 splah;
+ u32 splal;
+ u32 obah;
+ u32 obal;
+ u32 olah;
+ u32 olal;
+};
+
+/* PAMU Error Registers */
+#define PAMU_POES1 0x0040
+#define PAMU_POES2 0x0044
+#define PAMU_POEAH 0x0048
+#define PAMU_POEAL 0x004C
+#define PAMU_AVS1 0x0050
+#define PAMU_AVS1_AV 0x1
+#define PAMU_AVS1_OTV 0x6
+#define PAMU_AVS1_APV 0x78
+#define PAMU_AVS1_WAV 0x380
+#define PAMU_AVS1_LAV 0x1c00
+#define PAMU_AVS1_GCV 0x2000
+#define PAMU_AVS1_PDV 0x4000
+#define PAMU_AV_MASK (PAMU_AVS1_AV | PAMU_AVS1_OTV | PAMU_AVS1_APV | PAMU_AVS1_WAV \
+ | PAMU_AVS1_LAV | PAMU_AVS1_GCV | PAMU_AVS1_PDV)
+#define PAMU_AVS1_LIODN_SHIFT 16
+#define PAMU_LAV_LIODN_NOT_IN_PPAACT 0x400
+
+#define PAMU_AVS2 0x0054
+#define PAMU_AVAH 0x0058
+#define PAMU_AVAL 0x005C
+#define PAMU_EECTL 0x0060
+#define PAMU_EEDIS 0x0064
+#define PAMU_EEINTEN 0x0068
+#define PAMU_EEDET 0x006C
+#define PAMU_EEATTR 0x0070
+#define PAMU_EEAHI 0x0074
+#define PAMU_EEALO 0x0078
+#define PAMU_EEDHI 0X007C
+#define PAMU_EEDLO 0x0080
+#define PAMU_EECC 0x0084
+
+/* PAMU Revision Registers */
+#define PAMU_PR1 0x0BF8
+#define PAMU_PR2 0x0BFC
+
+/* PAMU Capabilities Registers */
+#define PAMU_PC1 0x0C00
+#define PAMU_PC2 0x0C04
+#define PAMU_PC3 0x0C08
+#define PAMU_PC4 0x0C0C
+
+/* PAMU Control Register */
+#define PAMU_PC 0x0C10
+
+/* PAMU control defs */
+#define PAMU_CONTROL 0x0C10
+#define PAMU_PC_PGC 0x80000000 /* 1 = PAMU Gate Closed : block all
+peripheral access, 0 : may allow peripheral access */
+
+#define PAMU_PC_PE 0x40000000 /* 0 = PAMU disabled, 1 = PAMU enabled */
+#define PAMU_PC_SPCC 0x00000010 /* sPAACE cache enable */
+#define PAMU_PC_PPCC 0x00000001 /* pPAACE cache enable */
+#define PAMU_PC_OCE 0x00001000 /* OMT cache enable */
+
+#define PAMU_PFA1 0x0C14
+#define PAMU_PFA2 0x0C18
+
+/* PAMU Interrupt control and Status Register */
+#define PAMU_PICS 0x0C1C
+#define PAMU_ACCESS_VIOLATION_STAT 0x8
+#define PAMU_ACCESS_VIOLATION_ENABLE 0x4
+
+/* PAMU Debug Registers */
+#define PAMU_PD1 0x0F00
+#define PAMU_PD2 0x0F04
+#define PAMU_PD3 0x0F08
+#define PAMU_PD4 0x0F0C
+
+#define PAACE_AP_PERMS_DENIED 0x0
+#define PAACE_AP_PERMS_QUERY 0x1
+#define PAACE_AP_PERMS_UPDATE 0x2
+#define PAACE_AP_PERMS_ALL 0x3
+#define PAACE_DD_TO_HOST 0x0
+#define PAACE_DD_TO_IO 0x1
+#define PAACE_PT_PRIMARY 0x0
+#define PAACE_PT_SECONDARY 0x1
+#define PAACE_V_INVALID 0x0
+#define PAACE_V_VALID 0x1
+#define PAACE_MW_SUBWINDOWS 0x1
+
+#define PAACE_WSE_4K 0xB
+#define PAACE_WSE_8K 0xC
+#define PAACE_WSE_16K 0xD
+#define PAACE_WSE_32K 0xE
+#define PAACE_WSE_64K 0xF
+#define PAACE_WSE_128K 0x10
+#define PAACE_WSE_256K 0x11
+#define PAACE_WSE_512K 0x12
+#define PAACE_WSE_1M 0x13
+#define PAACE_WSE_2M 0x14
+#define PAACE_WSE_4M 0x15
+#define PAACE_WSE_8M 0x16
+#define PAACE_WSE_16M 0x17
+#define PAACE_WSE_32M 0x18
+#define PAACE_WSE_64M 0x19
+#define PAACE_WSE_128M 0x1A
+#define PAACE_WSE_256M 0x1B
+#define PAACE_WSE_512M 0x1C
+#define PAACE_WSE_1G 0x1D
+#define PAACE_WSE_2G 0x1E
+#define PAACE_WSE_4G 0x1F
+
+#define PAACE_DID_PCI_EXPRESS_1 0x00
+#define PAACE_DID_PCI_EXPRESS_2 0x01
+#define PAACE_DID_PCI_EXPRESS_3 0x02
+#define PAACE_DID_PCI_EXPRESS_4 0x03
+#define PAACE_DID_LOCAL_BUS 0x04
+#define PAACE_DID_SRIO 0x0C
+#define PAACE_DID_MEM_1 0x10
+#define PAACE_DID_MEM_2 0x11
+#define PAACE_DID_MEM_3 0x12
+#define PAACE_DID_MEM_4 0x13
+#define PAACE_DID_MEM_1_2 0x14
+#define PAACE_DID_MEM_3_4 0x15
+#define PAACE_DID_MEM_1_4 0x16
+#define PAACE_DID_BM_SW_PORTAL 0x18
+#define PAACE_DID_PAMU 0x1C
+#define PAACE_DID_CAAM 0x21
+#define PAACE_DID_QM_SW_PORTAL 0x3C
+#define PAACE_DID_CORE0_INST 0x80
+#define PAACE_DID_CORE0_DATA 0x81
+#define PAACE_DID_CORE1_INST 0x82
+#define PAACE_DID_CORE1_DATA 0x83
+#define PAACE_DID_CORE2_INST 0x84
+#define PAACE_DID_CORE2_DATA 0x85
+#define PAACE_DID_CORE3_INST 0x86
+#define PAACE_DID_CORE3_DATA 0x87
+#define PAACE_DID_CORE4_INST 0x88
+#define PAACE_DID_CORE4_DATA 0x89
+#define PAACE_DID_CORE5_INST 0x8A
+#define PAACE_DID_CORE5_DATA 0x8B
+#define PAACE_DID_CORE6_INST 0x8C
+#define PAACE_DID_CORE6_DATA 0x8D
+#define PAACE_DID_CORE7_INST 0x8E
+#define PAACE_DID_CORE7_DATA 0x8F
+#define PAACE_DID_BROADCAST 0xFF
+
+#define PAACE_ATM_NO_XLATE 0x00
+#define PAACE_ATM_WINDOW_XLATE 0x01
+#define PAACE_ATM_PAGE_XLATE 0x02
+#define PAACE_ATM_WIN_PG_XLATE \
+ ( PAACE_ATM_WINDOW_XLATE | PAACE_ATM_PAGE_XLATE )
+#define PAACE_OTM_NO_XLATE 0x00
+#define PAACE_OTM_IMMEDIATE 0x01
+#define PAACE_OTM_INDEXED 0x02
+#define PAACE_OTM_RESERVED 0x03
+
+#define PAACE_M_COHERENCE_REQ 0x01
+
+#define PAACE_PID_0 0x0
+#define PAACE_PID_1 0x1
+#define PAACE_PID_2 0x2
+#define PAACE_PID_3 0x3
+#define PAACE_PID_4 0x4
+#define PAACE_PID_5 0x5
+#define PAACE_PID_6 0x6
+#define PAACE_PID_7 0x7
+
+#define PAACE_TCEF_FORMAT0_8B 0x00
+#define PAACE_TCEF_FORMAT1_RSVD 0x01
+
+#define PAACE_NUMBER_ENTRIES 0xFF
+
+#define OME_NUMBER_ENTRIES 16 /* based on P4080 2.0 silicon plan */
+
+/* PAMU Data Structures */
+
+struct ppaace {
+ /* PAACE Offset 0x00 */
+ /* Window Base Address */
+ u32 wbah;
+ unsigned int wbal : 20;
+ /* Window Size, 2^(N+1), N must be > 10 */
+ unsigned int wse : 6;
+ /* 1 Means there are secondary windows, wce is count */
+ unsigned int mw : 1;
+ /* Permissions, see PAACE_AP_PERMS_* defines */
+ unsigned int ap : 2;
+ /*
+ * Destination Domain, see PAACE_DD_* defines,
+ * defines data structure reference for ingress ops into
+ * host/coherency domain or ingress ops into I/O domain
+ */
+ unsigned int dd : 1;
+ /* PAACE Type, see PAACE_PT_* defines */
+ unsigned int pt : 1;
+ /* PAACE Valid, 0 is invalid */
+ unsigned int v : 1;
+
+ /* PAACE Offset 0x08 */
+ /* Interpretation of first 32 bits dependent on DD above */
+ union {
+ struct {
+ /* Destination ID, see PAACE_DID_* defines */
+ u8 did;
+ /* Partition ID */
+ u8 pid;
+ /* Snoop ID */
+ u8 snpid;
+ unsigned int coherency_required : 1;
+ unsigned int reserved : 7;
+ } to_host;
+ struct {
+ /* Destination ID, see PAACE_DID_* defines */
+ u8 did;
+ unsigned int __reserved : 24;
+ } to_io;
+ } __attribute__ ((packed)) domain_attr;
+ /* Implementation attributes */
+ struct {
+ unsigned int reserved1 : 8;
+ unsigned int cid : 8;
+ unsigned int reserved2 : 8;
+ } __attribute__ ((packed)) impl_attr;
+ /* Window Count; 2^(N+1) sub-windows; only valid for primary PAACE */
+ unsigned int wce : 4;
+ /* Address translation mode, see PAACE_ATM_* defines */
+ unsigned int atm : 2;
+ /* Operation translation mode, see PAACE_OTM_* defines */
+ unsigned int otm : 2;
+
+ /* PAACE Offset 0x10 */
+ /* Translated window base address */
+ u32 twbah;
+ unsigned int twbal : 20;
+ /* Subwindow size encoding; 2^(N+1), N > 10 */
+ unsigned int swse : 6;
+ unsigned int reserved4 : 6;
+
+ /* PAACE Offset 0x18 */
+ u32 fspi;
+ union {
+ struct {
+ u8 ioea;
+ u8 moea;
+ u8 ioeb;
+ u8 moeb;
+ } immed_ot;
+ struct {
+ u16 reserved;
+ u16 omi;
+ } index_ot;
+ } __attribute__ ((packed)) op_encode;
+
+ /* PAACE Offset 0x20 */
+ u32 sbah;
+ unsigned int sbal : 20;
+ unsigned int sse : 6;
+ unsigned int reserved5 : 6;
+
+ /* PAACE Offset 0x28 */
+ u32 tctbah;
+ unsigned int tctbal : 20;
+ unsigned int pse : 6;
+ unsigned int tcef :1;
+ unsigned int reserved6 : 5;
+
+ /* PAACE Offset 0x30 */
+ u32 reserved7[2];
+
+ /* PAACE Offset 0x38 */
+ u32 reserved8[2];
+} __attribute__ ((packed)) ppaace;
+
+/* MOE : Mapped Operation Encodings */
+#define NUM_MOE 128
+struct ome {
+ u8 moe[NUM_MOE];
+} __attribute__((packed)) ome;
+
+#define PAACT_SIZE (sizeof(struct ppaace) * PAACE_NUMBER_ENTRIES)
+#define OMT_SIZE (sizeof(struct ome) * OME_NUMBER_ENTRIES)
+
+#define IOE_READ 0x00
+#define IOE_READ_IDX 0x00
+#define IOE_WRITE 0x81
+#define IOE_WRITE_IDX 0x01
+#define IOE_EREAD0 0x82 /* Enhanced read type 0 */
+#define IOE_EREAD0_IDX 0x02 /* Enhanced read type 0 */
+#define IOE_EWRITE0 0x83 /* Enhanced write type 0 */
+#define IOE_EWRITE0_IDX 0x03 /* Enhanced write type 0 */
+#define IOE_DIRECT0 0x84 /* Directive type 0 */
+#define IOE_DIRECT0_IDX 0x04 /* Directive type 0 */
+#define IOE_EREAD1 0x85 /* Enhanced read type 1 */
+#define IOE_EREAD1_IDX 0x05 /* Enhanced read type 1 */
+#define IOE_EWRITE1 0x86 /* Enhanced write type 1 */
+#define IOE_EWRITE1_IDX 0x06 /* Enhanced write type 1 */
+#define IOE_DIRECT1 0x87 /* Directive type 1 */
+#define IOE_DIRECT1_IDX 0x07 /* Directive type 1 */
+#define IOE_RAC 0x8c /* Read with Atomic clear */
+#define IOE_RAC_IDX 0x0c /* Read with Atomic clear */
+#define IOE_RAS 0x8d /* Read with Atomic set */
+#define IOE_RAS_IDX 0x0d /* Read with Atomic set */
+#define IOE_RAD 0x8e /* Read with Atomic decrement */
+#define IOE_RAD_IDX 0x0e /* Read with Atomic decrement */
+#define IOE_RAI 0x8f /* Read with Atomic increment */
+#define IOE_RAI_IDX 0x0f /* Read with Atomic increment */
+
+#define EOE_READ 0x00
+#define EOE_WRITE 0x01
+#define EOE_RAC 0x0c /* Read with Atomic clear */
+#define EOE_RAS 0x0d /* Read with Atomic set */
+#define EOE_RAD 0x0e /* Read with Atomic decrement */
+#define EOE_RAI 0x0f /* Read with Atomic increment */
+#define EOE_LDEC 0x10 /* Load external cache */
+#define EOE_LDECL 0x11 /* Load external cache with stash lock */
+#define EOE_LDECPE 0x12 /* Load external cache with preferred exclusive */
+#define EOE_LDECPEL 0x13 /* Load external cache with preferred exclusive and lock */
+#define EOE_LDECFE 0x14 /* Load external cache with forced exclusive */
+#define EOE_LDECFEL 0x15 /* Load external cache with forced exclusive and lock */
+#define EOE_RSA 0x16 /* Read with stash allocate */
+#define EOE_RSAU 0x17 /* Read with stash allocate and unlock */
+#define EOE_READI 0x18 /* Read with invalidate */
+#define EOE_RWNITC 0x19 /* Read with no intention to cache */
+#define EOE_WCI 0x1a /* Write cache inhibited */
+#define EOE_WWSA 0x1b /* Write with stash allocate */
+#define EOE_WWSAL 0x1c /* Write with stash allocate and lock */
+#define EOE_WWSAO 0x1d /* Write with stash allocate only */
+#define EOE_WWSAOL 0x1e /* Write with stash allocate only and lock */
+#define EOE_VALID 0x80
+
+#endif /* __PAMU_H */