aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/iommu/0002-omap-iommu-omap2-architecture-specific-functions.patch
diff options
context:
space:
mode:
authorRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:14:24 +0100
committerRichard Purdie <rpurdie@linux.intel.com>2010-08-27 15:29:45 +0100
commit29d6678fd546377459ef75cf54abeef5b969b5cf (patch)
tree8edd65790e37a00d01c3f203f773fe4b5012db18 /meta/recipes-kernel/linux/linux-omap-2.6.29/isp/iommu/0002-omap-iommu-omap2-architecture-specific-functions.patch
parentda49de6885ee1bc424e70bc02f21f6ab920efb55 (diff)
downloadopenembedded-core-contrib-29d6678fd546377459ef75cf54abeef5b969b5cf.tar.gz
Major layout change to the packages directory
Having one monolithic packages directory makes it hard to find things and is generally overwhelming. This commit splits it into several logical sections roughly based on function, recipes.txt gives more information about the classifications used. The opportunity is also used to switch from "packages" to "recipes" as used in OpenEmbedded as the term "packages" can be confusing to people and has many different meanings. Not all recipes have been classified yet, this is just a first pass at separating things out. Some packages are moved to meta-extras as they're no longer actively used or maintained. Signed-off-by: Richard Purdie <rpurdie@linux.intel.com>
Diffstat (limited to 'meta/recipes-kernel/linux/linux-omap-2.6.29/isp/iommu/0002-omap-iommu-omap2-architecture-specific-functions.patch')
-rw-r--r--meta/recipes-kernel/linux/linux-omap-2.6.29/isp/iommu/0002-omap-iommu-omap2-architecture-specific-functions.patch453
1 files changed, 453 insertions, 0 deletions
diff --git a/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/iommu/0002-omap-iommu-omap2-architecture-specific-functions.patch b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/iommu/0002-omap-iommu-omap2-architecture-specific-functions.patch
new file mode 100644
index 0000000000..d5f78dd14e
--- /dev/null
+++ b/meta/recipes-kernel/linux/linux-omap-2.6.29/isp/iommu/0002-omap-iommu-omap2-architecture-specific-functions.patch
@@ -0,0 +1,453 @@
+From c79d7959c45f40e47520aa6acd54c19094754787 Mon Sep 17 00:00:00 2001
+From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+Date: Mon, 26 Jan 2009 15:13:45 +0200
+Subject: [PATCH] omap iommu: omap2 architecture specific functions
+
+The structure 'arch_mmu' accommodates the difference between omap1 and
+omap2/3.
+
+This patch provides omap2/3 specific functions
+
+Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
+---
+ arch/arm/mach-omap2/iommu2.c | 326 ++++++++++++++++++++++++++++++
+ arch/arm/plat-omap/include/mach/iommu2.h | 94 +++++++++
+ 2 files changed, 420 insertions(+), 0 deletions(-)
+ create mode 100644 arch/arm/mach-omap2/iommu2.c
+ create mode 100644 arch/arm/plat-omap/include/mach/iommu2.h
+
+diff --git a/arch/arm/mach-omap2/iommu2.c b/arch/arm/mach-omap2/iommu2.c
+new file mode 100644
+index 0000000..88a44f1
+--- /dev/null
++++ b/arch/arm/mach-omap2/iommu2.c
+@@ -0,0 +1,326 @@
++/*
++ * omap iommu: omap2/3 architecture specific functions
++ *
++ * Copyright (C) 2008-2009 Nokia Corporation
++ *
++ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>,
++ * Paul Mundt and Toshihiro Kobayashi
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#include <linux/err.h>
++#include <linux/device.h>
++#include <linux/jiffies.h>
++#include <linux/module.h>
++#include <linux/stringify.h>
++
++#include <asm/io.h>
++
++#include <mach/iommu.h>
++#include <mach/iommu2.h>
++
++/*
++ * omap2 architecture specific register bit definitions
++ */
++#define IOMMU_ARCH_VERSION 0x00000011
++
++/* SYSCONF */
++#define MMU_SYS_IDLE_SHIFT 3
++#define MMU_SYS_IDLE_FORCE (0 << MMU_SYS_IDLE_SHIFT)
++#define MMU_SYS_IDLE_NONE (1 << MMU_SYS_IDLE_SHIFT)
++#define MMU_SYS_IDLE_SMART (2 << MMU_SYS_IDLE_SHIFT)
++#define MMU_SYS_IDLE_MASK (3 << MMU_SYS_IDLE_SHIFT)
++
++#define MMU_SYS_SOFTRESET (1 << 1)
++#define MMU_SYS_AUTOIDLE 1
++
++/* SYSSTATUS */
++#define MMU_SYS_RESETDONE 1
++
++/* IRQSTATUS & IRQENABLE */
++#define MMU_IRQ_MULTIHITFAULT (1 << 4)
++#define MMU_IRQ_TABLEWALKFAULT (1 << 3)
++#define MMU_IRQ_EMUMISS (1 << 2)
++#define MMU_IRQ_TRANSLATIONFAULT (1 << 1)
++#define MMU_IRQ_TLBMISS (1 << 0)
++#define MMU_IRQ_MASK \
++ (MMU_IRQ_MULTIHITFAULT | MMU_IRQ_TABLEWALKFAULT | MMU_IRQ_EMUMISS | \
++ MMU_IRQ_TRANSLATIONFAULT)
++
++/* MMU_CNTL */
++#define MMU_CNTL_SHIFT 1
++#define MMU_CNTL_MASK (7 << MMU_CNTL_SHIFT)
++#define MMU_CNTL_EML_TLB (1 << 3)
++#define MMU_CNTL_TWL_EN (1 << 2)
++#define MMU_CNTL_MMU_EN (1 << 1)
++
++#define get_cam_va_mask(pgsz) \
++ (((pgsz) == MMU_CAM_PGSZ_16M) ? 0xff000000 : \
++ ((pgsz) == MMU_CAM_PGSZ_1M) ? 0xfff00000 : \
++ ((pgsz) == MMU_CAM_PGSZ_64K) ? 0xffff0000 : \
++ ((pgsz) == MMU_CAM_PGSZ_4K) ? 0xfffff000 : 0)
++
++static int omap2_iommu_enable(struct iommu *obj)
++{
++ u32 l, pa;
++ unsigned long timeout;
++
++ if (!obj->iopgd || !IS_ALIGNED((u32)obj->iopgd, SZ_16K))
++ return -EINVAL;
++
++ pa = virt_to_phys(obj->iopgd);
++ if (!IS_ALIGNED(pa, SZ_16K))
++ return -EINVAL;
++
++ iommu_write_reg(obj, MMU_SYS_SOFTRESET, MMU_SYSCONFIG);
++
++ timeout = jiffies + msecs_to_jiffies(20);
++ do {
++ l = iommu_read_reg(obj, MMU_SYSSTATUS);
++ if (l & MMU_SYS_RESETDONE)
++ break;
++ } while (time_after(jiffies, timeout));
++
++ if (!(l & MMU_SYS_RESETDONE)) {
++ dev_err(obj->dev, "can't take mmu out of reset\n");
++ return -ENODEV;
++ }
++
++ l = iommu_read_reg(obj, MMU_REVISION);
++ dev_info(obj->dev, "%s: version %d.%d\n", obj->name,
++ (l >> 4) & 0xf, l & 0xf);
++
++ l = iommu_read_reg(obj, MMU_SYSCONFIG);
++ l &= ~MMU_SYS_IDLE_MASK;
++ l |= (MMU_SYS_IDLE_SMART | MMU_SYS_AUTOIDLE);
++ iommu_write_reg(obj, l, MMU_SYSCONFIG);
++
++ iommu_write_reg(obj, MMU_IRQ_MASK, MMU_IRQENABLE);
++ iommu_write_reg(obj, pa, MMU_TTB);
++
++ l = iommu_read_reg(obj, MMU_CNTL);
++ l &= ~MMU_CNTL_MASK;
++ l |= (MMU_CNTL_MMU_EN | MMU_CNTL_TWL_EN);
++ iommu_write_reg(obj, l, MMU_CNTL);
++
++ return 0;
++}
++
++static void omap2_iommu_disable(struct iommu *obj)
++{
++ u32 l = iommu_read_reg(obj, MMU_CNTL);
++
++ l &= ~MMU_CNTL_MASK;
++ iommu_write_reg(obj, l, MMU_CNTL);
++ iommu_write_reg(obj, MMU_SYS_IDLE_FORCE, MMU_SYSCONFIG);
++
++ dev_dbg(obj->dev, "%s is shutting down\n", obj->name);
++}
++
++static u32 omap2_iommu_fault_isr(struct iommu *obj, u32 *ra)
++{
++ int i;
++ u32 stat, da;
++ const char *err_msg[] = {
++ "tlb miss",
++ "translation fault",
++ "emulation miss",
++ "table walk fault",
++ "multi hit fault",
++ };
++
++ stat = iommu_read_reg(obj, MMU_IRQSTATUS);
++ stat &= MMU_IRQ_MASK;
++ if (!stat)
++ return 0;
++
++ da = iommu_read_reg(obj, MMU_FAULT_AD);
++ *ra = da;
++
++ dev_err(obj->dev, "%s:\tda:%08x ", __func__, da);
++
++ for (i = 0; i < ARRAY_SIZE(err_msg); i++) {
++ if (stat & (1 << i))
++ printk("%s ", err_msg[i]);
++ }
++ printk("\n");
++
++ iommu_write_reg(obj, stat, MMU_IRQSTATUS);
++ return stat;
++}
++
++static void omap2_tlb_read_cr(struct iommu *obj, struct cr_regs *cr)
++{
++ cr->cam = iommu_read_reg(obj, MMU_READ_CAM);
++ cr->ram = iommu_read_reg(obj, MMU_READ_RAM);
++}
++
++static void omap2_tlb_load_cr(struct iommu *obj, struct cr_regs *cr)
++{
++ iommu_write_reg(obj, cr->cam | MMU_CAM_V, MMU_CAM);
++ iommu_write_reg(obj, cr->ram, MMU_RAM);
++}
++
++static u32 omap2_cr_to_virt(struct cr_regs *cr)
++{
++ u32 page_size = cr->cam & MMU_CAM_PGSZ_MASK;
++ u32 mask = get_cam_va_mask(cr->cam & page_size);
++
++ return cr->cam & mask;
++}
++
++static struct cr_regs *omap2_alloc_cr(struct iommu *obj, struct iotlb_entry *e)
++{
++ struct cr_regs *cr;
++
++ if (e->da & ~(get_cam_va_mask(e->pgsz))) {
++ dev_err(obj->dev, "%s:\twrong alignment: %08x\n", __func__,
++ e->da);
++ return ERR_PTR(-EINVAL);
++ }
++
++ cr = kmalloc(sizeof(*cr), GFP_KERNEL);
++ if (!cr)
++ return ERR_PTR(-ENOMEM);
++
++ cr->cam = (e->da & MMU_CAM_VATAG_MASK) | e->prsvd | e->pgsz;
++ cr->ram = e->pa | e->endian | e->elsz | e->mixed;
++
++ return cr;
++}
++
++static inline int omap2_cr_valid(struct cr_regs *cr)
++{
++ return cr->cam & MMU_CAM_V;
++}
++
++static u32 omap2_get_pte_attr(struct iotlb_entry *e)
++{
++ u32 attr;
++
++ attr = e->mixed << 5;
++ attr |= e->endian;
++ attr |= e->elsz >> 3;
++ attr <<= ((e->pgsz & MMU_CAM_PGSZ_4K) ? 0 : 6);
++
++ return attr;
++}
++
++static ssize_t omap2_dump_cr(struct iommu *obj, struct cr_regs *cr, char *buf)
++{
++ char *p = buf;
++
++ /* FIXME: Need more detail analysis of cam/ram */
++ p += sprintf(p, "%08x %08x\n", cr->cam, cr->ram);
++
++ return p - buf;
++}
++
++#define pr_reg(name) \
++ p += sprintf(p, "%20s: %08x\n", \
++ __stringify(name), iommu_read_reg(obj, MMU_##name));
++
++static ssize_t omap2_iommu_dump_ctx(struct iommu *obj, char *buf)
++{
++ char *p = buf;
++
++ pr_reg(REVISION);
++ pr_reg(SYSCONFIG);
++ pr_reg(SYSSTATUS);
++ pr_reg(IRQSTATUS);
++ pr_reg(IRQENABLE);
++ pr_reg(WALKING_ST);
++ pr_reg(CNTL);
++ pr_reg(FAULT_AD);
++ pr_reg(TTB);
++ pr_reg(LOCK);
++ pr_reg(LD_TLB);
++ pr_reg(CAM);
++ pr_reg(RAM);
++ pr_reg(GFLUSH);
++ pr_reg(FLUSH_ENTRY);
++ pr_reg(READ_CAM);
++ pr_reg(READ_RAM);
++ pr_reg(EMU_FAULT_AD);
++
++ return p - buf;
++}
++
++static void omap2_iommu_save_ctx(struct iommu *obj)
++{
++ int i;
++ u32 *p = obj->ctx;
++
++ for (i = 0; i < (MMU_REG_SIZE / sizeof(u32)); i++) {
++ p[i] = iommu_read_reg(obj, i * sizeof(u32));
++ dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, p[i]);
++ }
++
++ BUG_ON(p[0] != IOMMU_ARCH_VERSION);
++}
++
++static void omap2_iommu_restore_ctx(struct iommu *obj)
++{
++ int i;
++ u32 *p = obj->ctx;
++
++ for (i = 0; i < (MMU_REG_SIZE / sizeof(u32)); i++) {
++ iommu_write_reg(obj, p[i], i * sizeof(u32));
++ dev_dbg(obj->dev, "%s\t[%02d] %08x\n", __func__, i, p[i]);
++ }
++
++ BUG_ON(p[0] != IOMMU_ARCH_VERSION);
++}
++
++static void omap2_cr_to_e(struct cr_regs *cr, struct iotlb_entry *e)
++{
++ e->da = cr->cam & MMU_CAM_VATAG_MASK;
++ e->pa = cr->ram & MMU_RAM_PADDR_MASK;
++ e->valid = cr->cam & MMU_CAM_V;
++ e->pgsz = cr->cam & MMU_CAM_PGSZ_MASK;
++ e->endian = cr->ram & MMU_RAM_ENDIAN_MASK;
++ e->elsz = cr->ram & MMU_RAM_ELSZ_MASK;
++ e->mixed = cr->ram & MMU_RAM_MIXED;
++}
++
++static const struct iommu_functions omap2_iommu_ops = {
++ .version = IOMMU_ARCH_VERSION,
++
++ .enable = omap2_iommu_enable,
++ .disable = omap2_iommu_disable,
++ .fault_isr = omap2_iommu_fault_isr,
++
++ .tlb_read_cr = omap2_tlb_read_cr,
++ .tlb_load_cr = omap2_tlb_load_cr,
++
++ .cr_to_e = omap2_cr_to_e,
++ .cr_to_virt = omap2_cr_to_virt,
++ .alloc_cr = omap2_alloc_cr,
++ .cr_valid = omap2_cr_valid,
++ .dump_cr = omap2_dump_cr,
++
++ .get_pte_attr = omap2_get_pte_attr,
++
++ .save_ctx = omap2_iommu_save_ctx,
++ .restore_ctx = omap2_iommu_restore_ctx,
++ .dump_ctx = omap2_iommu_dump_ctx,
++};
++
++static int __init omap2_iommu_init(void)
++{
++ return install_iommu_arch(&omap2_iommu_ops);
++}
++module_init(omap2_iommu_init);
++
++static void __exit omap2_iommu_exit(void)
++{
++ uninstall_iommu_arch(&omap2_iommu_ops);
++}
++module_exit(omap2_iommu_exit);
++
++MODULE_AUTHOR("Hiroshi DOYU, Paul Mundt and Toshihiro Kobayashi");
++MODULE_DESCRIPTION("omap iommu: omap2/3 architecture specific functions");
++MODULE_LICENSE("GPL v2");
+diff --git a/arch/arm/plat-omap/include/mach/iommu2.h b/arch/arm/plat-omap/include/mach/iommu2.h
+new file mode 100644
+index 0000000..d746047
+--- /dev/null
++++ b/arch/arm/plat-omap/include/mach/iommu2.h
+@@ -0,0 +1,94 @@
++/*
++ * omap iommu: omap2 architecture specific definitions
++ *
++ * Copyright (C) 2008-2009 Nokia Corporation
++ *
++ * Written by Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2 as
++ * published by the Free Software Foundation.
++ */
++
++#ifndef __MACH_IOMMU2_H
++#define __MACH_IOMMU2_H
++
++/*
++ * MMU Register offsets
++ */
++#define MMU_REVISION 0x00
++#define MMU_SYSCONFIG 0x10
++#define MMU_SYSSTATUS 0x14
++#define MMU_IRQSTATUS 0x18
++#define MMU_IRQENABLE 0x1c
++#define MMU_WALKING_ST 0x40
++#define MMU_CNTL 0x44
++#define MMU_FAULT_AD 0x48
++#define MMU_TTB 0x4c
++#define MMU_LOCK 0x50
++#define MMU_LD_TLB 0x54
++#define MMU_CAM 0x58
++#define MMU_RAM 0x5c
++#define MMU_GFLUSH 0x60
++#define MMU_FLUSH_ENTRY 0x64
++#define MMU_READ_CAM 0x68
++#define MMU_READ_RAM 0x6c
++#define MMU_EMU_FAULT_AD 0x70
++
++#define MMU_REG_SIZE 256
++
++/*
++ * MMU Register bit definitions
++ */
++#define MMU_LOCK_BASE_SHIFT 10
++#define MMU_LOCK_BASE_MASK (0x1f << MMU_LOCK_BASE_SHIFT)
++#define MMU_LOCK_BASE(x) \
++ ((x & MMU_LOCK_BASE_MASK) >> MMU_LOCK_BASE_SHIFT)
++
++#define MMU_LOCK_VICT_SHIFT 4
++#define MMU_LOCK_VICT_MASK (0x1f << MMU_LOCK_VICT_SHIFT)
++#define MMU_LOCK_VICT(x) \
++ ((x & MMU_LOCK_VICT_MASK) >> MMU_LOCK_VICT_SHIFT)
++
++#define MMU_CAM_VATAG_SHIFT 12
++#define MMU_CAM_VATAG_MASK \
++ ((~0UL >> MMU_CAM_VATAG_SHIFT) << MMU_CAM_VATAG_SHIFT)
++#define MMU_CAM_P (1 << 3)
++#define MMU_CAM_V (1 << 2)
++#define MMU_CAM_PGSZ_MASK 3
++#define MMU_CAM_PGSZ_1M (0 << 0)
++#define MMU_CAM_PGSZ_64K (1 << 0)
++#define MMU_CAM_PGSZ_4K (2 << 0)
++#define MMU_CAM_PGSZ_16M (3 << 0)
++
++#define MMU_RAM_PADDR_SHIFT 12
++#define MMU_RAM_PADDR_MASK \
++ ((~0UL >> MMU_RAM_PADDR_SHIFT) << MMU_RAM_PADDR_SHIFT)
++#define MMU_RAM_ENDIAN_SHIFT 9
++#define MMU_RAM_ENDIAN_MASK (1 << MMU_RAM_ENDIAN_SHIFT)
++#define MMU_RAM_ENDIAN_BIG (1 << MMU_RAM_ENDIAN_SHIFT)
++#define MMU_RAM_ENDIAN_LITTLE (0 << MMU_RAM_ENDIAN_SHIFT)
++#define MMU_RAM_ELSZ_SHIFT 7
++#define MMU_RAM_ELSZ_MASK (3 << MMU_RAM_ELSZ_SHIFT)
++#define MMU_RAM_ELSZ_8 (0 << MMU_RAM_ELSZ_SHIFT)
++#define MMU_RAM_ELSZ_16 (1 << MMU_RAM_ELSZ_SHIFT)
++#define MMU_RAM_ELSZ_32 (2 << MMU_RAM_ELSZ_SHIFT)
++#define MMU_RAM_ELSZ_NONE (3 << MMU_RAM_ELSZ_SHIFT)
++#define MMU_RAM_MIXED_SHIFT 6
++#define MMU_RAM_MIXED_MASK (1 << MMU_RAM_MIXED_SHIFT)
++#define MMU_RAM_MIXED MMU_RAM_MIXED_MASK
++
++/*
++ * register accessors
++ */
++static inline u32 iommu_read_reg(struct iommu *obj, size_t offs)
++{
++ return __raw_readl(obj->regbase + offs);
++}
++
++static inline void iommu_write_reg(struct iommu *obj, u32 val, size_t offs)
++{
++ __raw_writel(val, obj->regbase + offs);
++}
++
++#endif /* __MACH_IOMMU2_H */
+--
+1.5.6.5
+