beagleboard: added 2.6.29 kernel from OE

tested on B7

Signed-off-by: Marcin Juszkiewicz <marcin@buglabs.net>
This commit is contained in:
Marcin Juszkiewicz
2009-04-27 16:41:24 +02:00
parent d65be3dd2a
commit 0adc74b062
146 changed files with 156117 additions and 1 deletions

View File

@@ -0,0 +1,153 @@
From 742cc1e62f0d04333c51630f3020da000aeb6de1 Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
Date: Mon, 2 Mar 2009 19:36:26 +0200
Subject: [PATCH] omap3: Add base address definitions and resources for OMAP 3 ISP
This replaces earlier patch from Sergio Aguirre titled "[REVIEW PATCH 03/14]
OMAP34XX: CAM: Resources fixes".
Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
arch/arm/mach-omap2/devices.c | 66 ++++++++++++++++++++++++---
arch/arm/plat-omap/include/mach/omap34xx.h | 28 +++++++++++-
2 files changed, 85 insertions(+), 9 deletions(-)
diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c
index dad4528..2568b0c 100644
--- a/arch/arm/mach-omap2/devices.c
+++ b/arch/arm/mach-omap2/devices.c
@@ -56,10 +56,60 @@ static inline void omap_init_camera(void)
#elif defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
-static struct resource cam_resources[] = {
+static struct resource omap3isp_resources[] = {
+ {
+ .start = OMAP3430_ISP_BASE,
+ .end = OMAP3430_ISP_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CBUFF_BASE,
+ .end = OMAP3430_ISP_CBUFF_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CCP2_BASE,
+ .end = OMAP3430_ISP_CCP2_END,
+ .flags = IORESOURCE_MEM,
+ },
{
- .start = OMAP34XX_CAMERA_BASE,
- .end = OMAP34XX_CAMERA_BASE + 0x1B70,
+ .start = OMAP3430_ISP_CCDC_BASE,
+ .end = OMAP3430_ISP_CCDC_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_HIST_BASE,
+ .end = OMAP3430_ISP_HIST_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_H3A_BASE,
+ .end = OMAP3430_ISP_H3A_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_PREV_BASE,
+ .end = OMAP3430_ISP_PREV_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_RESZ_BASE,
+ .end = OMAP3430_ISP_RESZ_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_SBL_BASE,
+ .end = OMAP3430_ISP_SBL_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CSI2A_BASE,
+ .end = OMAP3430_ISP_CSI2A_END,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3430_ISP_CSI2PHY_BASE,
+ .end = OMAP3430_ISP_CSI2PHY_END,
.flags = IORESOURCE_MEM,
},
{
@@ -68,16 +118,16 @@ static struct resource cam_resources[] = {
}
};
-static struct platform_device omap_cam_device = {
- .name = "omap34xxcam",
+static struct platform_device omap3isp_device = {
+ .name = "omap3isp",
.id = -1,
- .num_resources = ARRAY_SIZE(cam_resources),
- .resource = cam_resources,
+ .num_resources = ARRAY_SIZE(omap3isp_resources),
+ .resource = omap3isp_resources,
};
static inline void omap_init_camera(void)
{
- platform_device_register(&omap_cam_device);
+ platform_device_register(&omap3isp_device);
}
#else
static inline void omap_init_camera(void)
diff --git a/arch/arm/plat-omap/include/mach/omap34xx.h b/arch/arm/plat-omap/include/mach/omap34xx.h
index 27a1e45..3bfbdf7 100644
--- a/arch/arm/plat-omap/include/mach/omap34xx.h
+++ b/arch/arm/plat-omap/include/mach/omap34xx.h
@@ -49,6 +49,33 @@
#define OMAP343X_CTRL_BASE OMAP343X_SCM_BASE
#define OMAP34XX_IC_BASE 0x48200000
+
+#define OMAP3430_ISP_BASE (L4_34XX_BASE + 0xBC000)
+#define OMAP3430_ISP_CBUFF_BASE (OMAP3430_ISP_BASE + 0x0100)
+#define OMAP3430_ISP_CCP2_BASE (OMAP3430_ISP_BASE + 0x0400)
+#define OMAP3430_ISP_CCDC_BASE (OMAP3430_ISP_BASE + 0x0600)
+#define OMAP3430_ISP_HIST_BASE (OMAP3430_ISP_BASE + 0x0A00)
+#define OMAP3430_ISP_H3A_BASE (OMAP3430_ISP_BASE + 0x0C00)
+#define OMAP3430_ISP_PREV_BASE (OMAP3430_ISP_BASE + 0x0E00)
+#define OMAP3430_ISP_RESZ_BASE (OMAP3430_ISP_BASE + 0x1000)
+#define OMAP3430_ISP_SBL_BASE (OMAP3430_ISP_BASE + 0x1200)
+#define OMAP3430_ISP_MMU_BASE (OMAP3430_ISP_BASE + 0x1400)
+#define OMAP3430_ISP_CSI2A_BASE (OMAP3430_ISP_BASE + 0x1800)
+#define OMAP3430_ISP_CSI2PHY_BASE (OMAP3430_ISP_BASE + 0x1970)
+
+#define OMAP3430_ISP_END (OMAP3430_ISP_BASE + 0x06F)
+#define OMAP3430_ISP_CBUFF_END (OMAP3430_ISP_CBUFF_BASE + 0x077)
+#define OMAP3430_ISP_CCP2_END (OMAP3430_ISP_CCP2_BASE + 0x1EF)
+#define OMAP3430_ISP_CCDC_END (OMAP3430_ISP_CCDC_BASE + 0x0A7)
+#define OMAP3430_ISP_HIST_END (OMAP3430_ISP_HIST_BASE + 0x047)
+#define OMAP3430_ISP_H3A_END (OMAP3430_ISP_H3A_BASE + 0x05F)
+#define OMAP3430_ISP_PREV_END (OMAP3430_ISP_PREV_BASE + 0x09F)
+#define OMAP3430_ISP_RESZ_END (OMAP3430_ISP_RESZ_BASE + 0x0AB)
+#define OMAP3430_ISP_SBL_END (OMAP3430_ISP_SBL_BASE + 0x0FB)
+#define OMAP3430_ISP_MMU_END (OMAP3430_ISP_MMU_BASE + 0x06F)
+#define OMAP3430_ISP_CSI2A_END (OMAP3430_ISP_CSI2A_BASE + 0x16F)
+#define OMAP3430_ISP_CSI2PHY_END (OMAP3430_ISP_CSI2PHY_BASE + 0x007)
+
#define OMAP34XX_IVA_INTC_BASE 0x40000000
#define OMAP34XX_HSUSB_OTG_BASE (L4_34XX_BASE + 0xAB000)
#define OMAP34XX_HSUSB_HOST_BASE (L4_34XX_BASE + 0x64000)
@@ -56,7 +83,6 @@
#define OMAP34XX_SR1_BASE 0x480C9000
#define OMAP34XX_SR2_BASE 0x480CB000
-#define OMAP34XX_CAMERA_BASE (L4_34XX_BASE + 0xBC000)
#define OMAP34XX_MAILBOX_BASE (L4_34XX_BASE + 0x94000)
--
1.5.6.5

View File

@@ -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

View File

@@ -0,0 +1,124 @@
From 6a84082597dd322713c5d5951530e3eecb878ad4 Mon Sep 17 00:00:00 2001
From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
Date: Wed, 28 Jan 2009 21:32:04 +0200
Subject: [PATCH] omap iommu: omap3 iommu device registration
Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
---
arch/arm/mach-omap2/omap3-iommu.c | 104 +++++++++++++++++++++++++++++++++++++
1 files changed, 104 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-omap2/omap3-iommu.c
diff --git a/arch/arm/mach-omap2/omap3-iommu.c b/arch/arm/mach-omap2/omap3-iommu.c
new file mode 100644
index 0000000..97481cc
--- /dev/null
+++ b/arch/arm/mach-omap2/omap3-iommu.c
@@ -0,0 +1,104 @@
+/*
+ * omap iommu: omap3 device registration
+ *
+ * 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.
+ */
+
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <mach/iommu.h>
+
+#define OMAP3_MMU1_BASE 0x480bd400
+#define OMAP3_MMU2_BASE 0x5d000000
+#define OMAP3_MMU1_IRQ 24
+#define OMAP3_MMU2_IRQ 28
+
+static struct resource omap3_iommu_res[] = {
+ { /* Camera ISP MMU */
+ .start = OMAP3_MMU1_BASE,
+ .end = OMAP3_MMU1_BASE + MMU_REG_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3_MMU1_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+ { /* IVA2.2 MMU */
+ .start = OMAP3_MMU2_BASE,
+ .end = OMAP3_MMU2_BASE + MMU_REG_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = OMAP3_MMU2_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+#define NR_IOMMU_RES (ARRAY_SIZE(omap3_iommu_res) / 2)
+
+static const struct iommu_platform_data omap3_iommu_pdata[] __initconst = {
+ {
+ .name = "isp",
+ .nr_tlb_entries = 8,
+ .clk_name = "cam_ick",
+ },
+ {
+ .name = "iva2",
+ .nr_tlb_entries = 32,
+ .clk_name = "iva2_ck",
+ },
+};
+#define NR_IOMMU_DEVICES ARRAY_SIZE(omap3_iommu_pdata)
+
+static struct platform_device *omap3_iommu_pdev[NR_IOMMU_DEVICES];
+
+static int __init omap3_iommu_init(void)
+{
+ int i, err;
+
+ for (i = 0; i < NR_IOMMU_DEVICES; i++) {
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc("omap-iommu", i + 1);
+ if (!pdev)
+ goto err_out;
+ err = platform_device_add_resources(pdev,
+ &omap3_iommu_res[2 * i], NR_IOMMU_RES);
+ if (err)
+ goto err_out;
+ err = platform_device_add_data(pdev, &omap3_iommu_pdata[i],
+ sizeof(omap3_iommu_pdata[0]));
+ if (err)
+ goto err_out;
+ err = platform_device_add(pdev);
+ if (err)
+ goto err_out;
+ omap3_iommu_pdev[i] = pdev;
+ }
+ return 0;
+
+err_out:
+ while (i--)
+ platform_device_put(omap3_iommu_pdev[i]);
+ return err;
+}
+module_init(omap3_iommu_init);
+
+static void __exit omap3_iommu_exit(void)
+{
+ int i;
+
+ for (i = 0; i < NR_IOMMU_DEVICES; i++)
+ platform_device_unregister(omap3_iommu_pdev[i]);
+}
+module_exit(omap3_iommu_exit);
+
+MODULE_AUTHOR("Hiroshi DOYU");
+MODULE_DESCRIPTION("omap iommu: omap3 device registration");
+MODULE_LICENSE("GPL v2");
--
1.5.6.5

View File

@@ -0,0 +1,45 @@
From 7de046a6a8446358001c38ad1d0b2b829ca0c98c Mon Sep 17 00:00:00 2001
From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
Date: Wed, 28 Jan 2009 21:32:08 +0200
Subject: [PATCH] omap iommu: entries for Kconfig and Makefile
Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
---
arch/arm/plat-omap/Kconfig | 8 ++++++++
arch/arm/plat-omap/Makefile | 1 +
2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index b16ae76..2090bb5 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -176,6 +176,14 @@ config OMAP_MBOX_FWK
Say Y here if you want to use OMAP Mailbox framework support for
DSP, IVA1.0 and IVA2 in OMAP1/2/3.
+config OMAP_IOMMU
+ tristate "IOMMU support"
+ depends on ARCH_OMAP
+ default n
+ help
+ Say Y here if you want to use OMAP IOMMU support for IVA2 and
+ Camera in OMAP3.
+
choice
prompt "System timer"
default OMAP_MPU_TIMER
diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
index 3ebc09e..aa8f6df 100644
--- a/arch/arm/plat-omap/Makefile
+++ b/arch/arm/plat-omap/Makefile
@@ -13,6 +13,7 @@ obj- :=
obj-$(CONFIG_ARCH_OMAP16XX) += ocpi.o
obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
+obj-$(CONFIG_OMAP_IOMMU) += iommu.o iovmm.o
obj-$(CONFIG_CPU_FREQ) += cpu-omap.o
obj-$(CONFIG_OMAP_DM_TIMER) += dmtimer.o
--
1.5.6.5

View File

@@ -0,0 +1,26 @@
From b03f695e25bbdaa95a2cc87e15ee8592e7ca128d Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
Date: Tue, 10 Feb 2009 18:01:29 +0200
Subject: [PATCH] omap iommu: Don't try BUG_ON(in_interrupt())
Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
arch/arm/plat-omap/iovmm.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/arch/arm/plat-omap/iovmm.c b/arch/arm/plat-omap/iovmm.c
index 6726d10..bdfbb09 100644
--- a/arch/arm/plat-omap/iovmm.c
+++ b/arch/arm/plat-omap/iovmm.c
@@ -523,8 +523,6 @@ static struct sg_table *unmap_vm_area(struct iommu *obj, const u32 da,
struct sg_table *sgt = NULL;
struct iovm_struct *area;
- BUG_ON(in_interrupt());
-
if (!IS_ALIGNED(da, PAGE_SIZE)) {
dev_err(obj->dev, "%s: alignment err(%08x)\n", __func__, da);
return NULL;
--
1.5.6.5

View File

@@ -0,0 +1,24 @@
From 24f984f784cae1a4515fe1be8db1ac24cdf51e84 Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
Date: Tue, 10 Feb 2009 18:37:41 +0200
Subject: [PATCH] omap iommu: We support chained scatterlists, probably. :)
Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
arch/arm/include/asm/scatterlist.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/scatterlist.h b/arch/arm/include/asm/scatterlist.h
index ca0a37d..393f8b8 100644
--- a/arch/arm/include/asm/scatterlist.h
+++ b/arch/arm/include/asm/scatterlist.h
@@ -24,4 +24,6 @@ struct scatterlist {
#define sg_dma_address(sg) ((sg)->dma_address)
#define sg_dma_len(sg) ((sg)->length)
+#define ARCH_HAS_SG_CHAIN
+
#endif /* _ASMARM_SCATTERLIST_H */
--
1.5.6.5

View File

@@ -0,0 +1,29 @@
From 3c65ff4a684d3e0f4d9c59e731975408452c3743 Mon Sep 17 00:00:00 2001
From: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
Date: Wed, 28 Jan 2009 21:32:09 +0200
Subject: [PATCH] omap2 iommu: entries for Kconfig and Makefile
Signed-off-by: Hiroshi DOYU <Hiroshi.DOYU@nokia.com>
---
arch/arm/mach-omap2/Makefile | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index b44bb78..33b5aa8 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -38,6 +38,11 @@ obj-$(CONFIG_ARCH_OMAP3) += clock34xx.o
obj-$(CONFIG_OMAP_MBOX_FWK) += mailbox_mach.o
mailbox_mach-objs := mailbox.o
+iommu-y += iommu2.o
+iommu-$(CONFIG_ARCH_OMAP3) += omap3-iommu.o
+
+obj-$(CONFIG_OMAP_IOMMU) += $(iommu-y)
+
# Specific board support
obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o
obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o board-h4-mmc.o
--
1.5.6.5

View File

@@ -0,0 +1,209 @@
From 731527a7dc26533a878c7c5f36fc148fdcaa21b8 Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
Date: Tue, 10 Mar 2009 10:49:02 +0200
Subject: [PATCH] omap3isp: Add ISP MMU wrapper
TODO:
- The ISP driver should start using the IOMMU directly without this wrapper.
Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
drivers/media/video/isp/ispmmu.c | 141 ++++++++++++++++++++++++++++++++++++++
drivers/media/video/isp/ispmmu.h | 36 ++++++++++
2 files changed, 177 insertions(+), 0 deletions(-)
create mode 100644 drivers/media/video/isp/ispmmu.c
create mode 100644 drivers/media/video/isp/ispmmu.h
diff --git a/drivers/media/video/isp/ispmmu.c b/drivers/media/video/isp/ispmmu.c
new file mode 100644
index 0000000..f872c71
--- /dev/null
+++ b/drivers/media/video/isp/ispmmu.c
@@ -0,0 +1,141 @@
+/*
+ * omap iommu wrapper for TI's OMAP3430 Camera ISP
+ *
+ * Copyright (C) 2008--2009 Nokia.
+ *
+ * Contributors:
+ * Hiroshi Doyu <hiroshi.doyu@nokia.com>
+ * Sakari Ailus <sakari.ailus@nokia.com>
+ *
+ * This package 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.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#include <linux/module.h>
+
+#include "ispmmu.h"
+#include "isp.h"
+
+#include <mach/iommu.h>
+#include <mach/iovmm.h>
+
+#define IOMMU_FLAG (IOVMF_ENDIAN_LITTLE | IOVMF_ELSZ_8)
+
+static struct iommu *isp_iommu;
+
+dma_addr_t ispmmu_vmalloc(size_t bytes)
+{
+ return (dma_addr_t)iommu_vmalloc(isp_iommu, 0, bytes, IOMMU_FLAG);
+}
+
+void ispmmu_vfree(const dma_addr_t da)
+{
+ iommu_vfree(isp_iommu, (u32)da);
+}
+
+dma_addr_t ispmmu_kmap(u32 pa, int size)
+{
+ void *da;
+
+ da = (void *)iommu_kmap(isp_iommu, 0, pa, size, IOMMU_FLAG);
+ if (IS_ERR(da))
+ return PTR_ERR(da);
+
+ return (dma_addr_t)da;
+}
+
+void ispmmu_kunmap(dma_addr_t da)
+{
+ iommu_kunmap(isp_iommu, (u32)da);
+}
+
+dma_addr_t ispmmu_vmap(const struct scatterlist *sglist,
+ int sglen)
+{
+ int err;
+ void *da;
+ struct sg_table *sgt;
+ unsigned int i;
+ struct scatterlist *sg, *src = (struct scatterlist *)sglist;
+
+ /*
+ * convert isp sglist to iommu sgt
+ * FIXME: should be fixed in the upper layer?
+ */
+ sgt = kmalloc(sizeof(*sgt), GFP_KERNEL);
+ if (!sgt)
+ return -ENOMEM;
+ err = sg_alloc_table(sgt, sglen, GFP_KERNEL);
+ if (err)
+ goto err_sg_alloc;
+
+ for_each_sg(sgt->sgl, sg, sgt->nents, i)
+ sg_set_buf(sg, phys_to_virt(sg_dma_address(src + i)),
+ sg_dma_len(src + i));
+
+ da = (void *)iommu_vmap(isp_iommu, 0, sgt, IOMMU_FLAG);
+ if (IS_ERR(da))
+ goto err_vmap;
+
+ return (dma_addr_t)da;
+
+err_vmap:
+ sg_free_table(sgt);
+err_sg_alloc:
+ kfree(sgt);
+ return -ENOMEM;
+}
+EXPORT_SYMBOL_GPL(ispmmu_vmap);
+
+void ispmmu_vunmap(dma_addr_t da)
+{
+ struct sg_table *sgt;
+
+ sgt = iommu_vunmap(isp_iommu, (u32)da);
+ if (!sgt)
+ return;
+ sg_free_table(sgt);
+ kfree(sgt);
+}
+EXPORT_SYMBOL_GPL(ispmmu_vunmap);
+
+void ispmmu_save_context(void)
+{
+ if (isp_iommu)
+ iommu_save_ctx(isp_iommu);
+}
+
+void ispmmu_restore_context(void)
+{
+ if (isp_iommu)
+ iommu_restore_ctx(isp_iommu);
+}
+
+int __init ispmmu_init(void)
+{
+ int err = 0;
+
+ isp_get();
+ isp_iommu = iommu_get("isp");
+ if (IS_ERR(isp_iommu)) {
+ err = PTR_ERR(isp_iommu);
+ isp_iommu = NULL;
+ }
+ isp_put();
+
+ return err;
+}
+
+void ispmmu_cleanup(void)
+{
+ isp_get();
+ if (isp_iommu)
+ iommu_put(isp_iommu);
+ isp_put();
+ isp_iommu = NULL;
+}
diff --git a/drivers/media/video/isp/ispmmu.h b/drivers/media/video/isp/ispmmu.h
new file mode 100644
index 0000000..0bc5bcb
--- /dev/null
+++ b/drivers/media/video/isp/ispmmu.h
@@ -0,0 +1,36 @@
+/*
+ * omap iommu wrapper for TI's OMAP3430 Camera ISP
+ *
+ * Copyright (C) 2008--2009 Nokia.
+ *
+ * Contributors:
+ * Hiroshi Doyu <hiroshi.doyu@nokia.com>
+ * Sakari Ailus <sakari.ailus@nokia.com>
+ *
+ * This package 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.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef OMAP_ISP_MMU_H
+#define OMAP_ISP_MMU_H
+
+#include <linux/err.h>
+#include <linux/scatterlist.h>
+
+dma_addr_t ispmmu_vmalloc(size_t bytes);
+void ispmmu_vfree(const dma_addr_t da);
+dma_addr_t ispmmu_kmap(u32 pa, int size);
+void ispmmu_kunmap(dma_addr_t da);
+dma_addr_t ispmmu_vmap(const struct scatterlist *sglist, int sglen);
+void ispmmu_vunmap(dma_addr_t da);
+void ispmmu_save_context(void);
+void ispmmu_restore_context(void);
+int ispmmu_init(void);
+void ispmmu_cleanup(void);
+
+#endif /* OMAP_ISP_MMU_H */
--
1.5.6.5

View File

@@ -0,0 +1,696 @@
From 98ca1ef8c6e2561989aeef981131cf5077eab1d1 Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
Date: Tue, 10 Mar 2009 10:49:02 +0200
Subject: [PATCH] omap3isp: Add userspace header
Signed-off-by: Sakari Ailus <sakari.ailus@maxwell.research.nokia.com>
---
arch/arm/plat-omap/include/mach/isp_user.h | 676 ++++++++++++++++++++++++++++
1 files changed, 676 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/plat-omap/include/mach/isp_user.h
diff --git a/arch/arm/plat-omap/include/mach/isp_user.h b/arch/arm/plat-omap/include/mach/isp_user.h
new file mode 100644
index 0000000..b819e26
--- /dev/null
+++ b/arch/arm/plat-omap/include/mach/isp_user.h
@@ -0,0 +1,676 @@
+/*
+ * isp_user.h
+ *
+ * Include file for OMAP ISP module in TI's OMAP3.
+ *
+ * Copyright (C) 2009 Texas Instruments, Inc.
+ *
+ * Contributors:
+ * Mohit Jalori <mjalori@ti.com>
+ * Sergio Aguirre <saaguirre@ti.com>
+ *
+ * This package 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.
+ *
+ * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef OMAP_ISP_USER_H
+#define OMAP_ISP_USER_H
+
+/* ISP Private IOCTLs */
+#define VIDIOC_PRIVATE_ISP_CCDC_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct ispccdc_update_config)
+#define VIDIOC_PRIVATE_ISP_PRV_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 2, struct ispprv_update_config)
+#define VIDIOC_PRIVATE_ISP_AEWB_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 4, struct isph3a_aewb_config)
+#define VIDIOC_PRIVATE_ISP_AEWB_REQ \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 5, struct isph3a_aewb_data)
+#define VIDIOC_PRIVATE_ISP_HIST_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 6, struct isp_hist_config)
+#define VIDIOC_PRIVATE_ISP_HIST_REQ \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 7, struct isp_hist_data)
+#define VIDIOC_PRIVATE_ISP_AF_CFG \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 8, struct af_configuration)
+#define VIDIOC_PRIVATE_ISP_AF_REQ \
+ _IOWR('V', BASE_VIDIOC_PRIVATE + 9, struct isp_af_data)
+
+/* AE/AWB related structures and flags*/
+
+/* Flags for update field */
+#define REQUEST_STATISTICS (1 << 0)
+#define SET_COLOR_GAINS (1 << 1)
+#define SET_DIGITAL_GAIN (1 << 2)
+#define SET_EXPOSURE (1 << 3)
+#define SET_ANALOG_GAIN (1 << 4)
+
+#define MAX_FRAME_COUNT 0x0FFF
+#define MAX_FUTURE_FRAMES 10
+
+#define MAX_SATURATION_LIM 1023
+#define MIN_WIN_H 2
+#define MAX_WIN_H 256
+#define MIN_WIN_W 6
+#define MAX_WIN_W 256
+#define MAX_WINVC 128
+#define MAX_WINHC 36
+#define MAX_WINSTART 4095
+#define MIN_SUB_INC 2
+#define MAX_SUB_INC 32
+
+/* Range Constants */
+#define AF_IIRSH_MIN 0
+#define AF_IIRSH_MAX 4094
+#define AF_PAXEL_HORIZONTAL_COUNT_MIN 0
+#define AF_PAXEL_HORIZONTAL_COUNT_MAX 35
+#define AF_PAXEL_VERTICAL_COUNT_MIN 0
+#define AF_PAXEL_VERTICAL_COUNT_MAX 127
+#define AF_PAXEL_INCREMENT_MIN 0
+#define AF_PAXEL_INCREMENT_MAX 14
+#define AF_PAXEL_HEIGHT_MIN 0
+#define AF_PAXEL_HEIGHT_MAX 127
+#define AF_PAXEL_WIDTH_MIN 0
+#define AF_PAXEL_WIDTH_MAX 127
+#define AF_PAXEL_HZSTART_MIN 2
+#define AF_PAXEL_HZSTART_MAX 4094
+
+#define AF_PAXEL_VTSTART_MIN 0
+#define AF_PAXEL_VTSTART_MAX 4095
+#define AF_THRESHOLD_MAX 255
+#define AF_COEF_MAX 4095
+#define AF_PAXEL_SIZE 48
+
+/**
+ * struct isph3a_aewb_config - AE AWB configuration reset values.
+ * saturation_limit: Saturation limit.
+ * @win_height: Window Height. Range 2 - 256, even values only.
+ * @win_width: Window Width. Range 6 - 256, even values only.
+ * @ver_win_count: Vertical Window Count. Range 1 - 128.
+ * @hor_win_count: Horizontal Window Count. Range 1 - 36.
+ * @ver_win_start: Vertical Window Start. Range 0 - 4095.
+ * @hor_win_start: Horizontal Window Start. Range 0 - 4095.
+ * @blk_ver_win_start: Black Vertical Windows Start. Range 0 - 4095.
+ * @blk_win_height: Black Window Height. Range 2 - 256, even values only.
+ * @subsample_ver_inc: Subsample Vertical points increment Range 2 - 32, even
+ * values only.
+ * @subsample_hor_inc: Subsample Horizontal points increment Range 2 - 32, even
+ * values only.
+ * @alaw_enable: AEW ALAW EN flag.
+ * @aewb_enable: AE AWB stats generation EN flag.
+ */
+struct isph3a_aewb_config {
+ __u16 saturation_limit;
+ __u16 win_height;
+ __u16 win_width;
+ __u16 ver_win_count;
+ __u16 hor_win_count;
+ __u16 ver_win_start;
+ __u16 hor_win_start;
+ __u16 blk_ver_win_start;
+ __u16 blk_win_height;
+ __u16 subsample_ver_inc;
+ __u16 subsample_hor_inc;
+ __u8 alaw_enable;
+ __u8 aewb_enable;
+};
+
+/**
+ * struct isph3a_aewb_data - Structure of data sent to or received from user
+ * @h3a_aewb_statistics_buf: Pointer to pass to user.
+ * @shutter: Shutter speed.
+ * @gain: Sensor analog Gain.
+ * @shutter_cap: Shutter speed for capture.
+ * @gain_cap: Sensor Gain for capture.
+ * @dgain: White balance digital gain.
+ * @wb_gain_b: White balance color gain blue.
+ * @wb_gain_r: White balance color gain red.
+ * @wb_gain_gb: White balance color gain green blue.
+ * @wb_gain_gr: White balance color gain green red.
+ * @frame_number: Frame number of requested stats.
+ * @curr_frame: Current frame number being processed.
+ * @update: Bitwise flags to update parameters.
+ * @ts: Timestamp of returned framestats.
+ * @field_count: Sequence number of returned framestats.
+ */
+struct isph3a_aewb_data {
+ void *h3a_aewb_statistics_buf;
+ __u32 shutter;
+ __u16 gain;
+ __u32 shutter_cap;
+ __u16 gain_cap;
+ __u16 dgain;
+ __u16 wb_gain_b;
+ __u16 wb_gain_r;
+ __u16 wb_gain_gb;
+ __u16 wb_gain_gr;
+ __u16 frame_number;
+ __u16 curr_frame;
+ __u8 update;
+ struct timeval ts;
+ __u32 config_counter;
+ unsigned long field_count;
+};
+
+
+/* Histogram related structs */
+/* Flags for number of bins */
+#define BINS_32 0x0
+#define BINS_64 0x1
+#define BINS_128 0x2
+#define BINS_256 0x3
+
+struct isp_hist_config {
+ __u8 hist_source; /* CCDC or Memory */
+ __u8 input_bit_width; /* Needed o know the size per pixel */
+ __u8 hist_frames; /* Num of frames to be processed and
+ * accumulated
+ */
+ __u8 hist_h_v_info; /* frame-input width and height if source is
+ * memory
+ */
+ __u16 hist_radd; /* frame-input address in memory */
+ __u16 hist_radd_off; /* line-offset for frame-input */
+ __u16 hist_bins; /* number of bins: 32, 64, 128, or 256 */
+ __u16 wb_gain_R; /* White Balance Field-to-Pattern Assignments */
+ __u16 wb_gain_RG; /* White Balance Field-to-Pattern Assignments */
+ __u16 wb_gain_B; /* White Balance Field-to-Pattern Assignments */
+ __u16 wb_gain_BG; /* White Balance Field-to-Pattern Assignments */
+ __u8 num_regions; /* number of regions to be configured */
+ __u16 reg0_hor; /* Region 0 size and position */
+ __u16 reg0_ver; /* Region 0 size and position */
+ __u16 reg1_hor; /* Region 1 size and position */
+ __u16 reg1_ver; /* Region 1 size and position */
+ __u16 reg2_hor; /* Region 2 size and position */
+ __u16 reg2_ver; /* Region 2 size and position */
+ __u16 reg3_hor; /* Region 3 size and position */
+ __u16 reg3_ver; /* Region 3 size and position */
+};
+
+struct isp_hist_data {
+ __u32 *hist_statistics_buf; /* Pointer to pass to user */
+};
+
+/* Auto Focus related structs */
+
+#define AF_NUMBER_OF_COEF 11
+
+/* Flags for update field */
+#define REQUEST_STATISTICS (1 << 0)
+#define LENS_DESIRED_POSITION (1 << 1)
+#define LENS_CURRENT_POSITION (1 << 2)
+
+/**
+ * struct isp_af_xtrastats - Extra statistics related to AF generated stats.
+ * @ts: Timestamp when the frame gets delivered to the user.
+ * @field_count: Field count of the frame delivered to the user.
+ * @lens_position: Lens position when the stats are being generated.
+ */
+struct isp_af_xtrastats {
+ struct timeval ts;
+ unsigned long field_count;
+ __u16 lens_position; /* deprecated */
+};
+
+/**
+ * struct isp_af_data - AF statistics data to transfer between driver and user.
+ * @af_statistics_buf: Pointer to pass to user.
+ * @lens_current_position: Read value of lens absolute position.
+ * @desired_lens_direction: Lens desired location.
+ * @update: Bitwise flags to update parameters.
+ * @frame_number: Data for which frame is desired/given.
+ * @curr_frame: Current frame number being processed by AF module.
+ * @xtrastats: Extra statistics structure.
+ */
+struct isp_af_data {
+ void *af_statistics_buf;
+ __u16 lens_current_position; /* deprecated */
+ __u16 desired_lens_direction; /* deprecated */
+ __u16 update;
+ __u16 frame_number;
+ __u16 curr_frame;
+ __u32 config_counter;
+ struct isp_af_xtrastats xtrastats;
+};
+
+/* enum used for status of specific feature */
+enum af_alaw_enable {
+ H3A_AF_ALAW_DISABLE = 0,
+ H3A_AF_ALAW_ENABLE = 1
+};
+
+enum af_hmf_enable {
+ H3A_AF_HMF_DISABLE = 0,
+ H3A_AF_HMF_ENABLE = 1
+};
+
+enum af_config_flag {
+ H3A_AF_CFG_DISABLE = 0,
+ H3A_AF_CFG_ENABLE = 1
+};
+
+enum af_mode {
+ ACCUMULATOR_SUMMED = 0,
+ ACCUMULATOR_PEAK = 1
+};
+
+/* Red, Green, and blue pixel location in the AF windows */
+enum rgbpos {
+ GR_GB_BAYER = 0, /* GR and GB as Bayer pattern */
+ RG_GB_BAYER = 1, /* RG and GB as Bayer pattern */
+ GR_BG_BAYER = 2, /* GR and BG as Bayer pattern */
+ RG_BG_BAYER = 3, /* RG and BG as Bayer pattern */
+ GG_RB_CUSTOM = 4, /* GG and RB as custom pattern */
+ RB_GG_CUSTOM = 5 /* RB and GG as custom pattern */
+};
+
+/* Contains the information regarding the Horizontal Median Filter */
+struct af_hmf {
+ enum af_hmf_enable enable; /* Status of Horizontal Median Filter */
+ unsigned int threshold; /* Threshhold Value for Horizontal Median
+ * Filter
+ */
+};
+
+/* Contains the information regarding the IIR Filters */
+struct af_iir {
+ unsigned int hz_start_pos; /* IIR Start Register Value */
+ int coeff_set0[AF_NUMBER_OF_COEF]; /*
+ * IIR Filter Coefficient for
+ * Set 0
+ */
+ int coeff_set1[AF_NUMBER_OF_COEF]; /*
+ * IIR Filter Coefficient for
+ * Set 1
+ */
+};
+
+/* Contains the information regarding the Paxels Structure in AF Engine */
+struct af_paxel {
+ unsigned int width; /* Width of the Paxel */
+ unsigned int height; /* Height of the Paxel */
+ unsigned int hz_start; /* Horizontal Start Position */
+ unsigned int vt_start; /* Vertical Start Position */
+ unsigned int hz_cnt; /* Horizontal Count */
+ unsigned int vt_cnt; /* vertical Count */
+ unsigned int line_incr; /* Line Increment */
+};
+/* Contains the parameters required for hardware set up of AF Engine */
+struct af_configuration {
+ enum af_alaw_enable alaw_enable; /*ALWAW status */
+ struct af_hmf hmf_config; /*HMF configurations */
+ enum rgbpos rgb_pos; /*RGB Positions */
+ struct af_iir iir_config; /*IIR filter configurations */
+ struct af_paxel paxel_config; /*Paxel parameters */
+ enum af_mode mode; /*Accumulator mode */
+ enum af_config_flag af_config; /*Flag indicates Engine is configured */
+};
+
+/* ISP CCDC structs */
+
+/* Abstraction layer CCDC configurations */
+#define ISP_ABS_CCDC_ALAW (1 << 0)
+#define ISP_ABS_CCDC_LPF (1 << 1)
+#define ISP_ABS_CCDC_BLCLAMP (1 << 2)
+#define ISP_ABS_CCDC_BCOMP (1 << 3)
+#define ISP_ABS_CCDC_FPC (1 << 4)
+#define ISP_ABS_CCDC_CULL (1 << 5)
+#define ISP_ABS_CCDC_COLPTN (1 << 6)
+#define ISP_ABS_CCDC_CONFIG_LSC (1 << 7)
+#define ISP_ABS_TBL_LSC (1 << 8)
+
+#define RGB_MAX 3
+
+/* Enumeration constants for Alaw input width */
+enum alaw_ipwidth {
+ ALAW_BIT12_3 = 0x3,
+ ALAW_BIT11_2 = 0x4,
+ ALAW_BIT10_1 = 0x5,
+ ALAW_BIT9_0 = 0x6
+};
+
+/* Enumeration constants for Video Port */
+enum vpin {
+ BIT12_3 = 3,
+ BIT11_2 = 4,
+ BIT10_1 = 5,
+ BIT9_0 = 6
+};
+
+enum vpif_freq {
+ PIXCLKBY2,
+ PIXCLKBY3_5,
+ PIXCLKBY4_5,
+ PIXCLKBY5_5,
+ PIXCLKBY6_5
+};
+
+/**
+ * struct ispccdc_lsc_config - Structure for LSC configuration.
+ * @offset: Table Offset of the gain table.
+ * @gain_mode_n: Vertical dimension of a paxel in LSC configuration.
+ * @gain_mode_m: Horizontal dimension of a paxel in LSC configuration.
+ * @gain_format: Gain table format.
+ * @fmtsph: Start pixel horizontal from start of the HS sync pulse.
+ * @fmtlnh: Number of pixels in horizontal direction to use for the data
+ * reformatter.
+ * @fmtslv: Start line from start of VS sync pulse for the data reformatter.
+ * @fmtlnv: Number of lines in vertical direction for the data reformatter.
+ * @initial_x: X position, in pixels, of the first active pixel in reference
+ * to the first active paxel. Must be an even number.
+ * @initial_y: Y position, in pixels, of the first active pixel in reference
+ * to the first active paxel. Must be an even number.
+ * @size: Size of LSC gain table. Filled when loaded from userspace.
+ */
+struct ispccdc_lsc_config {
+ __u16 offset;
+ __u8 gain_mode_n;
+ __u8 gain_mode_m;
+ __u8 gain_format;
+ __u16 fmtsph;
+ __u16 fmtlnh;
+ __u16 fmtslv;
+ __u16 fmtlnv;
+ __u8 initial_x;
+ __u8 initial_y;
+ __u32 size;
+};
+
+/**
+ * struct ispccdc_bclamp - Structure for Optical & Digital black clamp subtract
+ * @obgain: Optical black average gain.
+ * @obstpixel: Start Pixel w.r.t. HS pulse in Optical black sample.
+ * @oblines: Optical Black Sample lines.
+ * @oblen: Optical Black Sample Length.
+ * @dcsubval: Digital Black Clamp subtract value.
+ */
+struct ispccdc_bclamp {
+ __u8 obgain;
+ __u8 obstpixel;
+ __u8 oblines;
+ __u8 oblen;
+ __u16 dcsubval;
+};
+
+/**
+ * ispccdc_fpc - Structure for FPC
+ * @fpnum: Number of faulty pixels to be corrected in the frame.
+ * @fpcaddr: Memory address of the FPC Table
+ */
+struct ispccdc_fpc {
+ __u16 fpnum;
+ __u32 fpcaddr;
+};
+
+/**
+ * ispccdc_blcomp - Structure for Black Level Compensation parameters.
+ * @b_mg: B/Mg pixels. 2's complement. -128 to +127.
+ * @gb_g: Gb/G pixels. 2's complement. -128 to +127.
+ * @gr_cy: Gr/Cy pixels. 2's complement. -128 to +127.
+ * @r_ye: R/Ye pixels. 2's complement. -128 to +127.
+ */
+struct ispccdc_blcomp {
+ __u8 b_mg;
+ __u8 gb_g;
+ __u8 gr_cy;
+ __u8 r_ye;
+};
+
+/**
+ * struct ispccdc_vp - Structure for Video Port parameters
+ * @bitshift_sel: Video port input select. 3 - bits 12-3, 4 - bits 11-2,
+ * 5 - bits 10-1, 6 - bits 9-0.
+ * @freq_sel: Video port data ready frequency. 1 - 1/3.5, 2 - 1/4.5,
+ * 3 - 1/5.5, 4 - 1/6.5.
+ */
+struct ispccdc_vp {
+ enum vpin bitshift_sel;
+ enum vpif_freq freq_sel;
+};
+
+/**
+ * ispccdc_culling - Structure for Culling parameters.
+ * @v_pattern: Vertical culling pattern.
+ * @h_odd: Horizontal Culling pattern for odd lines.
+ * @h_even: Horizontal Culling pattern for even lines.
+ */
+struct ispccdc_culling {
+ __u8 v_pattern;
+ __u16 h_odd;
+ __u16 h_even;
+};
+
+/**
+ * ispccdc_update_config - Structure for CCDC configuration.
+ * @update: Specifies which CCDC registers should be updated.
+ * @flag: Specifies which CCDC functions should be enabled.
+ * @alawip: Enable/Disable A-Law compression.
+ * @bclamp: Black clamp control register.
+ * @blcomp: Black level compensation value for RGrGbB Pixels. 2's complement.
+ * @fpc: Number of faulty pixels corrected in the frame, address of FPC table.
+ * @cull: Cull control register.
+ * @colptn: Color pattern of the sensor.
+ * @lsc: Pointer to LSC gain table.
+ */
+struct ispccdc_update_config {
+ __u16 update;
+ __u16 flag;
+ enum alaw_ipwidth alawip;
+ struct ispccdc_bclamp *bclamp;
+ struct ispccdc_blcomp *blcomp;
+ struct ispccdc_fpc *fpc;
+ struct ispccdc_lsc_config *lsc_cfg;
+ struct ispccdc_culling *cull;
+ __u32 colptn;
+ __u8 *lsc;
+};
+
+/* Preview configuration */
+
+/*Abstraction layer preview configurations*/
+#define ISP_ABS_PREV_LUMAENH (1 << 0)
+#define ISP_ABS_PREV_INVALAW (1 << 1)
+#define ISP_ABS_PREV_HRZ_MED (1 << 2)
+#define ISP_ABS_PREV_CFA (1 << 3)
+#define ISP_ABS_PREV_CHROMA_SUPP (1 << 4)
+#define ISP_ABS_PREV_WB (1 << 5)
+#define ISP_ABS_PREV_BLKADJ (1 << 6)
+#define ISP_ABS_PREV_RGB2RGB (1 << 7)
+#define ISP_ABS_PREV_COLOR_CONV (1 << 8)
+#define ISP_ABS_PREV_YC_LIMIT (1 << 9)
+#define ISP_ABS_PREV_DEFECT_COR (1 << 10)
+#define ISP_ABS_PREV_GAMMABYPASS (1 << 11)
+#define ISP_ABS_TBL_NF (1 << 12)
+#define ISP_ABS_TBL_REDGAMMA (1 << 13)
+#define ISP_ABS_TBL_GREENGAMMA (1 << 14)
+#define ISP_ABS_TBL_BLUEGAMMA (1 << 15)
+
+#define ISPPRV_NF_TBL_SIZE 64
+#define ISPPRV_CFA_TBL_SIZE 576
+#define ISPPRV_GAMMA_TBL_SIZE 1024
+#define ISPPRV_YENH_TBL_SIZE 128
+
+/**
+ * struct ispprev_hmed - Structure for Horizontal Median Filter.
+ * @odddist: Distance between consecutive pixels of same color in the odd line.
+ * @evendist: Distance between consecutive pixels of same color in the even
+ * line.
+ * @thres: Horizontal median filter threshold.
+ */
+struct ispprev_hmed {
+ __u8 odddist;
+ __u8 evendist;
+ __u8 thres;
+};
+
+/*
+ * Enumeration for CFA Formats supported by preview
+ */
+enum cfa_fmt {
+ CFAFMT_BAYER, CFAFMT_SONYVGA, CFAFMT_RGBFOVEON,
+ CFAFMT_DNSPL, CFAFMT_HONEYCOMB, CFAFMT_RRGGBBFOVEON
+};
+
+/**
+ * struct ispprev_cfa - Structure for CFA Inpterpolation.
+ * @cfafmt: CFA Format Enum value supported by preview.
+ * @cfa_gradthrs_vert: CFA Gradient Threshold - Vertical.
+ * @cfa_gradthrs_horz: CFA Gradient Threshold - Horizontal.
+ * @cfa_table: Pointer to the CFA table.
+ */
+struct ispprev_cfa {
+ enum cfa_fmt cfafmt;
+ __u8 cfa_gradthrs_vert;
+ __u8 cfa_gradthrs_horz;
+ __u32 *cfa_table;
+};
+
+/**
+ * struct ispprev_csup - Structure for Chrominance Suppression.
+ * @gain: Gain.
+ * @thres: Threshold.
+ * @hypf_en: Flag to enable/disable the High Pass Filter.
+ */
+struct ispprev_csup {
+ __u8 gain;
+ __u8 thres;
+ __u8 hypf_en;
+};
+
+/**
+ * struct ispprev_wbal - Structure for White Balance.
+ * @dgain: Digital gain (U10Q8).
+ * @coef3: White balance gain - COEF 3 (U8Q5).
+ * @coef2: White balance gain - COEF 2 (U8Q5).
+ * @coef1: White balance gain - COEF 1 (U8Q5).
+ * @coef0: White balance gain - COEF 0 (U8Q5).
+ */
+struct ispprev_wbal {
+ __u16 dgain;
+ __u8 coef3;
+ __u8 coef2;
+ __u8 coef1;
+ __u8 coef0;
+};
+
+/**
+ * struct ispprev_blkadj - Structure for Black Adjustment.
+ * @red: Black level offset adjustment for Red in 2's complement format
+ * @green: Black level offset adjustment for Green in 2's complement format
+ * @blue: Black level offset adjustment for Blue in 2's complement format
+ */
+struct ispprev_blkadj {
+ /*Black level offset adjustment for Red in 2's complement format */
+ __u8 red;
+ /*Black level offset adjustment for Green in 2's complement format */
+ __u8 green;
+ /* Black level offset adjustment for Blue in 2's complement format */
+ __u8 blue;
+};
+
+/**
+ * struct ispprev_rgbtorgb - Structure for RGB to RGB Blending.
+ * @matrix: Blending values(S12Q8 format)
+ * [RR] [GR] [BR]
+ * [RG] [GG] [BG]
+ * [RB] [GB] [BB]
+ * @offset: Blending offset value for R,G,B in 2's complement integer format.
+ */
+struct ispprev_rgbtorgb {
+ __u16 matrix[3][3];
+ __u16 offset[3];
+};
+
+/**
+ * struct ispprev_csc - Structure for Color Space Conversion from RGB-YCbYCr
+ * @matrix: Color space conversion coefficients(S10Q8)
+ * [CSCRY] [CSCGY] [CSCBY]
+ * [CSCRCB] [CSCGCB] [CSCBCB]
+ * [CSCRCR] [CSCGCR] [CSCBCR]
+ * @offset: CSC offset values for Y offset, CB offset and CR offset respectively
+ */
+struct ispprev_csc {
+ __u16 matrix[RGB_MAX][RGB_MAX];
+ __s16 offset[RGB_MAX];
+};
+
+/**
+ * struct ispprev_yclimit - Structure for Y, C Value Limit.
+ * @minC: Minimum C value
+ * @maxC: Maximum C value
+ * @minY: Minimum Y value
+ * @maxY: Maximum Y value
+ */
+struct ispprev_yclimit {
+ __u8 minC;
+ __u8 maxC;
+ __u8 minY;
+ __u8 maxY;
+};
+
+/**
+ * struct ispprev_dcor - Structure for Defect correction.
+ * @couplet_mode_en: Flag to enable or disable the couplet dc Correction in NF
+ * @detect_correct: Thresholds for correction bit 0:10 detect 16:25 correct
+ */
+struct ispprev_dcor {
+ __u8 couplet_mode_en;
+ __u32 detect_correct[4];
+};
+
+/**
+ * struct ispprev_nf - Structure for Noise Filter
+ * @spread: Spread value to be used in Noise Filter
+ * @table: Pointer to the Noise Filter table
+ */
+struct ispprev_nf {
+ __u8 spread;
+ __u32 table[ISPPRV_NF_TBL_SIZE];
+};
+
+/**
+ * struct ispprv_update_config - Structure for Preview Configuration (user).
+ * @update: Specifies which ISP Preview registers should be updated.
+ * @flag: Specifies which ISP Preview functions should be enabled.
+ * @yen: Pointer to luma enhancement table.
+ * @shading_shift: 3bit value of shift used in shading compensation.
+ * @prev_hmed: Pointer to structure containing the odd and even distance.
+ * between the pixels in the image along with the filter threshold.
+ * @prev_cfa: Pointer to structure containing the CFA interpolation table, CFA.
+ * format in the image, vertical and horizontal gradient threshold.
+ * @csup: Pointer to Structure for Chrominance Suppression coefficients.
+ * @prev_wbal: Pointer to structure for White Balance.
+ * @prev_blkadj: Pointer to structure for Black Adjustment.
+ * @rgb2rgb: Pointer to structure for RGB to RGB Blending.
+ * @prev_csc: Pointer to structure for Color Space Conversion from RGB-YCbYCr.
+ * @yclimit: Pointer to structure for Y, C Value Limit.
+ * @prev_dcor: Pointer to structure for defect correction.
+ * @prev_nf: Pointer to structure for Noise Filter
+ * @red_gamma: Pointer to red gamma correction table.
+ * @green_gamma: Pointer to green gamma correction table.
+ * @blue_gamma: Pointer to blue gamma correction table.
+ */
+struct ispprv_update_config {
+ __u16 update;
+ __u16 flag;
+ void *yen;
+ __u32 shading_shift;
+ struct ispprev_hmed *prev_hmed;
+ struct ispprev_cfa *prev_cfa;
+ struct ispprev_csup *csup;
+ struct ispprev_wbal *prev_wbal;
+ struct ispprev_blkadj *prev_blkadj;
+ struct ispprev_rgbtorgb *rgb2rgb;
+ struct ispprev_csc *prev_csc;
+ struct ispprev_yclimit *yclimit;
+ struct ispprev_dcor *prev_dcor;
+ struct ispprev_nf *prev_nf;
+ __u32 *red_gamma;
+ __u32 *green_gamma;
+ __u32 *blue_gamma;
+};
+
+#endif /* OMAP_ISP_USER_H */
--
1.5.6.5

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,730 @@
From 20d79137ecaa6c7dad007d9ea1d7be5550db4839 Mon Sep 17 00:00:00 2001
From: Vaibhav Hiremath <hvaibhav@ti.com>
Date: Fri, 13 Feb 2009 15:40:25 +0530
Subject: [PATCH 2/2] Resizer bug fixes on top of 1.0.2 release
This commit contains resizer bug fixes on top of
PSP1.0.2 release -
- 4096 aligned address constraint
- workaround for extra page allocation for page aligned
size buffers
Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
---
drivers/media/video/isp/omap_resizer.c | 417 ++++++++++++++++++++++++--------
include/linux/omap_resizer.h | 3 +-
2 files changed, 321 insertions(+), 99 deletions(-)
diff --git a/drivers/media/video/isp/omap_resizer.c b/drivers/media/video/isp/omap_resizer.c
index 54bc425..8059c70 100644
--- a/drivers/media/video/isp/omap_resizer.c
+++ b/drivers/media/video/isp/omap_resizer.c
@@ -28,6 +28,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/uaccess.h>
+#include <linux/pci.h>
#include <media/v4l2-dev.h>
#include <asm/cacheflush.h>
@@ -76,6 +77,10 @@
#define MAX_COEF_COUNTER 16
#define COEFF_ADDRESS_OFFSET 0x04
+#define RSZ_DEF_REQ_EXP 0xE /* Default read operation expand
+ * for the Resizer driver; value
+ * taken from Davinci.
+ */
/* Global structure which contains information about number of channels
and protection variables */
struct device_params {
@@ -85,6 +90,7 @@ struct device_params {
struct mutex reszwrap_mutex; /* Semaphore for array */
struct videobuf_queue_ops vbq_ops; /* videobuf queue operations */
+ unsigned long extra_page_addr;
};
/* Register mapped structure which contains the every register
@@ -126,6 +132,9 @@ struct resizer_config {
u32 rsz_yehn; /* yehn(luma)register mapping
* variable.
*/
+ u32 sdr_req_exp; /* Configuration for Non
+ * real time read expand
+ */
};
struct rsz_mult {
@@ -179,6 +188,7 @@ struct channel_config {
* channel is busy or not
*/
struct mutex chanprotection_mutex;
+ int buf_address[VIDEO_MAX_FRAME];
enum config_done config_state;
u8 input_buf_index;
u8 output_buf_index;
@@ -200,8 +210,6 @@ struct rsz_fh {
struct videobuf_queue vbq;
struct device_params *device;
- dma_addr_t isp_addr_read; /* Input/Output address */
- dma_addr_t isp_addr_write; /* Input/Output address */
u32 rsz_bufsize; /* channel specific buffersize
*/
};
@@ -227,6 +235,10 @@ static int rsz_set_ratio(struct rsz_mult *multipass,
static void rsz_config_ratio(struct rsz_mult *multipass,
struct channel_config *rsz_conf_chan);
+static void inline rsz_set_exp(unsigned int exp)
+{
+ omap_writel(((exp & 0x3FF) << 10), OMAP3ISP_SBL_REG(0xF8));
+}
/**
* rsz_hardware_setup - Sets hardware configuration registers
* @rsz_conf_chan: Structure containing channel configuration
@@ -271,12 +283,15 @@ static void rsz_hardware_setup(struct channel_config *rsz_conf_chan)
+ coeffoffset));
coeffoffset = coeffoffset + COEFF_ADDRESS_OFFSET;
}
+ /* Configure the read expand register */
+ rsz_set_exp(rsz_conf_chan->register_config.sdr_req_exp);
}
/**
* rsz_start - Enables Resizer Wrapper
* @arg: Currently not used.
- * @device: Structure containing ISP resizer wrapper global information
+ * @fh: File structure containing ISP resizer information specific to
+ * channel opened.
*
* Submits a resizing task specified by the rsz_resize structure. The call can
* either be blocked until the task is completed or returned immediately based
@@ -292,12 +307,18 @@ int rsz_start(int *arg, struct rsz_fh *fh)
struct channel_config *rsz_conf_chan = fh->config;
struct rsz_mult *multipass = fh->multipass;
struct videobuf_queue *q = &fh->vbq;
+ struct videobuf_buffer *buf;
int ret;
if (rsz_conf_chan->config_state) {
dev_err(rsz_device, "State not configured \n");
goto err_einval;
}
+ if (!rsz_conf_chan->register_config.rsz_sdr_inadd ||
+ !rsz_conf_chan->register_config.rsz_sdr_outadd) {
+ dev_err(rsz_device, "address is null\n");
+ goto err_einval;
+ }
rsz_conf_chan->status = CHANNEL_BUSY;
@@ -325,33 +346,22 @@ mult:
goto mult;
}
- if (fh->isp_addr_read) {
- ispmmu_vunmap(fh->isp_addr_read);
- fh->isp_addr_read = 0;
- }
- if (fh->isp_addr_write) {
- ispmmu_vunmap(fh->isp_addr_write);
- fh->isp_addr_write = 0;
- }
-
rsz_conf_chan->status = CHANNEL_FREE;
- q->bufs[rsz_conf_chan->input_buf_index]->state = VIDEOBUF_NEEDS_INIT;
- q->bufs[rsz_conf_chan->output_buf_index]->state = VIDEOBUF_NEEDS_INIT;
rsz_conf_chan->register_config.rsz_sdr_outadd = 0;
rsz_conf_chan->register_config.rsz_sdr_inadd = 0;
- /* Unmap and free the DMA memory allocated for buffers */
- videobuf_dma_unmap(q, videobuf_to_dma(
- q->bufs[rsz_conf_chan->input_buf_index]));
- videobuf_dma_unmap(q, videobuf_to_dma(
- q->bufs[rsz_conf_chan->output_buf_index]));
- videobuf_dma_free(videobuf_to_dma(
- q->bufs[rsz_conf_chan->input_buf_index]));
- videobuf_dma_free(videobuf_to_dma(
- q->bufs[rsz_conf_chan->output_buf_index]));
-
isp_unset_callback(CBK_RESZ_DONE);
+ /* Empty the Videobuf queue which was filled during the qbuf */
+ buf = q->bufs[rsz_conf_chan->input_buf_index];
+ buf->state = VIDEOBUF_IDLE;
+ list_del(&buf->stream);
+ if (rsz_conf_chan->input_buf_index != rsz_conf_chan->output_buf_index) {
+ buf = q->bufs[rsz_conf_chan->output_buf_index];
+ buf->state = VIDEOBUF_IDLE;
+ list_del(&buf->stream);
+ }
+
return 0;
err_einval:
return -EINVAL;
@@ -359,6 +369,8 @@ err_einval:
/**
* rsz_set_multipass - Set resizer multipass
+ * @multipass: Structure containing channel configuration
+ for multipass support
* @rsz_conf_chan: Structure containing channel configuration
*
* Returns always 0
@@ -384,6 +396,8 @@ static int rsz_set_multipass(struct rsz_mult *multipass,
/**
* rsz_copy_data - Copy data
+ * @multipass: Structure containing channel configuration
+ for multipass support
* @params: Structure containing the Resizer Wrapper parameters
*
* Copy data
@@ -413,6 +427,8 @@ static void rsz_copy_data(struct rsz_mult *multipass, struct rsz_params *params)
/**
* rsz_set_params - Set parameters for resizer wrapper
+ * @multipass: Structure containing channel configuration
+ for multipass support
* @params: Structure containing the Resizer Wrapper parameters
* @rsz_conf_chan: Structure containing channel configuration
*
@@ -524,6 +540,8 @@ static int rsz_set_params(struct rsz_mult *multipass, struct rsz_params *params,
}
rsz_config_ratio(multipass, rsz_conf_chan);
+ /* Default value for read expand:Taken from Davinci */
+ rsz_conf_chan->register_config.sdr_req_exp = RSZ_DEF_REQ_EXP;
rsz_conf_chan->config_state = STATE_CONFIGURED;
@@ -534,6 +552,8 @@ err_einval:
/**
* rsz_set_ratio - Set ratio
+ * @multipass: Structure containing channel configuration
+ for multipass support
* @rsz_conf_chan: Structure containing channel configuration
*
* Returns 0 if successful, -EINVAL if invalid output size, upscaling ratio is
@@ -548,7 +568,8 @@ static int rsz_set_ratio(struct rsz_mult *multipass,
if ((multipass->out_hsize > MAX_IMAGE_WIDTH) ||
(multipass->out_vsize > MAX_IMAGE_WIDTH)) {
- dev_err(rsz_device, "Invalid output size!");
+ dev_err(rsz_device, "Invalid output size! - %d", \
+ multipass->out_hsize);
goto err_einval;
}
if (multipass->cbilin) {
@@ -758,6 +779,8 @@ err_einval:
/**
* rsz_config_ratio - Configure ratio
+ * @multipass: Structure containing channel configuration
+ for multipass support
* @rsz_conf_chan: Structure containing channel configuration
*
* Configure ratio
@@ -789,6 +812,20 @@ static void rsz_config_ratio(struct rsz_mult *multipass,
((vsize << ISPRSZ_IN_SIZE_VERT_SHIFT)
& ISPRSZ_IN_SIZE_VERT_MASK);
+ /* This is another workaround for the ISP-MMU translation fault.
+ For the parameters whose image size comes exactly to PAGE_SIZE
+ generates ISP-MMU translation fault. The root-cause is the equation
+ input width = (32*sph + (ow - 1)*hrsz + 16) >> 8 + 7
+ = (64*sph + (ow - 1)*hrsz + 32) >> 8 + 7
+ input height = (32*spv + (oh - 1)*vrsz + 16) >> 8 + 4
+ = (64*spv + (oh - 1)*vrsz + 32) >> 8 + 7
+
+ we are adjusting the input width to suit for Resizer module,
+ application should use this configuration henceforth.
+ */
+ multipass->in_hsize = hsize;
+ multipass->in_vsize = vsize;
+
for (coeffcounter = 0; coeffcounter < MAX_COEF_COUNTER;
coeffcounter++) {
if (multipass->num_htap) {
@@ -990,24 +1027,15 @@ static void rsz_calculate_crop(struct channel_config *rsz_conf_chan,
static void rsz_vbq_release(struct videobuf_queue *q,
struct videobuf_buffer *vb)
{
- int i;
struct rsz_fh *fh = q->priv_data;
+ struct videobuf_dmabuf *dma = NULL;
- for (i = 0; i < VIDEO_MAX_FRAME; i++) {
- struct videobuf_dmabuf *dma = NULL;
- if (!q->bufs[i])
- continue;
- if (q->bufs[i]->memory != V4L2_MEMORY_MMAP)
- continue;
- dma = videobuf_to_dma(q->bufs[i]);
- videobuf_dma_unmap(q, dma);
- videobuf_dma_free(dma);
- }
+ dma = videobuf_to_dma(q->bufs[vb->i]);
+ videobuf_dma_unmap(q, dma);
+ videobuf_dma_free(dma);
+ ispmmu_vunmap(fh->config->buf_address[vb->i]);
+ fh->config->buf_address[vb->i] = 0;
- ispmmu_vunmap(fh->isp_addr_read);
- ispmmu_vunmap(fh->isp_addr_write);
- fh->isp_addr_read = 0;
- fh->isp_addr_write = 0;
spin_lock(&fh->vbq_lock);
vb->state = VIDEOBUF_NEEDS_INIT;
spin_unlock(&fh->vbq_lock);
@@ -1062,7 +1090,105 @@ err_einval:
spin_unlock(&fh->vbq_lock);
return -EINVAL;
}
+/*
+ * This function is work around for the videobuf_iolock API,
+ * for User memory allocated with ioremap (VM_IO flag) the API
+ * get_user_pages fails.
+ *
+ * To fulfill this requirement, we have completely ignored VM layer of
+ * Linux, and configuring the ISP MMU with physical address.
+ */
+static int omap_videobuf_dma_init_user(struct videobuf_buffer *vb,
+ unsigned long physp, unsigned long asize)
+{
+ struct videobuf_dmabuf *dma;
+ struct scatterlist *sglist;
+ unsigned long data, first, last;
+ int len, i = 0;
+
+ dma = videobuf_to_dma(vb);
+ data = vb->baddr;
+
+ first = (data & PAGE_MASK) >> PAGE_SHIFT;
+ last = ((data+asize-1) & PAGE_MASK) >> PAGE_SHIFT;
+ dma->offset = data & ~PAGE_MASK;
+ dma->nr_pages = last-first+1;
+
+ dma->direction = PCI_DMA_FROMDEVICE;
+ /*
+ * Allocate array of sglen + 1, to add entry of extra page
+ * for input buffer. Driver always uses 0th buffer as input buffer.
+ */
+ len = dma->nr_pages + (vb->i ? 0 : 1);
+ sglist = kcalloc(len, sizeof(*sglist), GFP_KERNEL);
+ if (NULL == sglist)
+ return -ENOMEM;
+
+ sglist[0].offset = 0;
+ sglist[0].length = PAGE_SIZE - dma->offset;
+ sglist[0].dma_address = (dma_addr_t)physp;
+ physp += sglist[0].length;
+ /*
+ * Iterate in a loop for the number of pages
+ */
+ for (i = 1; i < (len - (vb->i ? 0 : 1)); i++) {
+ sglist[i].offset = 0;
+ sglist[i].length = PAGE_SIZE;
+ sglist[i].dma_address = (dma_addr_t)physp;
+ physp += PAGE_SIZE;
+ }
+ if (0 == vb->i) {
+ sglist[i].offset = 0;
+ sglist[i].length = PAGE_SIZE;
+ sglist[i].dma_address =
+ (dma_addr_t)device_config->extra_page_addr;
+ }
+ dma->sglist = sglist;
+ dma->sglen = len;
+ return 0;
+
+ }
+/*
+ * This function is workaround for the issue, where ISP-MMU generated
+ * translation fault for specific params whose size is aligned to PAGE_SIZE.
+
+ * As a workaround we are padding one extra page for input buffer. This page
+ * we are allocating during init time and will not be released through-out
+ * life time of resizer driver. Please note that Resizer module only reads
+ * from this extra page.
+ */
+int omap_create_sg(struct videobuf_queue *q, struct videobuf_dmabuf *dma)
+{
+ struct scatterlist *sglist;
+ int sglen;
+ sglen = dma->sglen;
+ sglist = kcalloc(sglen + 1, sizeof(*sglist), GFP_KERNEL);
+ if (NULL == sglist)
+ return -ENOMEM;
+ /*
+ * Copy the sglist locally
+ */
+ memcpy(sglist, dma->sglist, sglen * sizeof(*sglist));
+ /*
+ * Release the old sglist, since we already copied it locally
+ */
+ videobuf_dma_unmap(q, dma);
+ /*
+ * Add extra entry to sglist to work with specific params, whose
+ * buffer address alined to PAGE_SIZE.
+ */
+ sglist[sglen].offset = 0;
+ sglist[sglen].length = PAGE_SIZE;
+ sglist[sglen].dma_address = (dma_addr_t)device_config->extra_page_addr;
+ sglen++;
+ /*
+ * Save the sglist for mapping to ISP-MMU space
+ */
+ dma->sglist = sglist;
+ dma->sglen = sglen;
+ return 0;
+}
/**
* rsz_vbq_prepare - Videobuffer is prepared and mmapped.
* @q: Structure containing the videobuffer queue file handle, and device
@@ -1079,19 +1205,24 @@ static int rsz_vbq_prepare(struct videobuf_queue *q,
{
struct rsz_fh *fh = q->priv_data;
struct channel_config *rsz_conf_chan = fh->config;
- struct rsz_mult *multipass = fh->multipass;
int err = 0;
unsigned int isp_addr, insize, outsize;
- struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
-
+ struct rsz_mult *multipass = fh->multipass;
spin_lock(&fh->vbq_lock);
if (vb->baddr) {
+ /* Check for 32 byte alignement */
+ if (vb->baddr != (vb->baddr & ~0x1F)) {
+ spin_unlock(&fh->vbq_lock);
+ dev_err(rsz_device, "Buffer address should be aligned \
+ to 32 byte\n");
+ return -EINVAL;
+ }
vb->size = fh->rsz_bufsize;
vb->bsize = fh->rsz_bufsize;
} else {
spin_unlock(&fh->vbq_lock);
dev_err(rsz_device, "No user buffer allocated\n");
- goto out;
+ return -EINVAL;
}
if (vb->i) {
vb->width = fh->params->out_hsize;
@@ -1103,55 +1234,128 @@ static int rsz_vbq_prepare(struct videobuf_queue *q,
vb->field = field;
spin_unlock(&fh->vbq_lock);
+ /*
+ * Calculate input and output sizes, will be used while mapping
+ * user pages
+ */
+ outsize = multipass->out_pitch * multipass->out_vsize;
+ insize = multipass->in_pitch * multipass->in_vsize;
if (vb->state == VIDEOBUF_NEEDS_INIT) {
- err = videobuf_iolock(q, vb, NULL);
- if (!err) {
- isp_addr = ispmmu_vmap(dma->sglist, dma->sglen);
- if (!isp_addr)
- err = -EIO;
- else {
- if (vb->i) {
- rsz_conf_chan->register_config.
- rsz_sdr_outadd
- = isp_addr;
- fh->isp_addr_write = isp_addr;
- rsz_conf_chan->output_buf_index = vb->i;
- } else {
+ struct videobuf_dmabuf *dma;
+ struct vm_area_struct *vma;
+ spin_lock(&fh->vbq_lock);
+ dma = videobuf_to_dma(vb);
+ vma = find_vma(current->mm, vb->baddr);
+ if ((vma) && (vma->vm_flags & VM_IO) && (vma->vm_pgoff)) {
+ /* This will catch ioremaped buffers to the kernel.
+ * It gives two possible scenarios -
+ * - Driver allocates buffer using either
+ * dma_alloc_coherent or get_free_pages,
+ * and maps to user space using
+ * io_remap_pfn_range/remap_pfn_range
+ * - Drivers maps memory outside from Linux using
+ * io_remap
+ */
+ unsigned long physp = 0, asize;
+ asize = vb->i ? outsize : insize;
+ if ((vb->baddr + asize) > vma->vm_end) {
+ spin_unlock(&fh->vbq_lock);
+ dev_err(rsz_device, "User Buffer Allocation:" \
+ "err=%lu[%lu]\n",\
+ (vma->vm_end - vb->baddr), asize);
+ return -ENOMEM;
+ }
+ physp = (vma->vm_pgoff << PAGE_SHIFT) +
+ (vb->baddr - vma->vm_start);
+ err = omap_videobuf_dma_init_user(vb, physp, asize);
+ spin_unlock(&fh->vbq_lock);
+ if (0 != err)
+ return err;
+ } else {
+ err = videobuf_iolock(q, vb, NULL);
+ /*
+ * In case of user pointer mode, the get_user_pages
+ * will fail if user has allocated less memory than
+ * vb->size. But it is not error from resizer driver
+ * point of view. so handled seperately
+ */
+ if ((err < 0) && (dma->nr_pages > 0))
+ err = videobuf_dma_map(q, dma);
+ if (err)
+ goto buf_release;
+ /*
+ * Add one extra page for input buffer
+ */
+ if (0 == vb->i)
+ err = omap_create_sg(q, dma);
+ if (err)
+ goto buf_release;
+ spin_unlock(&fh->vbq_lock);
+ }
+ isp_addr = ispmmu_vmap(dma->sglist, dma->sglen);
+ if (!isp_addr)
+ err = -EIO;
+ else {
+ if (vb->i) {
+ rsz_conf_chan->buf_address[vb->i] = isp_addr;
+ rsz_conf_chan->register_config.
+ rsz_sdr_outadd
+ = isp_addr;
+ rsz_conf_chan->output_buf_index = vb->i;
+ } else {
+ rsz_conf_chan->buf_address[vb->i] = isp_addr;
+ rsz_conf_chan->register_config.
+ rsz_sdr_inadd
+ = isp_addr;
+ rsz_conf_chan->input_buf_index = vb->i;
+ if (outsize < insize && rsz_conf_chan->
+ register_config.
+ rsz_sdr_outadd == 0) {
rsz_conf_chan->register_config.
- rsz_sdr_inadd
- = isp_addr;
- rsz_conf_chan->input_buf_index = vb->i;
- outsize = multipass->out_pitch *
- multipass->out_vsize;
- insize = multipass->in_pitch *
- multipass->in_vsize;
- if (outsize < insize) {
- rsz_conf_chan->register_config.
- rsz_sdr_outadd
- = isp_addr;
- rsz_conf_chan->
- output_buf_index =
- vb->i;
- }
-
- fh->isp_addr_read = isp_addr;
+ rsz_sdr_outadd
+ = isp_addr;
+ rsz_conf_chan->
+ output_buf_index =
+ vb->i;
}
}
}
- }
+ } else {
+ if(vb->i) {
+ rsz_conf_chan->register_config.
+ rsz_sdr_outadd =
+ rsz_conf_chan->buf_address[vb->i];
+ rsz_conf_chan->output_buf_index = vb->i;
+ } else {
+ rsz_conf_chan->register_config.
+ rsz_sdr_inadd =
+ rsz_conf_chan->buf_address[vb->i];
+ rsz_conf_chan->input_buf_index = vb->i;
+ if(outsize < insize && rsz_conf_chan->
+ register_config.
+ rsz_sdr_outadd == 0) {
+ rsz_conf_chan->register_config.
+ rsz_sdr_outadd
+ = rsz_conf_chan->buf_address[vb->i];
+ rsz_conf_chan->output_buf_index = vb->i;
+ }
+
+ }
+ }
if (!err) {
spin_lock(&fh->vbq_lock);
vb->state = VIDEOBUF_PREPARED;
spin_unlock(&fh->vbq_lock);
- flush_cache_user_range(NULL, vb->baddr, (vb->baddr
- + vb->bsize));
} else
rsz_vbq_release(q, vb);
-out:
+ return err;
+buf_release:
+ spin_unlock(&fh->vbq_lock);
+ rsz_vbq_release(q, vb);
return err;
}
@@ -1255,7 +1459,8 @@ err_enomem0:
**/
static int rsz_release(struct inode *inode, struct file *filp)
{
- u32 timeout = 0;
+ int i;
+ unsigned int timeout = 0;
struct rsz_fh *fh = filp->private_data;
struct channel_config *rsz_conf_chan = fh->config;
struct rsz_params *params = fh->params;
@@ -1266,17 +1471,17 @@ static int rsz_release(struct inode *inode, struct file *filp)
timeout++;
schedule();
}
- if (mutex_lock_interruptible(&device_config->reszwrap_mutex))
- return -EINTR;
- device_config->opened--;
- mutex_unlock(&device_config->reszwrap_mutex);
- /* This will Free memory allocated to the buffers,
- * and flushes the queue
- */
- videobuf_queue_cancel(q);
- fh->params = NULL;
- fh->config = NULL;
+ /* Free memory allocated to the buffers */
+ for (i = 0 ; i < VIDEO_MAX_FRAME ; i++) {
+ struct videobuf_dmabuf *dma = NULL;
+ if (!q->bufs[i])
+ continue;
+ dma = videobuf_to_dma(q->bufs[i]);
+ videobuf_dma_unmap(q, dma);
+ videobuf_dma_free(dma);
+ }
+ videobuf_mmap_free(q);
fh->rsz_bufsize = 0;
filp->private_data = NULL;
@@ -1286,7 +1491,8 @@ static int rsz_release(struct inode *inode, struct file *filp)
kfree(fh);
isp_put();
-
+ fh->params = NULL;
+ fh->config = NULL;
return 0;
}
@@ -1353,6 +1559,12 @@ static long rsz_unlocked_ioctl(struct file *file, unsigned int cmd,
chanprotection_mutex))
return -EINTR;
ret = videobuf_reqbufs(&fh->vbq, (void *)&req_buf);
+ if (ret >= 0) {
+ if (copy_to_user((struct v4l2_requestbuffers *)arg,
+ &req_buf, sizeof(struct
+ v4l2_requestbuffers)))
+ return -EFAULT;
+ }
mutex_unlock(&rsz_conf_chan->chanprotection_mutex);
break;
}
@@ -1394,11 +1606,7 @@ static long rsz_unlocked_ioctl(struct file *file, unsigned int cmd,
sizeof(struct rsz_params))) {
return -EFAULT;
}
- if (mutex_lock_interruptible(&rsz_conf_chan->
- chanprotection_mutex))
- return -EINTR;
- ret = rsz_set_params(fh->multipass, params, rsz_conf_chan);
- mutex_unlock(&rsz_conf_chan->chanprotection_mutex);
+ ret = rsz_set_params(fh->multipass, fh->params, rsz_conf_chan);
break;
}
case RSZ_G_PARAM:
@@ -1433,6 +1641,12 @@ static long rsz_unlocked_ioctl(struct file *file, unsigned int cmd,
rsz_calculate_crop(rsz_conf_chan, (struct rsz_cropsize *)arg);
break;
+ case RSZ_S_EXP:
+ if (mutex_lock_interruptible(&rsz_conf_chan->chanprotection_mutex))
+ return -EINTR;
+ rsz_conf_chan->register_config.sdr_req_exp = *((unsigned int *)arg);
+ mutex_unlock(&rsz_conf_chan->chanprotection_mutex);
+ break;
default:
dev_err(rsz_device, "resizer_ioctl: Invalid Command Value");
return -EINVAL;
@@ -1535,14 +1749,18 @@ static int __init omap_rsz_init(void)
"memory\n");
return -ENOMEM;
}
-
+ device->extra_page_addr = __get_free_pages(GFP_KERNEL | GFP_DMA, 0);
+ if (!device->extra_page_addr) {
+ dev_err(rsz_device, OMAP_REZR_NAME ":Allocation failed. ");
+ kfree(device);
+ return -ENOMEM;
+ }
ret = alloc_chrdev_region(&dev, 0, 1, OMAP_REZR_NAME);
if (ret < 0) {
dev_err(rsz_device, OMAP_REZR_NAME ": intialization failed. "
"Could not allocate region "
"for character device\n");
- kfree(device);
- return -ENODEV;
+ goto fail1;
}
/* Register the driver in the kernel */
@@ -1608,6 +1826,8 @@ fail3:
cdev_del(&c_dev);
fail2:
unregister_chrdev_region(dev, 1);
+fail1:
+ free_pages((unsigned long)device->extra_page_addr, 0);
kfree(device);
return ret;
}
@@ -1623,6 +1843,7 @@ void __exit omap_rsz_exit(void)
platform_driver_unregister(&omap_resizer_driver);
cdev_del(&c_dev);
unregister_chrdev_region(dev, 1);
+ free_pages((unsigned long)device_config->extra_page_addr, 0);
kfree(device_config);
}
diff --git a/include/linux/omap_resizer.h b/include/linux/omap_resizer.h
index 5ac0c88..47b8dd8 100644
--- a/include/linux/omap_resizer.h
+++ b/include/linux/omap_resizer.h
@@ -21,7 +21,7 @@
/* ioctls definition */
#define RSZ_IOC_BASE 'R'
-#define RSZ_IOC_MAXNR 8
+#define RSZ_IOC_MAXNR 9
/*Ioctl options which are to be passed while calling the ioctl*/
#define RSZ_REQBUF _IOWR(RSZ_IOC_BASE, 1,\
@@ -33,6 +33,7 @@
#define RSZ_G_STATUS _IOWR(RSZ_IOC_BASE, 6, struct rsz_status)
#define RSZ_QUEUEBUF _IOWR(RSZ_IOC_BASE, 7, struct v4l2_buffer)
#define RSZ_GET_CROPSIZE _IOWR(RSZ_IOC_BASE, 8, struct rsz_cropsize)
+#define RSZ_S_EXP _IOWR(RSZ_IOC_BASE, 9, __s32)
#define RSZ_INTYPE_YCBCR422_16BIT 0
#define RSZ_INTYPE_PLANAR_8BIT 1
--
1.6.0.3

View File

@@ -0,0 +1,44 @@
From ad422f476ce04636f911557bbfd066c516e9b472 Mon Sep 17 00:00:00 2001
From: Aguirre Rodriguez, Sergio Alberto <saaguirre@ti.com>
Date: Tue, 20 Jan 2009 16:29:26 -0600
Subject: [PATCH] V4L2: Add COLORFX user control
From 07396d67b39bf7bcc81440d3e72d253ad6c54f11 Mon Sep 17 00:00:00 2001
From: Sergio Aguirre <saaguirre@ti.com>
Date: Tue, 20 Jan 2009 15:34:43 -0600
Subject: [PATCH v2] V4L2: Add COLORFX user control
This is a common feature on many cameras. the options are:
Default colors,
B & W,
Sepia
Signed-off-by: Sergio Aguirre <saaguirre@ti.com>
---
include/linux/videodev2.h | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
index 5571dbe..8e4e25e 100644
--- a/include/linux/videodev2.h
+++ b/include/linux/videodev2.h
@@ -879,8 +879,15 @@ enum v4l2_power_line_frequency {
#define V4L2_CID_BACKLIGHT_COMPENSATION (V4L2_CID_BASE+28)
#define V4L2_CID_CHROMA_AGC (V4L2_CID_BASE+29)
#define V4L2_CID_COLOR_KILLER (V4L2_CID_BASE+30)
+#define V4L2_CID_COLORFX (V4L2_CID_BASE+31)
+enum v4l2_colorfx {
+ V4L2_COLORFX_NONE = 0,
+ V4L2_COLORFX_BW = 1,
+ V4L2_COLORFX_SEPIA = 2,
+};
+
/* last CID + 1 */
-#define V4L2_CID_LASTP1 (V4L2_CID_BASE+31)
+#define V4L2_CID_LASTP1 (V4L2_CID_BASE+32)
/* MPEG-class control IDs defined by V4L2 */
#define V4L2_CID_MPEG_BASE (V4L2_CTRL_CLASS_MPEG | 0x900)
--
1.5.6.5

View File

@@ -0,0 +1,50 @@
From 5b007183d51543624bc9f582966f245a64157b57 Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@nokia.com>
Date: Fri, 31 Oct 2008 11:51:30 +0200
Subject: [PATCH] V4L: Int if: v4l2_int_device_try_attach_all requires mutex
Signed-off-by: Sakari Ailus <sakari.ailus@nokia.com>
---
drivers/media/video/v4l2-int-device.c | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/media/video/v4l2-int-device.c b/drivers/media/video/v4l2-int-device.c
index a935bae..eb8dc84 100644
--- a/drivers/media/video/v4l2-int-device.c
+++ b/drivers/media/video/v4l2-int-device.c
@@ -32,7 +32,7 @@
static DEFINE_MUTEX(mutex);
static LIST_HEAD(int_list);
-void v4l2_int_device_try_attach_all(void)
+static void __v4l2_int_device_try_attach_all(void)
{
struct v4l2_int_device *m, *s;
@@ -66,6 +66,14 @@ void v4l2_int_device_try_attach_all(void)
}
}
}
+
+void v4l2_int_device_try_attach_all(void)
+{
+ mutex_lock(&mutex);
+ __v4l2_int_device_try_attach_all();
+ mutex_unlock(&mutex);
+}
+
EXPORT_SYMBOL_GPL(v4l2_int_device_try_attach_all);
static int ioctl_sort_cmp(const void *a, const void *b)
@@ -89,7 +97,7 @@ int v4l2_int_device_register(struct v4l2_int_device *d)
&ioctl_sort_cmp, NULL);
mutex_lock(&mutex);
list_add(&d->head, &int_list);
- v4l2_int_device_try_attach_all();
+ __v4l2_int_device_try_attach_all();
mutex_unlock(&mutex);
return 0;
--
1.5.6.5

View File

@@ -0,0 +1,61 @@
From cc1d76e0f50321e80f7f50e9e214de2c9a45628a Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@nokia.com>
Date: Wed, 22 Oct 2008 18:41:20 +0300
Subject: [PATCH] V4L: Int if: Dummy slave
This patch implements a dummy slave that has no functionality. Helps
managing slaves in the OMAP 3 camera driver; no need to check for NULL
pointers.
Signed-off-by: Sakari Ailus <sakari.ailus@nokia.com>
---
drivers/media/video/v4l2-int-device.c | 19 +++++++++++++++++++
include/media/v4l2-int-device.h | 2 ++
2 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/drivers/media/video/v4l2-int-device.c b/drivers/media/video/v4l2-int-device.c
index eb8dc84..483ee2e 100644
--- a/drivers/media/video/v4l2-int-device.c
+++ b/drivers/media/video/v4l2-int-device.c
@@ -67,6 +67,25 @@ static void __v4l2_int_device_try_attach_all(void)
}
}
+static struct v4l2_int_slave dummy_slave = {
+ /* Dummy pointer to avoid underflow in find_ioctl. */
+ .ioctls = (void *)sizeof(struct v4l2_int_ioctl_desc),
+ .num_ioctls = 0,
+};
+
+static struct v4l2_int_device dummy = {
+ .type = v4l2_int_type_slave,
+ .u = {
+ .slave = &dummy_slave,
+ },
+};
+
+struct v4l2_int_device *v4l2_int_device_dummy()
+{
+ return &dummy;
+}
+EXPORT_SYMBOL_GPL(v4l2_int_device_dummy);
+
void v4l2_int_device_try_attach_all(void)
{
mutex_lock(&mutex);
diff --git a/include/media/v4l2-int-device.h b/include/media/v4l2-int-device.h
index fbf5855..5d254c4 100644
--- a/include/media/v4l2-int-device.h
+++ b/include/media/v4l2-int-device.h
@@ -84,6 +84,8 @@ struct v4l2_int_device {
void *priv;
};
+struct v4l2_int_device *v4l2_int_device_dummy(void);
+
void v4l2_int_device_try_attach_all(void);
int v4l2_int_device_register(struct v4l2_int_device *d);
--
1.5.6.5

View File

@@ -0,0 +1,33 @@
From e041e57cafca24cf92430cdf3cc091060a271e19 Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@nokia.com>
Date: Fri, 31 Oct 2008 10:20:31 +0200
Subject: [PATCH] V4L: int device: add support for VIDIOC_QUERYMENU
Signed-off-by: Tuukka Toivonen <tuukka.o.toivonen@nokia.com>
---
include/media/v4l2-int-device.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/include/media/v4l2-int-device.h b/include/media/v4l2-int-device.h
index 5d254c4..81f4863 100644
--- a/include/media/v4l2-int-device.h
+++ b/include/media/v4l2-int-device.h
@@ -178,6 +178,7 @@ enum v4l2_int_ioctl_num {
vidioc_int_s_fmt_cap_num,
vidioc_int_try_fmt_cap_num,
vidioc_int_queryctrl_num,
+ vidioc_int_querymenu_num,
vidioc_int_g_ctrl_num,
vidioc_int_s_ctrl_num,
vidioc_int_cropcap_num,
@@ -282,6 +283,7 @@ V4L2_INT_WRAPPER_1(g_fmt_cap, struct v4l2_format, *);
V4L2_INT_WRAPPER_1(s_fmt_cap, struct v4l2_format, *);
V4L2_INT_WRAPPER_1(try_fmt_cap, struct v4l2_format, *);
V4L2_INT_WRAPPER_1(queryctrl, struct v4l2_queryctrl, *);
+V4L2_INT_WRAPPER_1(querymenu, struct v4l2_querymenu, *);
V4L2_INT_WRAPPER_1(g_ctrl, struct v4l2_control, *);
V4L2_INT_WRAPPER_1(s_ctrl, struct v4l2_control, *);
V4L2_INT_WRAPPER_1(cropcap, struct v4l2_cropcap, *);
--
1.5.6.5

View File

@@ -0,0 +1,35 @@
From dc05ee10583dca44e0f8d4109bd1397ee3c5ffae Mon Sep 17 00:00:00 2001
From: Sakari Ailus <sakari.ailus@nokia.com>
Date: Thu, 2 Oct 2008 11:55:07 +0300
Subject: [PATCH] V4L: Int if: Add vidioc_int_querycap
Signed-off-by: Sakari Ailus <sakari.ailus@nokia.com>
---
include/media/v4l2-int-device.h | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/include/media/v4l2-int-device.h b/include/media/v4l2-int-device.h
index 81f4863..2830ae1 100644
--- a/include/media/v4l2-int-device.h
+++ b/include/media/v4l2-int-device.h
@@ -173,7 +173,8 @@ enum v4l2_int_ioctl_num {
* "Proper" V4L ioctls, as in struct video_device.
*
*/
- vidioc_int_enum_fmt_cap_num = 1,
+ vidioc_int_querycap_num = 1,
+ vidioc_int_enum_fmt_cap_num,
vidioc_int_g_fmt_cap_num,
vidioc_int_s_fmt_cap_num,
vidioc_int_try_fmt_cap_num,
@@ -278,6 +279,7 @@ enum v4l2_int_ioctl_num {
return desc; \
}
+V4L2_INT_WRAPPER_1(querycap, struct v4l2_capability, *);
V4L2_INT_WRAPPER_1(enum_fmt_cap, struct v4l2_fmtdesc, *);
V4L2_INT_WRAPPER_1(g_fmt_cap, struct v4l2_format, *);
V4L2_INT_WRAPPER_1(s_fmt_cap, struct v4l2_format, *);
--
1.5.6.5